package com.jasamedika.medifirst2000.dao.custom.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.jasamedika.medifirst2000.dao.IkiDanRemunerasiDao;
import com.jasamedika.medifirst2000.dao.SettingDataFixedDao;
import com.jasamedika.medifirst2000.dao.custom.RevIndeksKinerjaDaoCustom;
import com.jasamedika.medifirst2000.service.impl.BaseVoServiceImpl;
import com.jasamedika.medifirst2000.util.CommonUtil;

@Repository
public class RevIndeksKinerjaDaoCustomImpl extends BaseVoServiceImpl implements RevIndeksKinerjaDaoCustom {

	@Autowired
	private SettingDataFixedDao settingDataFixedDao;

	@Autowired
	private IkiDanRemunerasiDao ikiDanRemunerasiDao;

	@Override
	public List<Map<String, Object>> findAllProdukPerPeriode(Integer id, String periode, Boolean isFFS,
			Integer idProduk, Integer idKelas, List<String> listFriday, List<String> listSK, List<String> listRanap) {

		StringBuffer buffer = new StringBuffer();
		List<String> listjenisPetugasPelaksana = ikiDanRemunerasiDao.findIdJeniPetugasPelaksana();

		buffer.append("select new map (CAST(sum(pelayananPasien.jumlah) as long) as count,"
				+ "pelayananPasien.hargaSatuan as harga,"
				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas, "
				+ "PegawaiJadwalKerja jadwalKerja, "
				+ "Kalender kalender, "
				+ "ShiftKerja shift "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where dokter.id = jadwalKerja.pegawaiId "
				+ "and kalender.id = jadwalKerja.tanggalId "
				+ "and shift.id = jadwalKerja.shiftId "
				+ "and (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		if (CommonUtil.isNotNullOrEmpty(listjenisPetugasPelaksana)) {
			buffer.append("and cast(jenisPetugas.id as string) <> '2' ");
		}
		String departementRawatInap = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRawatInap");

		String departementICU = settingDataFixedDao.getSettingDataFixed("KdInstalasiICU");

		String departementBedahSentral = settingDataFixedDao.getSettingDataFixed("KdInstalasiBedahSentral");

		String departementRawatJalan = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRawatJalan");

		String instalasiGawatDarurat = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiGawatDarurat");

		String instalasiRehabilMedik = settingDataFixedDao
				.getSettingDataFixed("KdDepartemenInstalasiRehabilitasiMedik");

		String instalasiLaboratorium = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiLaboratorium");

		String instalasiRadiologi = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRadiologi");

		String departemenPeristi = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiPeristi");
		
		List<String> listDepartemen = new ArrayList<>();
		listDepartemen.add(departementRawatInap);
		listDepartemen.add(departementICU);
		listDepartemen.add(departementBedahSentral);
		listDepartemen.add(departementRawatJalan);
		listDepartemen.add(instalasiGawatDarurat);
		listDepartemen.add(instalasiRehabilMedik);
		listDepartemen.add(instalasiLaboratorium);
		listDepartemen.add(instalasiRadiologi);
		listDepartemen.add(departemenPeristi);
		
		if (CommonUtil.isNotNullOrEmpty(listDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		}
		
		if (!isFFS) {
			buffer.append("and cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI')");

		} else {
			buffer.append("and ((cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 00:00', 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI')) "
				+ "or (cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 24:00', 'yyyy-MM-dd HH24:MI'))) ");
		}
		
		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listDepartemen)) {
			query.setParameter("listDepartemen", listDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}
	
	@Override
	public Long countAllProdukPerPeriode(Integer id, String periode, Integer idProduk, Integer idKelas, Integer idPelaksana,
			List<Integer> listKelas2Down, List<String> listAllDepartemen, List<String> listInapDepartemen, List<String> listJalanDepartemen, Integer idBPJS, 
			List<Integer> drPatologiAnatomiList) {
		
		Long result = 0L;
		
		Long countAllBpjs = countAllProdukBpjsRemunPerPeriode(id, periode, idProduk, idKelas, idPelaksana, listAllDepartemen, idBPJS);
		Long countInapNonBpjsShift = countAllProdukInapNonbpjsPerPeriode(id, periode, false, idProduk, idKelas, idPelaksana, listInapDepartemen, idBPJS);
		Long countInapNonBpjsOutshift = 0L;
		if (listKelas2Down.contains(idKelas)) {
			countInapNonBpjsOutshift = countAllProdukInapNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, idPelaksana, listInapDepartemen, idBPJS);
		}
		Long countJalanNonbpjsShift = countAllProdukJalanNonbpjsPerPeriode(id, periode, false, idProduk, idKelas, idPelaksana, listJalanDepartemen, idBPJS);
		Long countJalanNonbpjsOutshift = 0L;
		Long countInapNonBpjsOutshift1 = 0L;
		if (drPatologiAnatomiList.contains(id)) {
			countJalanNonbpjsOutshift = countAllProdukJalanNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, idPelaksana, listJalanDepartemen, idBPJS);
			if (!listKelas2Down.contains(idKelas)) {
				countInapNonBpjsOutshift1 = countAllProdukInapNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, idPelaksana, listInapDepartemen, idBPJS);
			}
		}
		
		if (CommonUtil.isNullOrEmpty(countAllBpjs)) {
			countAllBpjs = 0L;
		}
		if (CommonUtil.isNullOrEmpty(countInapNonBpjsShift)) {
			countInapNonBpjsShift = 0L;
		}
		if (CommonUtil.isNullOrEmpty(countInapNonBpjsOutshift)) {
			countInapNonBpjsOutshift = 0L;
		}
		if (CommonUtil.isNullOrEmpty(countJalanNonbpjsShift)) {
			countJalanNonbpjsShift = 0L;
		}
		if (CommonUtil.isNullOrEmpty(countJalanNonbpjsOutshift)) {
			countJalanNonbpjsOutshift = 0L;
		}
		if (CommonUtil.isNullOrEmpty(countInapNonBpjsOutshift1)) {
			countInapNonBpjsOutshift1 = 0L;
		}
		
		result = countAllBpjs+countInapNonBpjsShift+countInapNonBpjsOutshift+countJalanNonbpjsShift+countJalanNonbpjsOutshift+countInapNonBpjsOutshift1;
		
		return result;
		
	}
	
	@Override
	public List<Map<String, Object>> findAllProdukPerPeriode(Integer id, String periode, Integer idProduk, Integer idKelas, Integer idPelaksana,
			List<Integer> listKelas2Down, List<String> listAllDepartemen, List<String> listInapDepartemen, List<String> listJalanDepartemen, Integer idBPJS, 
			List<Integer> drPatologiAnatomiList) {
		List<Map<String, Object>> result = new ArrayList<>();
		
		List<Map<String, Object>> allBpjs = findAllProdukBpjsRemunPerPeriode(id, periode, idProduk, idKelas, idPelaksana, listAllDepartemen, idBPJS);
		List<Map<String, Object>> inapNonBpjsShift = findAllProdukInapNonbpjsPerPeriode(id, periode, false, idProduk, idKelas, idPelaksana, listInapDepartemen, idBPJS);
		List<Map<String, Object>> inapNonBpjsOutshift = new ArrayList<>();
		if (listKelas2Down.contains(idKelas)) {
			inapNonBpjsOutshift = findAllProdukInapNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, idPelaksana, listInapDepartemen, idBPJS);
		}
		List<Map<String, Object>> jalanNonbpjsShift = findAllProdukJalanNonbpjsPerPeriode(id, periode, false, idProduk, idKelas, idPelaksana, listJalanDepartemen, idBPJS);
		
		List<Map<String, Object>> jalanNonbpjsOutshift = new ArrayList<>();
		List<Map<String, Object>> inapNonBpjsOutshift1 = new ArrayList<>();
		if (drPatologiAnatomiList.contains(id)) {
			jalanNonbpjsOutshift = findAllProdukJalanNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, idPelaksana, listJalanDepartemen, idBPJS);
			if (!listKelas2Down.contains(idKelas)) {
				inapNonBpjsOutshift1 = findAllProdukInapNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, idPelaksana, listInapDepartemen, idBPJS);
			}
		}
		
		List<Map<String, Object>> result1 = new ArrayList<>();
		if (CommonUtil.isNotNullOrEmpty(allBpjs) && CommonUtil.isNotNullOrEmpty(inapNonBpjsShift)) {
			for (Map<String, Object> mapp1 : allBpjs) {
				for (Map<String, Object> mapp2 : inapNonBpjsShift) {
					if (mapp1.get("harga").equals(mapp2.get("harga"))) {
						if (mapp1.get("tanggal").equals(mapp2.get("tanggal"))) {
							Long count = Long.valueOf(mapp1.get("count").toString()) + Long.valueOf(mapp2.get("count").toString());
							Map<String, Object> mapp = new HashMap<>();
							mapp.put("harga", mapp1.get("harga"));
							mapp.put("tanggal", mapp2.get("tanggal"));
							mapp.put("count", count);
							result1.add(mapp);
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(result1)) {
				ArrayList<String> valueList = new ArrayList<String>();
				for (Map<String, Object> map : result1) {
					valueList.add(map.get("tanggal").toString());
				}
				if (allBpjs.size()>inapNonBpjsShift.size()) {
					if (result1.size()<allBpjs.size()) {
						for (Map<String, Object> mapp1 : allBpjs) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsShift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result1.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : inapNonBpjsShift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : allBpjs) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result1.add(mapp1);
							}
						}
					}
				} else {
					if (result1.size()<inapNonBpjsShift.size()) {
						for (Map<String, Object> mapp1 : inapNonBpjsShift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : allBpjs) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result1.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : allBpjs) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsShift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result1.add(mapp1);
							}
						}
					}
				}
			} else if (CommonUtil.isNullOrEmpty(result1)) {
				for (Map<String, Object> mapp1 : allBpjs) {
					result1.add(mapp1);
				}
				for (Map<String, Object> mapp2 : inapNonBpjsShift) {
					result1.add(mapp2);
				}
			}
		} else if (CommonUtil.isNotNullOrEmpty(allBpjs)) {
			result1 = allBpjs;
		} else if (CommonUtil.isNotNullOrEmpty(inapNonBpjsShift)) {
			result1 = inapNonBpjsShift;
		} else {
			result1 = null;
		}
		
		List<Map<String, Object>> result2 = new ArrayList<>();
		if (CommonUtil.isNotNullOrEmpty(inapNonBpjsOutshift) && CommonUtil.isNotNullOrEmpty(jalanNonbpjsShift)) {
			for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
				for (Map<String, Object> mapp2 : jalanNonbpjsShift) {
					if (mapp1.get("harga").equals(mapp2.get("harga"))) {
						if (mapp1.get("tanggal").equals(mapp2.get("tanggal"))) {
							Long count = Long.valueOf(mapp1.get("count").toString()) + Long.valueOf(mapp2.get("count").toString());
							Map<String, Object> mapp = new HashMap<>();
							mapp.put("harga", mapp1.get("harga"));
							mapp.put("tanggal", mapp2.get("tanggal"));
							mapp.put("count", count);
							result2.add(mapp);
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(result2)) {
				ArrayList<String> valueList = new ArrayList<String>();
				for (Map<String, Object> map : result2) {
					valueList.add(map.get("tanggal").toString());
				}
				if (inapNonBpjsOutshift.size()>jalanNonbpjsShift.size()) {
					if (result2.size()<inapNonBpjsOutshift.size()) {
						for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : jalanNonbpjsShift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result2.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : jalanNonbpjsShift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result2.add(mapp1);
							}
						}
					}
				} else {
					if (result2.size()<jalanNonbpjsShift.size()) {
						for (Map<String, Object> mapp1 : jalanNonbpjsShift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result2.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : jalanNonbpjsShift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result2.add(mapp1);
							}
						}
					}
				}
			} else if (CommonUtil.isNullOrEmpty(result2)) {
				for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
					result2.add(mapp1);
				}
				for (Map<String, Object> mapp2 : jalanNonbpjsShift) {
					result2.add(mapp2);
				}
			}
		} else if (CommonUtil.isNotNullOrEmpty(inapNonBpjsOutshift)) {
			result2 = inapNonBpjsOutshift;
		} else if (CommonUtil.isNotNullOrEmpty(jalanNonbpjsShift)) {
			result2 = jalanNonbpjsShift;
		} else {
			result2 = null;
		}
		
		List<Map<String, Object>> result3 = new ArrayList<>();
		if (CommonUtil.isNotNullOrEmpty(result1) && CommonUtil.isNotNullOrEmpty(result2)) {
			for (Map<String, Object> mapp1 : result1) {
				for (Map<String, Object> mapp2 : result2) {
					if (mapp1.get("harga").equals(mapp2.get("harga"))) {
						if (mapp1.get("tanggal").equals(mapp2.get("tanggal"))) {
							Long count = Long.valueOf(mapp1.get("count").toString()) + Long.valueOf(mapp2.get("count").toString());
							Map<String, Object> mapp = new HashMap<>();
							mapp.put("harga", mapp1.get("harga"));
							mapp.put("tanggal", mapp2.get("tanggal"));
							mapp.put("count", count);
							result3.add(mapp);
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(result3)) {
				ArrayList<String> valueList = new ArrayList<String>();
				for (Map<String, Object> map : result3) {
					valueList.add(map.get("tanggal").toString());
				}
				if (result1.size()>result2.size()) {
					if (result3.size()<result1.size()) {
						for (Map<String, Object> mapp1 : result1) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result2) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result3.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : result2) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result1) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result3.add(mapp1);
							}
						}
					}
				} else {
					if (result3.size()<result2.size()) {
						for (Map<String, Object> mapp1 : result2) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result1) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result3.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : result1) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result2) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result3.add(mapp1);
							}
						}
					}
				}
			} else if (CommonUtil.isNullOrEmpty(result3)) {
				for (Map<String, Object> mapp1 : result1) {
					result3.add(mapp1);
				}
				for (Map<String, Object> mapp2 : result2) {
					result3.add(mapp2);
				}
			}
		} else if (CommonUtil.isNotNullOrEmpty(result1)) {
			result3 = result1;
		} else if (CommonUtil.isNotNullOrEmpty(result2)) {
			result3 = result2;
		} else {
			result3 = null;
		}
		
		List<Map<String, Object>> result4 = new ArrayList<>();
		if (CommonUtil.isNotNullOrEmpty(jalanNonbpjsOutshift) && CommonUtil.isNotNullOrEmpty(inapNonBpjsOutshift1)) {
			for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
				for (Map<String, Object> mapp2 : inapNonBpjsOutshift1) {
					if (mapp1.get("harga").equals(mapp2.get("harga"))) {
						if (mapp1.get("tanggal").equals(mapp2.get("tanggal"))) {
							Long count = Long.valueOf(mapp1.get("count").toString()) + Long.valueOf(mapp2.get("count").toString());
							Map<String, Object> mapp = new HashMap<>();
							mapp.put("harga", mapp1.get("harga"));
							mapp.put("tanggal", mapp2.get("tanggal"));
							mapp.put("count", count);
							result4.add(mapp);
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(result4)) {
				ArrayList<String> valueList = new ArrayList<String>();
				for (Map<String, Object> map : result4) {
					valueList.add(map.get("tanggal").toString());
				}
				if (jalanNonbpjsOutshift.size()>inapNonBpjsOutshift1.size()) {
					if (result4.size()<jalanNonbpjsOutshift.size()) {
						for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsOutshift1) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result4.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : inapNonBpjsOutshift1) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : jalanNonbpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result4.add(mapp1);
							}
						}
					}
				} else {
					if (result4.size()<inapNonBpjsOutshift1.size()) {
						for (Map<String, Object> mapp1 : inapNonBpjsOutshift1) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : jalanNonbpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result4.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsOutshift1) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result4.add(mapp1);
							}
						}
					}
				}
			} else if (CommonUtil.isNullOrEmpty(result4)) {
				for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
					result4.add(mapp1);
				}
				for (Map<String, Object> mapp2 : inapNonBpjsOutshift1) {
					result4.add(mapp2);
				}
			}
		} else if (CommonUtil.isNotNullOrEmpty(jalanNonbpjsOutshift)) {
			result4 = jalanNonbpjsOutshift;
		} else if (CommonUtil.isNotNullOrEmpty(inapNonBpjsOutshift1)) {
			result4 = inapNonBpjsOutshift1;
		} else {
			result4 = null;
		}
		
		if (CommonUtil.isNotNullOrEmpty(result3) && CommonUtil.isNotNullOrEmpty(result4)) {
			for (Map<String, Object> mapp1 : result3) {
				for (Map<String, Object> mapp2 : result4) {
					if (mapp1.get("harga").equals(mapp2.get("harga"))) {
						if (mapp1.get("tanggal").equals(mapp2.get("tanggal"))) {
							Long count = Long.valueOf(mapp1.get("count").toString()) + Long.valueOf(mapp2.get("count").toString());
							Map<String, Object> mapp = new HashMap<>();
							mapp.put("harga", mapp1.get("harga"));
							mapp.put("tanggal", mapp2.get("tanggal"));
							mapp.put("count", count);
							result.add(mapp);
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(result)) {
				ArrayList<String> valueList = new ArrayList<String>();
				for (Map<String, Object> map : result) {
					valueList.add(map.get("tanggal").toString());
				}
				if (result3.size()>result4.size()) {
					if (result.size()<result3.size()) {
						for (Map<String, Object> mapp1 : result3) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result4) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : result4) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result3) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
					}
				} else {
					if (result.size()<result4.size()) {
						for (Map<String, Object> mapp1 : result4) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result3) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : result3) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result4) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
					}
				}
			} else if (CommonUtil.isNullOrEmpty(result)) {
				for (Map<String, Object> mapp1 : result3) {
					result.add(mapp1);
				}
				for (Map<String, Object> mapp2 : result4) {
					result.add(mapp2);
				}
			}
		} else if (CommonUtil.isNotNullOrEmpty(result3)) {
			result = result3;
		} else if (CommonUtil.isNotNullOrEmpty(result4)) {
			result = result4;
		} else {
			result = null;
		}
		
		return result;
	}
	
	@Override
	@Transactional
	public List<Map<String, Object>> findAllProdukPerPeriode(Integer id, String periode, Integer idProduk,
			Integer idKelas, List<String> listFriday, List<String> listSK, List<String> listRanap) {
		List<Map<String, Object>> result = new ArrayList<>();
		List<Integer> listKelas2Down = splitDataSettingDatafixed("KelasTindakanRemun");
		
		List<Map<String, Object>> allBpjs = findAllProdukBpjsRemunPerPeriode(id, periode, idProduk, idKelas, listFriday, listSK, listRanap);
		List<Map<String, Object>> inapNonBpjsShift = findAllProdukInapNonbpjsPerPeriode(id, periode, false, idProduk, idKelas, listFriday, listSK, listRanap);
		List<Map<String, Object>> inapNonBpjsOutshift = new ArrayList<>();
		if (listKelas2Down.contains(idKelas)) {
			inapNonBpjsOutshift = findAllProdukInapNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, listFriday, listSK, listRanap);
		}
		List<Map<String, Object>> jalanNonbpjsShift = findAllProdukJalanNonbpjsPerPeriode(id, periode, false, idProduk, idKelas, listFriday, listSK, listRanap);
		
		List<Map<String, Object>> result1 = new ArrayList<>();
		if (CommonUtil.isNotNullOrEmpty(allBpjs) && CommonUtil.isNotNullOrEmpty(inapNonBpjsShift)) {
			for (Map<String, Object> mapp1 : allBpjs) {
				for (Map<String, Object> mapp2 : inapNonBpjsShift) {
					if (mapp1.get("harga").equals(mapp2.get("harga"))) {
						if (mapp1.get("tanggal").equals(mapp2.get("tanggal"))) {
							Long count = Long.valueOf(mapp1.get("count").toString()) + Long.valueOf(mapp2.get("count").toString());
							Map<String, Object> mapp = new HashMap<>();
							mapp.put("harga", mapp1.get("harga"));
							mapp.put("tanggal", mapp2.get("tanggal"));
							mapp.put("count", count);
							result1.add(mapp);
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(result1)) {
				ArrayList<String> valueList = new ArrayList<String>();
				for (Map<String, Object> map : result1) {
					valueList.add(map.get("tanggal").toString());
				}
				if (allBpjs.size()>inapNonBpjsShift.size()) {
					if (result1.size()<allBpjs.size()) {
						for (Map<String, Object> mapp1 : allBpjs) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsShift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result1.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : inapNonBpjsShift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : allBpjs) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result1.add(mapp1);
							}
						}
					}
				} else {
					if (result1.size()<inapNonBpjsShift.size()) {
						for (Map<String, Object> mapp1 : inapNonBpjsShift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : allBpjs) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result1.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : allBpjs) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsShift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result1.add(mapp1);
							}
						}
					}
				}
			} else if (CommonUtil.isNullOrEmpty(result1)) {
				for (Map<String, Object> mapp1 : allBpjs) {
					result1.add(mapp1);
				}
				for (Map<String, Object> mapp2 : inapNonBpjsShift) {
					result1.add(mapp2);
				}
			}
		} else if (CommonUtil.isNotNullOrEmpty(allBpjs)) {
			result1 = allBpjs;
		} else if (CommonUtil.isNotNullOrEmpty(inapNonBpjsShift)) {
			result1 = inapNonBpjsShift;
		} else {
			result1 = null;
		}
		
		List<Map<String, Object>> result2 = new ArrayList<>();
		if (CommonUtil.isNotNullOrEmpty(inapNonBpjsOutshift) && CommonUtil.isNotNullOrEmpty(jalanNonbpjsShift)) {
			for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
				for (Map<String, Object> mapp2 : jalanNonbpjsShift) {
					if (mapp1.get("harga").equals(mapp2.get("harga"))) {
						if (mapp1.get("tanggal").equals(mapp2.get("tanggal"))) {
							Long count = Long.valueOf(mapp1.get("count").toString()) + Long.valueOf(mapp2.get("count").toString());
							Map<String, Object> mapp = new HashMap<>();
							mapp.put("harga", mapp1.get("harga"));
							mapp.put("tanggal", mapp2.get("tanggal"));
							mapp.put("count", count);
							result2.add(mapp);
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(result2)) {
				ArrayList<String> valueList = new ArrayList<String>();
				for (Map<String, Object> map : result2) {
					valueList.add(map.get("tanggal").toString());
				}
				if (inapNonBpjsOutshift.size()>jalanNonbpjsShift.size()) {
					if (result2.size()<inapNonBpjsOutshift.size()) {
						for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : jalanNonbpjsShift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result2.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : jalanNonbpjsShift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result2.add(mapp1);
							}
						}
					}
				} else {
					if (result2.size()<jalanNonbpjsShift.size()) {
						for (Map<String, Object> mapp1 : jalanNonbpjsShift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result2.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : jalanNonbpjsShift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result2.add(mapp1);
							}
						}
					}
				}
			} else if (CommonUtil.isNullOrEmpty(result2)) {
				for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
					result2.add(mapp1);
				}
				for (Map<String, Object> mapp2 : jalanNonbpjsShift) {
					result2.add(mapp2);
				}
			}
		} else if (CommonUtil.isNotNullOrEmpty(inapNonBpjsOutshift)) {
			result2 = inapNonBpjsOutshift;
		} else if (CommonUtil.isNotNullOrEmpty(jalanNonbpjsShift)) {
			result2 = jalanNonbpjsShift;
		} else {
			result2 = null;
		}
		
		if (CommonUtil.isNotNullOrEmpty(result1) && CommonUtil.isNotNullOrEmpty(result2)) {
			for (Map<String, Object> mapp1 : result1) {
				for (Map<String, Object> mapp2 : result2) {
					if (mapp1.get("harga").equals(mapp2.get("harga"))) {
						if (mapp1.get("tanggal").equals(mapp2.get("tanggal"))) {
							Long count = Long.valueOf(mapp1.get("count").toString()) + Long.valueOf(mapp2.get("count").toString());
							Map<String, Object> mapp = new HashMap<>();
							mapp.put("harga", mapp1.get("harga"));
							mapp.put("tanggal", mapp2.get("tanggal"));
							mapp.put("count", count);
							result.add(mapp);
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(result)) {
				ArrayList<String> valueList = new ArrayList<String>();
				for (Map<String, Object> map : result) {
					valueList.add(map.get("tanggal").toString());
				}
				if (result1.size()>result2.size()) {
					if (result.size()<result1.size()) {
						for (Map<String, Object> mapp1 : result1) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result2) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : result2) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result1) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
					}
				} else {
					if (result.size()<result2.size()) {
						for (Map<String, Object> mapp1 : result2) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result1) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : result1) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : result2) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
					}
				}
			} else if (CommonUtil.isNullOrEmpty(result)) {
				for (Map<String, Object> mapp1 : result1) {
					result.add(mapp1);
				}
				for (Map<String, Object> mapp2 : result2) {
					result.add(mapp2);
				}
			}
		} else if (CommonUtil.isNotNullOrEmpty(result1)) {
			result = result1;
		} else if (CommonUtil.isNotNullOrEmpty(result2)) {
			result = result2;
		} else {
			result = null;
		}
		
		return result;
	}
	
	@Override
	public Long countAllProdukFfsPerPeriode(Integer id, String periode, Integer idProduk, Integer idKelas, Integer idPelaksana,
			List<Integer> listKelas2Down, List<String> listAllDepartemen, List<String> listInapDepartemen, List<String> listJalanDepartemen, Integer idBPJS,
			List<Integer> drPatologiAnatomiList) {
		Long result = 0L;
		
		Long countJalanNonbpjsOutshift = 0L;
		Long countInapNonBpjsOutshift = 0L;
		if (!drPatologiAnatomiList.contains(id)) {
			countJalanNonbpjsOutshift = countAllProdukJalanNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, idPelaksana, listJalanDepartemen, idBPJS);
			if (!listKelas2Down.contains(idKelas)) {
				countInapNonBpjsOutshift = countAllProdukInapNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, idPelaksana, listInapDepartemen, idBPJS);
			}
		}
		
		if (CommonUtil.isNullOrEmpty(countJalanNonbpjsOutshift)) {
			countJalanNonbpjsOutshift = 0L;
		}
		if (CommonUtil.isNullOrEmpty(countInapNonBpjsOutshift)) {
			countInapNonBpjsOutshift = 0L;
		}
		
		result = countJalanNonbpjsOutshift+countInapNonBpjsOutshift;
		
		return result;
	}
	
	@Override
	public List<Map<String, Object>> findAllProdukFfsPerPeriode(Integer id, String periode, Integer idProduk, Integer idKelas, Integer idPelaksana,
			List<Integer> listKelas2Down, List<String> listAllDepartemen, List<String> listInapDepartemen, List<String> listJalanDepartemen, Integer idBPJS,
			List<Integer> drPatologiAnatomiList) {
		List<Map<String,Object>> result = new ArrayList<>();
		
		List<Map<String, Object>> jalanNonbpjsOutshift = new ArrayList<>();
		List<Map<String, Object>> inapNonBpjsOutshift = new ArrayList<>();
		if (!drPatologiAnatomiList.contains(id)) {
			jalanNonbpjsOutshift = findAllProdukJalanNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, idPelaksana, listJalanDepartemen, idBPJS);
			if (!listKelas2Down.contains(idKelas)) {
				inapNonBpjsOutshift = findAllProdukInapNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, idPelaksana, listInapDepartemen, idBPJS);
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(jalanNonbpjsOutshift) && CommonUtil.isNotNullOrEmpty(inapNonBpjsOutshift)) {
			for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
				for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
					if (mapp1.get("harga").equals(mapp2.get("harga"))) {
						if (mapp1.get("tanggal").equals(mapp2.get("tanggal"))) {
							Long count = Long.valueOf(mapp1.get("count").toString()) + Long.valueOf(mapp2.get("count").toString());
							Map<String, Object> mapp = new HashMap<>();
							mapp.put("harga", mapp1.get("harga"));
							mapp.put("tanggal", mapp2.get("tanggal"));
							mapp.put("count", count);
							result.add(mapp);
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(result)) {
				ArrayList<String> valueList = new ArrayList<String>();
				for (Map<String, Object> map : result) {
					valueList.add(map.get("tanggal").toString());
				}
				if (jalanNonbpjsOutshift.size()>inapNonBpjsOutshift.size()) {
					if (result.size()<jalanNonbpjsOutshift.size()) {
						for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : jalanNonbpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
					}
				} else {
					if (result.size()<inapNonBpjsOutshift.size()) {
						for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : jalanNonbpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
					}
				}
			} else if (CommonUtil.isNullOrEmpty(result)) {
				for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
					result.add(mapp1);
				}
				for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
					result.add(mapp2);
				}
			}
		} else if (CommonUtil.isNotNullOrEmpty(jalanNonbpjsOutshift)) {
			result = jalanNonbpjsOutshift;
		} else if (CommonUtil.isNotNullOrEmpty(inapNonBpjsOutshift)) {
			result = inapNonBpjsOutshift;
		} else {
			result = null;
		}
		
		return result;
	}
	
	@Override
	public List<Map<String, Object>> findAllProdukFfsPerPeriode(Integer id, String periode, Integer idProduk,
			Integer idKelas, List<String> listFriday, List<String> listSK, List<String> listRanap) {
		List<Map<String,Object>> result = new ArrayList<>();
		List<Integer> listKelas2Down = splitDataSettingDatafixed("KelasTindakanRemun");
		
		List<Map<String, Object>> jalanNonbpjsOutshift = findAllProdukJalanNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, listFriday, listSK, listRanap);
		List<Map<String, Object>> inapNonBpjsOutshift = new ArrayList<>();
		if (!listKelas2Down.contains(idKelas)) {
			inapNonBpjsOutshift = findAllProdukInapNonbpjsPerPeriode(id, periode, true, idProduk, idKelas, listFriday, listSK, listRanap);
		}
		if (CommonUtil.isNotNullOrEmpty(jalanNonbpjsOutshift) && CommonUtil.isNotNullOrEmpty(inapNonBpjsOutshift)) {
			for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
				for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
					if (mapp1.get("harga").equals(mapp2.get("harga"))) {
						if (mapp1.get("tanggal").equals(mapp2.get("tanggal"))) {
							Long count = Long.valueOf(mapp1.get("count").toString()) + Long.valueOf(mapp2.get("count").toString());
							Map<String, Object> mapp = new HashMap<>();
							mapp.put("harga", mapp1.get("harga"));
							mapp.put("tanggal", mapp2.get("tanggal"));
							mapp.put("count", count);
							result.add(mapp);
						}
					}
				}
			}
			if (CommonUtil.isNotNullOrEmpty(result)) {
				ArrayList<String> valueList = new ArrayList<String>();
				for (Map<String, Object> map : result) {
					valueList.add(map.get("tanggal").toString());
				}
				if (jalanNonbpjsOutshift.size()>inapNonBpjsOutshift.size()) {
					if (result.size()<jalanNonbpjsOutshift.size()) {
						for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : jalanNonbpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
					}
				} else {
					if (result.size()<inapNonBpjsOutshift.size()) {
						for (Map<String, Object> mapp1 : inapNonBpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : jalanNonbpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
						for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
							Boolean isDiff = false;
							for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
								if (!mapp1.get("tanggal").equals(mapp2.get("tanggal")) && !valueList.contains(mapp1.get("tanggal").toString())) {
									isDiff = true;
									break;
								}
							}
							if (isDiff) {
								result.add(mapp1);
							}
						}
					}
				}
			} else if (CommonUtil.isNullOrEmpty(result)) {
				for (Map<String, Object> mapp1 : jalanNonbpjsOutshift) {
					result.add(mapp1);
				}
				for (Map<String, Object> mapp2 : inapNonBpjsOutshift) {
					result.add(mapp2);
				}
			}
		} else if (CommonUtil.isNotNullOrEmpty(jalanNonbpjsOutshift)) {
			result = jalanNonbpjsOutshift;
		} else if (CommonUtil.isNotNullOrEmpty(inapNonBpjsOutshift)) {
			result = inapNonBpjsOutshift;
		} else {
			result = null;
		}
		
		return result;
	}
	
	@Override
	public List<Map<String, Object>> findAllProdukJalanNonbpjsPerPeriode(Integer id, String periode, Boolean isFFS, Integer idProduk, Integer idKelas, Integer idPelaksana,
			List<String> listJalanDepartemen, Integer idBPJS) {
		StringBuffer buffer = new StringBuffer();
		String month = periode.substring(0, 7);

		buffer.append("select new map (CAST(sum(pelayananPasien.jumlah) as long) as count,"
				+ "pelayananPasien.hargaSatuan as harga,"
				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas, "
				+ "PegawaiJadwalKerja jadwalKerja, "
				+ "Kalender kalender, "
				+ "ShiftKerja shift "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where dokter.id = jadwalKerja.pegawaiId "
				+ "and kalender.id = jadwalKerja.tanggalId "
				+ "and shift.id = jadwalKerja.shiftId "
				+ "and (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) "
				+ "and kategoryPegawai.id not in (12,13,19) "
				+ "and jenisPetugas.id <> 2 ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				buffer.append("and jenisPetugas.id = :pelaksanaId ");
			} else {
				buffer.append("and jenisPetugas.id not in (6,13) ");
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			buffer.append("and pasienDaftar.kelompokPasienId not in (:idKelPasienBpjs) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listJalanDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode) && periode.equals(month)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		} else {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM-dd') = :periode ");
		}
		
		if (!isFFS) {
			buffer.append("and cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI')");
		} else {
			buffer.append("and ((cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 00:00', 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI')) "
				+ "or (cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 24:00', 'yyyy-MM-dd HH24:MI'))) ");
		}
		
		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				query.setParameter("pelaksanaId", idPelaksana);
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			query.setParameter("idKelPasienBpjs", idBPJS);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listJalanDepartemen)) {
			query.setParameter("listDepartemen", listJalanDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}
	
	@Override
	public Long countAllProdukJalanNonbpjsPerPeriode(Integer id, String periode, Boolean isFFS, Integer idProduk, Integer idKelas, Integer idPelaksana,
			List<String> listJalanDepartemen, Integer idBPJS) {
		StringBuffer buffer = new StringBuffer();

		buffer.append("select CAST(sum(pelayananPasien.jumlah) as long) as count "
//				+ "pelayananPasien.hargaSatuan as harga,"
//				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas, "
				+ "PegawaiJadwalKerja jadwalKerja, "
				+ "Kalender kalender, "
				+ "ShiftKerja shift "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where dokter.id = jadwalKerja.pegawaiId "
				+ "and kalender.id = jadwalKerja.tanggalId "
				+ "and shift.id = jadwalKerja.shiftId "
				+ "and (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) "
				+ "and kategoryPegawai.id not in (12,13,19) "
				+ "and jenisPetugas.id <> 2 ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				buffer.append("and jenisPetugas.id = :pelaksanaId ");
			} else {
				buffer.append("and jenisPetugas.id not in (6,13) ");
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			buffer.append("and pasienDaftar.kelompokPasienId not in (:idKelPasienBpjs) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listJalanDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		}
		
		if (!isFFS) {
			buffer.append("and cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI')");
		} else {
			buffer.append("and ((cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 00:00', 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI')) "
				+ "or (cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 24:00', 'yyyy-MM-dd HH24:MI'))) ");
		}
		
//		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
//		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				query.setParameter("pelaksanaId", idPelaksana);
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			query.setParameter("idKelPasienBpjs", idBPJS);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listJalanDepartemen)) {
			query.setParameter("listDepartemen", listJalanDepartemen);
		}

		return (Long) query.getSingleResult();
	}
	
	@Override
	public List<Map<String, Object>> findAllProdukJalanNonbpjsPerPeriode(Integer id, String periode, Boolean isFFS,
			Integer idProduk, Integer idKelas, List<String> listFriday, List<String> listSK, List<String> listRanap) {
		StringBuffer buffer = new StringBuffer();
		List<String> listjenisPetugasPelaksana = ikiDanRemunerasiDao.findIdJeniPetugasPelaksana();
		Integer bpjsKelPasienId = Integer.valueOf(settingDataFixedDao.getSettingDataFixed("bpjsRemun"));

		buffer.append("select new map (CAST(sum(pelayananPasien.jumlah) as long) as count,"
				+ "pelayananPasien.hargaSatuan as harga,"
				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas, "
				+ "PegawaiJadwalKerja jadwalKerja, "
				+ "Kalender kalender, "
				+ "ShiftKerja shift "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where dokter.id = jadwalKerja.pegawaiId "
				+ "and kalender.id = jadwalKerja.tanggalId "
				+ "and shift.id = jadwalKerja.shiftId "
				+ "and (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(bpjsKelPasienId)) {
			buffer.append("and pasienDaftar.kelompokPasienId not in (:idKelPasienBpjs) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listjenisPetugasPelaksana)) {
			buffer.append("and cast(jenisPetugas.id as string) <> '2' ");
		}
			
		String departementRawatJalan = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRawatJalan");

		String instalasiGawatDarurat = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiGawatDarurat");

		String instalasiRehabilMedik = settingDataFixedDao
				.getSettingDataFixed("KdDepartemenInstalasiRehabilitasiMedik");

		String instalasiLaboratorium = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiLaboratorium");

		String instalasiRadiologi = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRadiologi");
		
		List<String> listDepartemen = new ArrayList<>();
		listDepartemen.add(departementRawatJalan);
		listDepartemen.add(instalasiGawatDarurat);
		listDepartemen.add(instalasiRehabilMedik);
		listDepartemen.add(instalasiLaboratorium);
		listDepartemen.add(instalasiRadiologi);
		
		if (CommonUtil.isNotNullOrEmpty(listDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		}
		
		if (!isFFS) {
			buffer.append("and cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI')");
		} else {
			buffer.append("and ((cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 00:00', 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI')) "
				+ "or (cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 24:00', 'yyyy-MM-dd HH24:MI'))) ");
		}
		
		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(bpjsKelPasienId)) {
			query.setParameter("idKelPasienBpjs", bpjsKelPasienId);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listDepartemen)) {
			query.setParameter("listDepartemen", listDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}
	
	@Override
	public List<Map<String, Object>> findAllProdukInapNonbpjsPerPeriode(Integer id, String periode, Boolean isFFS, Integer idProduk, Integer idKelas, Integer idPelaksana,
			List<String> listInapDepartemen, Integer idBPJS) {
		StringBuffer buffer = new StringBuffer();
		String month = periode.substring(0, 7);

		buffer.append("select new map (CAST(sum(pelayananPasien.jumlah) as long) as count,"
				+ "pelayananPasien.hargaSatuan as harga,"
				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas, "
				+ "PegawaiJadwalKerja jadwalKerja, "
				+ "Kalender kalender, "
				+ "ShiftKerja shift "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where dokter.id = jadwalKerja.pegawaiId "
				+ "and kalender.id = jadwalKerja.tanggalId "
				+ "and shift.id = jadwalKerja.shiftId "
				+ "and (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) "
				+ "and kategoryPegawai.id not in (12,13,19) "
				+ "and jenisPetugas.id <> 2 ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				buffer.append("and jenisPetugas.id = :pelaksanaId ");
			} else {
				buffer.append("and jenisPetugas.id not in (6,13) ");
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			buffer.append("and pasienDaftar.kelompokPasienId not in (:idKelPasienBpjs) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listInapDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode) && periode.equals(month)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		} else {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM-dd') = :periode ");
		}
		
		if (!isFFS) {
			buffer.append("and cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI')");

		} else {
			buffer.append("and ((cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 00:00', 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI')) "
				+ "or (cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 24:00', 'yyyy-MM-dd HH24:MI'))) ");
		}
		
		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				query.setParameter("pelaksanaId", idPelaksana);
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			query.setParameter("idKelPasienBpjs", idBPJS);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listInapDepartemen)) {
			query.setParameter("listDepartemen", listInapDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}
	
	@Override
	public Long countAllProdukInapNonbpjsPerPeriode(Integer id, String periode, Boolean isFFS, Integer idProduk, Integer idKelas, Integer idPelaksana,
			List<String> listInapDepartemen, Integer idBPJS) {
		StringBuffer buffer = new StringBuffer();

		buffer.append("select CAST(sum(pelayananPasien.jumlah) as long) as count "
//				+ "pelayananPasien.hargaSatuan as harga,"
//				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas, "
				+ "PegawaiJadwalKerja jadwalKerja, "
				+ "Kalender kalender, "
				+ "ShiftKerja shift "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where dokter.id = jadwalKerja.pegawaiId "
				+ "and kalender.id = jadwalKerja.tanggalId "
				+ "and shift.id = jadwalKerja.shiftId "
				+ "and (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) "
				+ "and kategoryPegawai.id not in (12,13,19) "
				+ "and jenisPetugas.id <> 2 ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				buffer.append("and jenisPetugas.id = :pelaksanaId ");
			} else {
				buffer.append("and jenisPetugas.id not in (6,13) ");
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			buffer.append("and pasienDaftar.kelompokPasienId not in (:idKelPasienBpjs) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listInapDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		}
		
		if (!isFFS) {
			buffer.append("and cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI')");

		} else {
			buffer.append("and ((cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 00:00', 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI')) "
				+ "or (cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 24:00', 'yyyy-MM-dd HH24:MI'))) ");
		}
		
//		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
//		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				query.setParameter("pelaksanaId", idPelaksana);
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			query.setParameter("idKelPasienBpjs", idBPJS);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listInapDepartemen)) {
			query.setParameter("listDepartemen", listInapDepartemen);
		}

		return (Long) query.getSingleResult();
	}

	@Override
	public List<Map<String, Object>> findAllProdukInapNonbpjsPerPeriode(Integer id, String periode,
			Boolean isFFS, Integer idProduk, Integer idKelas, List<String> listFriday, List<String> listSK,
			List<String> listRanap) {
		StringBuffer buffer = new StringBuffer();
		List<String> listjenisPetugasPelaksana = ikiDanRemunerasiDao.findIdJeniPetugasPelaksana();
		Integer bpjsKelPasienId = Integer.valueOf(settingDataFixedDao.getSettingDataFixed("bpjsRemun"));

		buffer.append("select new map (CAST(sum(pelayananPasien.jumlah) as long) as count,"
				+ "pelayananPasien.hargaSatuan as harga,"
				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas, "
				+ "PegawaiJadwalKerja jadwalKerja, "
				+ "Kalender kalender, "
				+ "ShiftKerja shift "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where dokter.id = jadwalKerja.pegawaiId "
				+ "and kalender.id = jadwalKerja.tanggalId "
				+ "and shift.id = jadwalKerja.shiftId "
				+ "and (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(bpjsKelPasienId)) {
			buffer.append("and pasienDaftar.kelompokPasienId not in (:idKelPasienBpjs) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listjenisPetugasPelaksana)) {
			buffer.append("and cast(jenisPetugas.id as string) <> '2' ");
		}
		
		String departementRawatInap = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRawatInap");

		String departementICU = settingDataFixedDao.getSettingDataFixed("KdInstalasiICU");

		String departementBedahSentral = settingDataFixedDao.getSettingDataFixed("KdInstalasiBedahSentral");

		String departemenPeristi = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiPeristi");
		
		List<String> listDepartemen = new ArrayList<>();
		listDepartemen.add(departementRawatInap);
		listDepartemen.add(departementICU);
		listDepartemen.add(departementBedahSentral);
		listDepartemen.add(departemenPeristi);
		
		if (CommonUtil.isNotNullOrEmpty(listDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		}
		
		if (!isFFS) {
			buffer.append("and cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI')");

		} else {
			buffer.append("and ((cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 00:00', 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI')) "
				+ "or (cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 24:00', 'yyyy-MM-dd HH24:MI'))) ");
		}
		
		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(bpjsKelPasienId)) {
			query.setParameter("idKelPasienBpjs", bpjsKelPasienId);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listDepartemen)) {
			query.setParameter("listDepartemen", listDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}
	
	@Override
	public List<Map<String, Object>> findAllProdukDokterLuarPerPeriode(Integer id, String periode, Integer idProduk, 
			Integer idKelas, Integer idPelaksana, List<String> listAllDepartemen) {
		StringBuffer buffer = new StringBuffer();
		String month = periode.substring(0, 7);

		buffer.append("select new map (CAST(sum(pelayananPasien.jumlah) as long) as count,"
				+ "pelayananPasien.hargaSatuan as harga,"
				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) "
				+ "and kategoryPegawai.id in (12,13,19) "
				+ "and jenisPetugas.id <> 2 ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				buffer.append("and jenisPetugas.id = :pelaksanaId ");
			} else {
				buffer.append("and jenisPetugas.id not in (6,13) ");
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode) && periode.equals(month)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		} else {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM-dd') = :periode ");
		}
		
		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				query.setParameter("pelaksanaId", idPelaksana);
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			query.setParameter("listDepartemen", listAllDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}
	
	@Override
	public Long countAllProdukDokterLuarPerPeriode(Integer id, String periode, Integer idProduk, 
			Integer idKelas, Integer idPelaksana, List<String> listAllDepartemen) {
		StringBuffer buffer = new StringBuffer();

		buffer.append("select CAST(sum(pelayananPasien.jumlah) as long) as count "
//				+ "pelayananPasien.hargaSatuan as harga,"
//				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) "
				+ "and kategoryPegawai.id in (12,13,19) "
				+ "and jenisPetugas.id <> 2 ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				buffer.append("and jenisPetugas.id = :pelaksanaId ");
			} else {
				buffer.append("and jenisPetugas.id not in (6,13) ");
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		}
		
//		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
//		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				query.setParameter("pelaksanaId", idPelaksana);
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			query.setParameter("listDepartemen", listAllDepartemen);
		}

		return (Long) query.getSingleResult();
	}
	
	@Override
	public List<Map<String, Object>> findAllProdukBpjsRemunPerPeriode(Integer id, String periode, Integer idProduk,
			Integer idKelas, Integer idPelaksana, List<String> listAllDepartemen, Integer idBPJS) {
		StringBuffer buffer = new StringBuffer();
		String month = periode.substring(0, 7);

		buffer.append("select new map (CAST(sum(pelayananPasien.jumlah) as long) as count,"
				+ "pelayananPasien.hargaSatuan as harga,"
				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) "
				+ "and kategoryPegawai.id not in (12,13,19) "
				+ "and jenisPetugas.id <> 2 ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				buffer.append("and jenisPetugas.id = :pelaksanaId ");
			} else {
				buffer.append("and jenisPetugas.id not in (6,13) ");
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			buffer.append("and pasienDaftar.kelompokPasienId in (:idKelPasienBpjs) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode) && periode.equals(month)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		} else {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM-dd') = :periode ");
		}
		
		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				query.setParameter("pelaksanaId", idPelaksana);
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			query.setParameter("idKelPasienBpjs", idBPJS);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			query.setParameter("listDepartemen", listAllDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}
	
	@Override
	public Long countAllProdukBpjsRemunPerPeriode(Integer id, String periode, Integer idProduk,
			Integer idKelas, Integer idPelaksana, List<String> listAllDepartemen, Integer idBPJS) {
		StringBuffer buffer = new StringBuffer();

		buffer.append("select CAST(sum(pelayananPasien.jumlah) as long) as count "
//				+ "pelayananPasien.hargaSatuan as harga,"
//				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) "
				+ "and kategoryPegawai.id not in (12,13,19) "
				+ "and jenisPetugas.id <> 2 ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				buffer.append("and jenisPetugas.id = :pelaksanaId ");
			} else {
				buffer.append("and jenisPetugas.id not in (6,13) ");
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			buffer.append("and pasienDaftar.kelompokPasienId in (:idKelPasienBpjs) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		}
		
//		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
//		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPelaksana)) {
			if (idPelaksana==6 || idPelaksana==13) {
				query.setParameter("pelaksanaId", idPelaksana);
			}
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			query.setParameter("idKelPasienBpjs", idBPJS);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			query.setParameter("listDepartemen", listAllDepartemen);
		}

		return (Long) query.getSingleResult();
	}

	@Override
	public List<Map<String, Object>> findAllProdukBpjsRemunPerPeriode(Integer id, String periode, Integer idProduk,
			Integer idKelas, List<String> listFriday, List<String> listSK, List<String> listRanap) {
		StringBuffer buffer = new StringBuffer();
		List<String> listjenisPetugasPelaksana = ikiDanRemunerasiDao.findIdJeniPetugasPelaksana();
		Integer bpjsKelPasienId = Integer.valueOf(settingDataFixedDao.getSettingDataFixed("bpjsRemun"));

		buffer.append("select new map (CAST(sum(pelayananPasien.jumlah) as long) as count,"
				+ "pelayananPasien.hargaSatuan as harga,"
				+ "to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tanggal) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join antrian.pasienDaftar pasienDaftar "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true) ");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(bpjsKelPasienId)) {
			buffer.append("and pasienDaftar.kelompokPasienId in (:idKelPasienBpjs) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listjenisPetugasPelaksana)) {
			buffer.append("and cast(jenisPetugas.id as string) <> '2' ");
		}
		
		String departementRawatInap = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRawatInap");

		String departementICU = settingDataFixedDao.getSettingDataFixed("KdInstalasiICU");

		String departementBedahSentral = settingDataFixedDao.getSettingDataFixed("KdInstalasiBedahSentral");

		String departementRawatJalan = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRawatJalan");

		String instalasiGawatDarurat = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiGawatDarurat");

		String instalasiRehabilMedik = settingDataFixedDao
				.getSettingDataFixed("KdDepartemenInstalasiRehabilitasiMedik");

		String instalasiLaboratorium = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiLaboratorium");

		String instalasiRadiologi = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRadiologi");

		String departemenPeristi = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiPeristi");
		
		List<String> listDepartemen = new ArrayList<>();
		listDepartemen.add(departementRawatInap);
		listDepartemen.add(departementICU);
		listDepartemen.add(departementBedahSentral);
		listDepartemen.add(departementRawatJalan);
		listDepartemen.add(instalasiGawatDarurat);
		listDepartemen.add(instalasiRehabilMedik);
		listDepartemen.add(instalasiLaboratorium);
		listDepartemen.add(instalasiRadiologi);
		listDepartemen.add(departemenPeristi);
		
		if (CommonUtil.isNotNullOrEmpty(listDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			buffer.append("and to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode ");
		}
		
		buffer.append(" group by pelayananPasien.hargaSatuan,to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd')");
		buffer.append(" order by to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') ");

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(bpjsKelPasienId)) {
			query.setParameter("idKelPasienBpjs", bpjsKelPasienId);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listDepartemen)) {
			query.setParameter("listDepartemen", listDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}	
	
	@Override
	public Long countAllProdukPerPeriode(Integer id, String periode, Boolean isFFS, Integer idProduk, Integer idKelas,
			List<String> listFriday, List<String> listSK, List<String> listRanap) {

		StringBuffer buffer = new StringBuffer();
		List<String> listjenisPetugasPelaksana = ikiDanRemunerasiDao.findIdJeniPetugasPelaksana();

		buffer.append("select CAST(sum(pelayananPasien.jumlah) as long) "
				+ "from PelayananPasienPetugas pelayananPasienPetugas, "
				+ "PegawaiJadwalKerja jadwalKerja, "
				+ "Kalender kalender, "
				+ "ShiftKerja shift "
				+ "left join pelayananPasienPetugas.kdjenispetugaspe jenisPetugas "
				+ "left join pelayananPasienPetugas.kdpegawai dokter "
				+ "left join pelayananPasienPetugas.pelayananPasien pelayananPasien "
				+ "left join dokter.detailKategoryPegawai detailKategoriPegawai "
				+ "left join dokter.kategoryPegawai kategoryPegawai "
				+ "left join pelayananPasien.pasienDaftar antrian "
				+ "left join pelayananPasien.produk produk "
				+ "left join antrian.ruangan ruangan "
				+ "left join produk.detailJenisProduk detail "
				+ "left join ruangan.departemen departemen "
				+ "left join detail.jenisProduk jenisProduk "
				+ "where dokter.id = jadwalKerja.pegawaiId "
				+ "and kalender.id = jadwalKerja.tanggalId "
				+ "and shift.id = jadwalKerja.shiftId "
				+ "and (pelayananPasienPetugas.statusEnabled is null or pelayananPasienPetugas.statusEnabled is true) "
				+ "and (pelayananPasien.statusEnabled is null or pelayananPasien.statusEnabled is true)");

		if (CommonUtil.isNotNullOrEmpty(id)) {
			buffer.append("and dokter.id=:id ");
		}
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append("and produk.id=:idProduk ");
		}
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		if (CommonUtil.isNotNullOrEmpty(listjenisPetugasPelaksana)) {
			buffer.append("and cast(jenisPetugas.id as string) in (:listjenisPetugasPelaksana) ");
		}
		String departementRawatInap = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRawatInap");

		String departementICU = settingDataFixedDao.getSettingDataFixed("KdInstalasiICU");

		String departementBedahSentral = settingDataFixedDao.getSettingDataFixed("KdInstalasiBedahSentral");

		String departementRawatJalan = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRawatJalan");

		String instalasiGawatDarurat = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiGawatDarurat");

		String instalasiRehabilMedik = settingDataFixedDao
				.getSettingDataFixed("KdDepartemenInstalasiRehabilitasiMedik");

		String instalasiLaboratorium = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiLaboratorium");

		String instalasiRadiologi = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRadiologi");

		String departemenPeristi = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiPeristi");
		
		List<String> listDepartemen = new ArrayList<>();
		listDepartemen.add(departementRawatInap);
		listDepartemen.add(departementICU);
		listDepartemen.add(departementBedahSentral);
		listDepartemen.add(departementRawatJalan);
		listDepartemen.add(instalasiGawatDarurat);
		listDepartemen.add(instalasiRehabilMedik);
		listDepartemen.add(instalasiLaboratorium);
		listDepartemen.add(instalasiRadiologi);
		listDepartemen.add(departemenPeristi);
		
		if (CommonUtil.isNotNullOrEmpty(listDepartemen)) {
			buffer.append("and cast(departemen.id as string) in (:listDepartemen) ");
		}
		
		if (!isFFS) {
			if (CommonUtil.isNotNullOrEmpty(periode)) {
				buffer.append("and (to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode "
						+ "and cast(pelayananPasien.tglPelayanan as timestamp) "
						+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
						+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI'))");
			}

		} else {
			if (CommonUtil.isNotNullOrEmpty(periode)) {
				buffer.append("and (to_char(pelayananPasien.tglPelayanan, 'yyyy-MM') = :periode "
					+ "and ((cast(pelayananPasien.tglPelayanan as timestamp) "
						+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 00:00', 'yyyy-MM-dd HH24:MI') "
						+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI')) "
					+ "or (cast(pelayananPasien.tglPelayanan as timestamp) "
						+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
						+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 24:00', 'yyyy-MM-dd HH24:MI')))) ");
			}
		}

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(id)) {
			query.setParameter("id", id);
		}
		
		if (CommonUtil.isNotNullOrEmpty(periode)) {
			query.setParameter("periode", periode);
		}

		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		if (CommonUtil.isNotNullOrEmpty(listjenisPetugasPelaksana)) {
			query.setParameter("listjenisPetugasPelaksana", listjenisPetugasPelaksana);
		}
		if (CommonUtil.isNotNullOrEmpty(listDepartemen)) {
			query.setParameter("listDepartemen", listDepartemen);
		}
		
		return (Long) query.getSingleResult();
	}
	
	@Override
	public List<Map<String, Object>> findPatientDetailForEveryTindakan(Integer idProduk, Integer idPegawai,
			Integer idKelas, String tgl, List<Integer> listKelas2Down, List<String> listAllDepartemen,
			List<String> listInapDepartemen, List<String> listJalanDepartemen, Integer idBPJS,
			List<Integer> drPatologiAnatomiList, Boolean FFS) {
		
		List<Map<String, Object>> results = new ArrayList<>();
		
		List<Map<String, Object>> jalanNonbpjsOutshift = new ArrayList<>();
		List<Map<String, Object>> inapNonbpjsOutshift1 = new ArrayList<>();
		
		if (!FFS) {
			List<Map<String, Object>> allBpjs = findPatientDetailBpjsRemunForEveryTindakan(idPegawai, tgl, idProduk, idKelas, listAllDepartemen, idBPJS);
			List<Map<String, Object>> inapNonbpjsShift = findPatientDetailInapNonbpjsForEveryTindakan(idPegawai, tgl, false, idProduk, idKelas, listInapDepartemen, idBPJS);
			List<Map<String, Object>> inapNonbpjsOutshift = new ArrayList<>();
			if (listKelas2Down.contains(idKelas)) {
				inapNonbpjsOutshift = findPatientDetailInapNonbpjsForEveryTindakan(idPegawai, tgl, true, idProduk, idKelas, listInapDepartemen, idBPJS);
			}
			List<Map<String, Object>> jalanNonbpjsShift = findPatientDetailJalanNonbpjsForEveryTindakan(idPegawai, tgl, false, idProduk, idKelas, listJalanDepartemen, idBPJS);
			
			
			if (drPatologiAnatomiList.contains(idPegawai)) {
				jalanNonbpjsOutshift = findPatientDetailJalanNonbpjsForEveryTindakan(idPegawai, tgl, true, idProduk, idKelas, listJalanDepartemen, idBPJS);
				if (!listKelas2Down.contains(idKelas)) {
					inapNonbpjsOutshift1 = findPatientDetailInapNonbpjsForEveryTindakan(idPegawai, tgl, true, idProduk, idKelas, listInapDepartemen, idBPJS);
				}
			}
			
			results.addAll(allBpjs);
			results.addAll(inapNonbpjsShift);
			results.addAll(inapNonbpjsOutshift);
			results.addAll(jalanNonbpjsShift);
			results.addAll(jalanNonbpjsOutshift);
			results.addAll(inapNonbpjsOutshift1);
		} else {
			if (!drPatologiAnatomiList.contains(idPegawai)) {
				jalanNonbpjsOutshift = findPatientDetailJalanNonbpjsForEveryTindakan(idPegawai, tgl, true, idProduk, idKelas, listJalanDepartemen, idBPJS);
				if (!listKelas2Down.contains(idKelas)) {
					inapNonbpjsOutshift1 = findPatientDetailInapNonbpjsForEveryTindakan(idPegawai, tgl, true, idProduk, idKelas, listInapDepartemen, idBPJS);
				}
			}
			
			results.addAll(jalanNonbpjsOutshift);
			results.addAll(inapNonbpjsOutshift1);
		}
		
		return results;
	}
	
	@Override
	public List<Map<String, Object>> findPatientDetailDokterLuarForEveryTindakan(Integer idPegawai, String tgl,
			Integer idProduk, Integer idKelas, List<String> listAllDepartemen) {
		StringBuffer buffer = new StringBuffer();
		String periode = tgl.substring(0, 7);
		buffer.append("select new map (petugas.noRec as norecPetugas,"+
				" ruangan.namaRuangan as ruangan,"+
				" pelayananPasien.noRec as noRecPelayananPasien,"+
				" produk.namaProduk as namaProduk,"+
				" pasien.namaPasien as namapasien,"+ 
				" pasien.noCm as noCm,"+ 
				" pasien.tglLahir as tglLahir,"+
				" pasienDaftar.noRegistrasi as noRegistrasi,"+ 
				" pasienDaftar.tglRegistrasi as tglRegistrasi,"+
				" pelayananPasien.hargaSatuan as harga,"+ 
				" (select distinct harga.hargaNetto1 from HargaNettoProdukByKelas harga"+
				" where harga.produkId = produk.id"+
				" and ((harga.statusEnabled is true and harga.reportDisplay = 'tarif_2022_Nov')"+
				" or (harga.statusEnabled is false and harga.reportDisplay <> 'tarif_2022_Nov'))"+
				" and harga.kelasId = 3) as hargaKelas1,"+
				" pelayananPasien.tglPelayanan as tglpelayanan,"+
				" kelas.namaKelas as namaKelas,"+ 
				" pasienDaftar.tglPulang as tglPulang,"+
				" produk.id as idProduk,"+
				" dokter.id as idPegawai,"+
				" to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tglpel,"+
				" kelas.id as idKelas,"+
				" jenisPetugas.jenisPetugasPe as jenisPetugas)"+ 
				" from PelayananPasienPetugas petugas"+
				" left join petugas.pelayananPasien pelayananPasien"+
				" left join petugas.kdjenispetugaspe jenisPetugas"+ 
				" left join petugas.kdpegawai dokter"+
				" left join dokter.kategoryPegawai kategoryPegawai "+
				" left join pelayananPasien.pasienDaftar antrian"+ 
				" left join pelayananPasien.produk produk"+
				" left join antrian.kelas kelas"+ 
				" left join antrian.ruangan ruangan"+
				" left join ruangan.departemen departemen"+ 
				" left join antrian.pasienDaftar pasienDaftar"+
				" left join pasienDaftar.pasien pasien"+
				" where (pelayananPasien.statusEnabled is true or pelayananPasien.statusEnabled is null)"+
				" and (petugas.statusEnabled is true or petugas.statusEnabled is null)"+
				" and kategoryPegawai.id in (12,13,19)"+
				" and cast(jenisPetugas.id as string) <> '2'");

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append(" and antrian.kelasId = :idKelas");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPegawai)) {
			buffer.append(" and dokter.id = :idPegawai");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append(" and produk.id = :idProduk");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			buffer.append(" and cast(departemen.id as string) in (:listDepartemen)");
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl) && !tgl.equals(periode)) {
			buffer.append(" and to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') = :tgl ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl) && tgl.equals(periode)) {
			buffer.append(" and to_char(pelayananPasien.tglPelayanan,'yyyy-MM') = :tgl ");
		}

		buffer.append(" order by pelayananPasien.tglPelayanan ");

		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(idPegawai)) {
			query.setParameter("idPegawai", idPegawai);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl)) {
			query.setParameter("tgl", tgl);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			query.setParameter("listDepartemen", listAllDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}
	
	@Override
	public List<Map<String, Object>> findPatientDetailBpjsRemunForEveryTindakan(Integer idPegawai, String tgl, Integer idProduk, Integer idKelas, 
			List<String> listAllDepartemen, Integer idBPJS) {
		StringBuffer buffer = new StringBuffer();
		String periode = tgl.substring(0, 7);
		buffer.append("select new map (petugas.noRec as norecPetugas,"+
				" ruangan.namaRuangan as ruangan,"+
				" pelayananPasien.noRec as noRecPelayananPasien,"+
				" produk.namaProduk as namaProduk,"+
				" pasien.namaPasien as namapasien,"+ 
				" pasien.noCm as noCm,"+ 
				" pasien.tglLahir as tglLahir,"+
				" pasienDaftar.noRegistrasi as noRegistrasi,"+ 
				" pasienDaftar.tglRegistrasi as tglRegistrasi,"+
				" pelayananPasien.hargaSatuan as harga,"+ 
				" (select distinct harga.hargaNetto1 from HargaNettoProdukByKelas harga "+
				" where harga.produkId = produk.id"+
				" and ((harga.statusEnabled is true and harga.reportDisplay = 'tarif_2022_Nov')"+
				" or (harga.statusEnabled is false and harga.reportDisplay <> 'tarif_2022_Nov'))"+
				" and harga.kelasId = 3) as hargaKelas1,"+
				" pelayananPasien.tglPelayanan as tglpelayanan,"+
				" kelas.namaKelas as namaKelas,"+ 
				" pasienDaftar.tglPulang as tglPulang,"+
				" produk.id as idProduk,"+
				" dokter.id as idPegawai,"+
				" to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tglpel,"+
				" kelas.id as idKelas,"+
				" jenisPetugas.jenisPetugasPe as jenisPetugas)"+ 
				" from PelayananPasienPetugas petugas"+
				" left join petugas.pelayananPasien pelayananPasien"+
				" left join petugas.kdjenispetugaspe jenisPetugas"+ 
				" left join petugas.kdpegawai dokter"+
				" left join dokter.kategoryPegawai kategoryPegawai "+
				" left join pelayananPasien.pasienDaftar antrian"+ 
				" left join pelayananPasien.produk produk"+
				" left join antrian.kelas kelas"+ 
				" left join antrian.ruangan ruangan"+
				" left join ruangan.departemen departemen"+ 
				" left join antrian.pasienDaftar pasienDaftar"+
				" left join pasienDaftar.pasien pasien"+
				" where (pelayananPasien.statusEnabled is true or pelayananPasien.statusEnabled is null)"+
				" and (petugas.statusEnabled is true or petugas.statusEnabled is null)"+
				" and kategoryPegawai.id not in (12,13,19)"+
				" and cast(jenisPetugas.id as string) <> '2'");

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append(" and antrian.kelasId = :idKelas");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPegawai)) {
			buffer.append(" and dokter.id = :idPegawai");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append(" and produk.id = :idProduk");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			buffer.append(" and pasienDaftar.kelompokPasienId in (:idKelPasienBpjs)");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			buffer.append(" and cast(departemen.id as string) in (:listDepartemen)");
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl) && !tgl.equals(periode)) {
			buffer.append(" and to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') = :tgl ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl) && tgl.equals(periode)) {
			buffer.append(" and to_char(pelayananPasien.tglPelayanan,'yyyy-MM') = :tgl ");
		}

		buffer.append(" order by pelayananPasien.tglPelayanan ");

		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(idPegawai)) {
			query.setParameter("idPegawai", idPegawai);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl)) {
			query.setParameter("tgl", tgl);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			query.setParameter("idKelPasienBpjs", idBPJS);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listAllDepartemen)) {
			query.setParameter("listDepartemen", listAllDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}
	
	@Override
	public List<Map<String, Object>> findPatientDetailInapNonbpjsForEveryTindakan(Integer idPegawai, String tgl, Boolean isFFS, Integer idProduk, Integer idKelas, 
			List<String> listInapDepartemen, Integer idBPJS) {
		StringBuffer buffer = new StringBuffer();
		String periode = tgl.substring(0, 7);
		buffer.append("select new map (petugas.noRec as norecPetugas,"+
				" ruangan.namaRuangan as ruangan,"+
				" pelayananPasien.noRec as noRecPelayananPasien,"+
				" produk.namaProduk as namaProduk,"+
				" pasien.namaPasien as namapasien,"+ 
				" pasien.noCm as noCm,"+ 
				" pasien.tglLahir as tglLahir,"+
				" pasienDaftar.noRegistrasi as noRegistrasi,"+ 
				" pasienDaftar.tglRegistrasi as tglRegistrasi,"+
				" pelayananPasien.hargaSatuan as harga,"+ 
				" (select distinct harga.hargaNetto1 from HargaNettoProdukByKelas harga "+
				" where harga.produkId = produk.id"+
				" and ((harga.statusEnabled is true and harga.reportDisplay = 'tarif_2022_Nov')"+
				" or (harga.statusEnabled is false and harga.reportDisplay <> 'tarif_2022_Nov'))"+
				" and harga.kelasId = 3) as hargaKelas1,"+
				" pelayananPasien.tglPelayanan as tglpelayanan,"+
				" kelas.namaKelas as namaKelas,"+ 
				" pasienDaftar.tglPulang as tglPulang,"+
				" produk.id as idProduk,"+
				" dokter.id as idPegawai,"+
				" to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tglpel,"+
				" kelas.id as idKelas,"+
				" jenisPetugas.jenisPetugasPe as jenisPetugas)"+ 
				" from PelayananPasienPetugas petugas,"+
				" PegawaiJadwalKerja jadwalKerja,"+
				" Kalender kalender,"+
				" ShiftKerja shift"+
				" left join petugas.pelayananPasien pelayananPasien"+
				" left join petugas.kdjenispetugaspe jenisPetugas"+ 
				" left join petugas.kdpegawai dokter"+
				" left join dokter.kategoryPegawai kategoryPegawai "+
				" left join pelayananPasien.pasienDaftar antrian"+ 
				" left join pelayananPasien.produk produk"+
				" left join antrian.kelas kelas"+ 
				" left join antrian.ruangan ruangan"+
				" left join ruangan.departemen departemen"+ 
				" left join antrian.pasienDaftar pasienDaftar"+
				" left join pasienDaftar.pasien pasien"+
				" where dokter.id = jadwalKerja.pegawaiId"+
				" and kalender.id = jadwalKerja.tanggalId"+
				" and shift.id = jadwalKerja.shiftId"+
				" and (pelayananPasien.statusEnabled is true or pelayananPasien.statusEnabled is null)"+
				" and (petugas.statusEnabled is true or petugas.statusEnabled is null)"+
				" and kategoryPegawai.id not in (12,13,19)"+
				" and cast(jenisPetugas.id as string) <> '2'");

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append(" and antrian.kelasId = :idKelas");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPegawai)) {
			buffer.append(" and dokter.id = :idPegawai");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append(" and produk.id = :idProduk");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			buffer.append(" and pasienDaftar.kelompokPasienId not in (:idKelPasienBpjs)");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listInapDepartemen)) {
			buffer.append(" and cast(departemen.id as string) in (:listDepartemen)");
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl) && !tgl.equals(periode)) {
			buffer.append(" and to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') = :tgl ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl) && tgl.equals(periode)) {
			buffer.append(" and to_char(pelayananPasien.tglPelayanan,'yyyy-MM') = :tgl ");
		}
		
		if (!isFFS) {
			buffer.append("and cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI')");
		} else {
			buffer.append("and ((cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 00:00', 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI')) "
				+ "or (cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 24:00', 'yyyy-MM-dd HH24:MI'))) ");
		}

		buffer.append(" order by pelayananPasien.tglPelayanan ");

		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(idPegawai)) {
			query.setParameter("idPegawai", idPegawai);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl)) {
			query.setParameter("tgl", tgl);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			query.setParameter("idKelPasienBpjs", idBPJS);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listInapDepartemen)) {
			query.setParameter("listDepartemen", listInapDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}
	
	@Override
	public List<Map<String, Object>> findPatientDetailJalanNonbpjsForEveryTindakan(Integer idPegawai, String tgl, Boolean isFFS, Integer idProduk, Integer idKelas, 
			List<String> listJalanDepartemen, Integer idBPJS) {
		StringBuffer buffer = new StringBuffer();
		String periode = tgl.substring(0, 7);
		buffer.append("select new map (petugas.noRec as norecPetugas,"+
				" ruangan.namaRuangan as ruangan,"+
				" pelayananPasien.noRec as noRecPelayananPasien,"+
				" produk.namaProduk as namaProduk,"+
				" pasien.namaPasien as namapasien,"+ 
				" pasien.noCm as noCm,"+ 
				" pasien.tglLahir as tglLahir,"+
				" pasienDaftar.noRegistrasi as noRegistrasi,"+ 
				" pasienDaftar.tglRegistrasi as tglRegistrasi,"+
				" pelayananPasien.hargaSatuan as harga,"+ 
				" (select distinct harga.hargaNetto1 from HargaNettoProdukByKelas harga "+
				" where harga.produkId = produk.id"+
				" and ((harga.statusEnabled is true and harga.reportDisplay = 'tarif_2022_Nov')"+
				" or (harga.statusEnabled is false and harga.reportDisplay <> 'tarif_2022_Nov'))"+
				" and harga.kelasId = 3) as hargaKelas1,"+
				" pelayananPasien.tglPelayanan as tglpelayanan,"+
				" kelas.namaKelas as namaKelas,"+ 
				" pasienDaftar.tglPulang as tglPulang,"+
				" produk.id as idProduk,"+
				" dokter.id as idPegawai,"+
				" to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tglpel,"+
				" kelas.id as idKelas,"+
				" jenisPetugas.jenisPetugasPe as jenisPetugas)"+ 
				" from PelayananPasienPetugas petugas,"+
				" PegawaiJadwalKerja jadwalKerja,"+
				" Kalender kalender,"+
				" ShiftKerja shift"+
				" left join petugas.pelayananPasien pelayananPasien"+
				" left join petugas.kdjenispetugaspe jenisPetugas"+ 
				" left join petugas.kdpegawai dokter"+
				" left join dokter.kategoryPegawai kategoryPegawai "+
				" left join pelayananPasien.pasienDaftar antrian"+ 
				" left join pelayananPasien.produk produk"+
				" left join antrian.kelas kelas"+ 
				" left join antrian.ruangan ruangan"+
				" left join ruangan.departemen departemen"+ 
				" left join antrian.pasienDaftar pasienDaftar"+
				" left join pasienDaftar.pasien pasien"+
				" where dokter.id = jadwalKerja.pegawaiId"+
				" and kalender.id = jadwalKerja.tanggalId"+
				" and shift.id = jadwalKerja.shiftId"+
				" and (pelayananPasien.statusEnabled is true or pelayananPasien.statusEnabled is null)"+
				" and (petugas.statusEnabled is true or petugas.statusEnabled is null)"+
				" and kategoryPegawai.id not in (12,13,19)"+
				" and cast(jenisPetugas.id as string) <> '2'");

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append(" and antrian.kelasId = :idKelas");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idPegawai)) {
			buffer.append(" and dokter.id = :idPegawai");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append(" and produk.id = :idProduk");
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			buffer.append(" and pasienDaftar.kelompokPasienId not in (:idKelPasienBpjs)");
		}
		
		if (CommonUtil.isNotNullOrEmpty(listJalanDepartemen)) {
			buffer.append(" and cast(departemen.id as string) in (:listDepartemen)");
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl) && !tgl.equals(periode)) {
			buffer.append(" and to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') = :tgl ");
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl) && tgl.equals(periode)) {
			buffer.append(" and to_char(pelayananPasien.tglPelayanan,'yyyy-MM') = :tgl ");
		}
		
		if (!isFFS) {
			buffer.append("and cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI')");
		} else {
			buffer.append("and ((cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 00:00', 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamMasuk, '\\.', ':')), 'yyyy-MM-dd HH24:MI')) "
				+ "or (cast(pelayananPasien.tglPelayanan as timestamp) "
					+ "between TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' ' || lower(regexp_replace(shift.jamPulang, '\\.', ':')), 'yyyy-MM-dd HH24:MI') "
					+ "and TO_TIMESTAMP(TO_CHAR(kalender.tanggal, 'yyyy-MM-dd') || ' 24:00', 'yyyy-MM-dd HH24:MI'))) ");
		}

		buffer.append(" order by pelayananPasien.tglPelayanan ");

		Query query = em.createQuery(buffer.toString());
		
		if (CommonUtil.isNotNullOrEmpty(idPegawai)) {
			query.setParameter("idPegawai", idPegawai);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		
		if (CommonUtil.isNotNullOrEmpty(tgl)) {
			query.setParameter("tgl", tgl);
		}
		
		if (CommonUtil.isNotNullOrEmpty(idBPJS)) {
			query.setParameter("idKelPasienBpjs", idBPJS);
		}
		
		if (CommonUtil.isNotNullOrEmpty(listJalanDepartemen)) {
			query.setParameter("listDepartemen", listJalanDepartemen);
		}

		return (List<Map<String, Object>>) query.getResultList();
	}

	@Override
	public List<Map<String, Object>> findPatientDetailForEveryTindakan(Integer idProduk, 
			Integer idPegawai,Integer idKelas,  String tgl, List<String> listFriday, List<String> listSK, List<String> listRanap,
			Boolean isFFS) {
		StringBuffer buffer = new StringBuffer();
		String periode = tgl.substring(0, 7);
		List<String> listjenisPetugasPelaksana = ikiDanRemunerasiDao.findIdJeniPetugasPelaksana();
		buffer.append(" select new map (petugas.noRec as norecPetugas, " + " ruangan.namaRuangan as ruangan, "
				+ " pelayananPasien.noRec as noRecPelayananPasien, " + " produk.namaProduk as namaProduk, "
				+ " pasien.namaPasien as namapasien, " + " pasien.noCm as noCm, " + " pasien.tglLahir as tglLahir, "
				+ " pasienDaftar.noRegistrasi as noRegistrasi, " + " pasienDaftar.tglRegistrasi as tglRegistrasi, "
				+ " pelayananPasien.hargaSatuan as harga, " + " pelayananPasien.tglPelayanan as tglpelayanan, "
				+ " kelas.namaKelas as namaKelas, " + " pasienDaftar.tglPulang, "
				+ " produk.id as idProduk, dokter.id as idPegawai, to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') as tglpel, kelas.id as idKelas, "
				+ " jenisPetugas.jenisPetugasPe as jenisPetugas) " + " from PelayananPasienPetugas  petugas "
				+ " left join petugas.pelayananPasien pelayananPasien "
				+ " left join petugas.kdjenispetugaspe jenisPetugas " + " left join petugas.kdpegawai dokter "
				+ " left join pelayananPasien.pasienDaftar antrian " + " left join pelayananPasien.produk produk "
				+ " left join antrian.kelas kelas " + " left join antrian.ruangan ruangan "
				+ " left join ruangan.departemen departemen" + " left join antrian.pasienDaftar pasienDaftar "
				+ " left join pasienDaftar.pasien pasien "
				+ " where (pelayananPasien.statusEnabled is true or pelayananPasien.statusEnabled is null) "
				+ " and (petugas.statusEnabled is true or petugas.statusEnabled is null) ");

		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			buffer.append("and antrian.kelasId=:idKelas ");
		}
		if (CommonUtil.isNotNullOrEmpty(idPegawai)) {
			buffer.append(" and dokter.id = :idPegawai");
		}
		if (CommonUtil.isNotNullOrEmpty(listjenisPetugasPelaksana)) {
			buffer.append(" and cast(jenisPetugas.id as string) <> '2' ");
		}
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			buffer.append(" and produk.id = :idProduk");
		}
		if (CommonUtil.isNotNullOrEmpty(tgl) && !tgl.equals(periode)) {
			buffer.append(" and to_char(pelayananPasien.tglPelayanan,'yyyy-MM-dd') = :tgl ");
		}
		if (CommonUtil.isNotNullOrEmpty(tgl) && tgl.equals(periode)) {
			buffer.append(" and to_char(pelayananPasien.tglPelayanan,'yyyy-MM') = :tgl ");
		}
		String departementRawatInap = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRawatInap");

		String departementICU = settingDataFixedDao.getSettingDataFixed("KdInstalasiICU");

		String departementBedahSentral = settingDataFixedDao.getSettingDataFixed("KdInstalasiBedahSentral");

		String departementRawatJalan = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRawatJalan");

		String instalasiGawatDarurat = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiGawatDarurat");

		String instalasiRehabilMedik = settingDataFixedDao
				.getSettingDataFixed("KdDepartemenInstalasiRehabilitasiMedik");

		String instalasiLaboratorium = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiLaboratorium");

		String instalasiRadiologi = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiRadiologi");

		String departemenPeristi = settingDataFixedDao.getSettingDataFixed("KdDepartemenInstalasiPeristi");

		if (!isFFS) {
			// Ranap
			buffer.append("and (" + " ((departemen.id=:departementRawatInap or " + "departemen.id=:departementICU or "
					+ "departemen.id=:departemenPeristi or "
					+ "departemen.id=:departementBedahSentral ) and CAST (pelayananPasien.tglPelayanan as time ) between CAST ('00:00:00' as time) and CAST('24:00:00' as time) "
					+ "and to_char (pelayananPasien.tglPelayanan,'yyyy-MM-dd') in (:listDateRanap))");
			// Senin-Kamis RJ
			buffer.append("or " + "((departemen.id=:departementRawatJalan or "
					+ "departemen.id=:instalasiGawatDarurat or " + "departemen.id=:instalasiRehabilMedik or "
					+ "departemen.id=:instalasiRadiologi or "
					+ "departemen.id=:instalasiLaboratorium) and CAST (pelayananPasien.tglPelayanan as time ) between CAST ('07:00:00' as time) and CAST('15:30:00' as time) "
					+ "and to_char (pelayananPasien.tglPelayanan,'yyyy-MM-dd') in (:listDate))");
			// Jumar RJ
			buffer.append("or " + "((departemen.id=:departementRawatJalan or "
					+ "departemen.id=:instalasiGawatDarurat or " + "departemen.id=:instalasiRehabilMedik or "
					+ "departemen.id=:instalasiRadiologi or "
					+ "departemen.id=:instalasiLaboratorium) and CAST (pelayananPasien.tglPelayanan as time ) between CAST ('07:00:00' as time) and CAST('16:00:00' as time)  "
					+ "and to_char (pelayananPasien.tglPelayanan,'yyyy-MM-dd') in (:listDateFriday)))");

		} else {
			// Ranap
			buffer.append("and (" + " ((departemen.id=:departementRawatInap or " + "departemen.id=:departementICU or "
					+ "departemen.id=:departemenPeristi or "
					+ "departemen.id=:departementBedahSentral ) and CAST (pelayananPasien.tglPelayanan as time ) between CAST ('00:00:00' as time) and CAST('24:00:00' as time) "
					+ "and to_char (pelayananPasien.tglPelayanan,'yyyy-MM-dd') in (:listDateRanap))");
			// RJ libur
			buffer.append("or " + "((departemen.id=:departementRawatJalan or "
					+ "departemen.id=:instalasiGawatDarurat or " + "departemen.id=:instalasiRehabilMedik or "
					+ "departemen.id=:instalasiRadiologi or "
					+ "departemen.id=:instalasiLaboratorium) and CAST (pelayananPasien.tglPelayanan as time ) between CAST ('00:00:01' as time) and CAST('24:00:00' as time) "
					+ "and to_char (pelayananPasien.tglPelayanan,'yyyy-MM-dd') in (:listDateRanap))");
			// Senin-Kamis RJ
			buffer.append("or " + "((departemen.id=:departementRawatJalan or "
					+ "departemen.id=:instalasiGawatDarurat or " + "departemen.id=:instalasiRehabilMedik or "
					+ "departemen.id=:instalasiRadiologi or "
					+ "departemen.id=:instalasiLaboratorium) and "
					+ "(CAST (pelayananPasien.tglPelayanan as time ) between CAST ('15:30:01' as time) and CAST('24:00:00' as time) "
					+ "or CAST (pelayananPasien.tglPelayanan as time ) between CAST ('00:00:00' as time) and CAST('07:00:00' as time))"
					+ "and to_char (pelayananPasien.tglPelayanan,'yyyy-MM-dd') in (:listDate))");
			// Jumar RJ
			buffer.append("or " + "((departemen.id=:departementRawatJalan or "
					+ "departemen.id=:instalasiGawatDarurat or " + "departemen.id=:instalasiRehabilMedik or "
					+ "departemen.id=:instalasiRadiologi or "
					+ "departemen.id=:instalasiLaboratorium) and "
					+ "(CAST (pelayananPasien.tglPelayanan as time ) between CAST ('16:00:01' as time) and CAST('24:00:00' as time) "
					+ "or CAST (pelayananPasien.tglPelayanan as time ) between CAST ('00:00:00' as time) and CAST('07:00:00' as time))"
					+ "and to_char (pelayananPasien.tglPelayanan,'yyyy-MM-dd') in (:listDateFriday)))");

		}
		buffer.append(" order by pelayananPasien.tglPelayanan ");

		Query query = em.createQuery(buffer.toString());
		if (CommonUtil.isNotNullOrEmpty(idPegawai)) {
			query.setParameter("idPegawai", idPegawai);
		}
		if (CommonUtil.isNotNullOrEmpty(idProduk)) {
			query.setParameter("idProduk", idProduk);
		}
		if (CommonUtil.isNotNullOrEmpty(idKelas)) {
			query.setParameter("idKelas", idKelas);
		}
		if (CommonUtil.isNotNullOrEmpty(tgl)) {
			query.setParameter("tgl", tgl);
		}
		if (CommonUtil.isNotNullOrEmpty(listRanap)) {
			query.setParameter("listDateRanap", listRanap);
		}
		if (CommonUtil.isNotNullOrEmpty(listSK)) {
			query.setParameter("listDate", listSK);
		}
		if (CommonUtil.isNotNullOrEmpty(listFriday)) {
			query.setParameter("listDateFriday", listFriday);
		}
		if (CommonUtil.isNotNullOrEmpty(departementRawatInap) || CommonUtil.isNotNullOrEmpty(departementICU)
				|| CommonUtil.isNotNullOrEmpty(departementBedahSentral)) {
			query.setParameter("departementRawatInap", Integer.parseInt(departementRawatInap));
			query.setParameter("departementICU", Integer.parseInt(departementICU));
			query.setParameter("departemenPeristi", Integer.parseInt(departemenPeristi));
			query.setParameter("departementBedahSentral", Integer.parseInt(departementBedahSentral));
		}
		if (CommonUtil.isNotNullOrEmpty(departementRawatJalan) || CommonUtil.isNotNullOrEmpty(instalasiGawatDarurat)
				|| CommonUtil.isNotNullOrEmpty(instalasiRehabilMedik)
				|| CommonUtil.isNotNullOrEmpty(instalasiLaboratorium)
				|| CommonUtil.isNotNullOrEmpty(instalasiRadiologi)) {
			query.setParameter("departementRawatJalan", Integer.parseInt(departementRawatJalan));
			query.setParameter("instalasiGawatDarurat", Integer.parseInt(instalasiGawatDarurat));
			query.setParameter("instalasiRehabilMedik", Integer.parseInt(instalasiRehabilMedik));
			query.setParameter("instalasiLaboratorium", Integer.parseInt(instalasiLaboratorium));
			query.setParameter("instalasiRadiologi", Integer.parseInt(instalasiRadiologi));
		}
		return (List<Map<String, Object>>) query.getResultList();
	}

}
