diff --git a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/IkiDanRemunerasiDao.java b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/IkiDanRemunerasiDao.java index 64989b93..5472fa3a 100644 --- a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/IkiDanRemunerasiDao.java +++ b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/IkiDanRemunerasiDao.java @@ -166,7 +166,7 @@ public interface IkiDanRemunerasiDao extends PagingAndSortingRepository listIdBpjs, @Param("karcisId") Integer idKarcis); // Logbook_kinerja_jam_kerja_dokter - @Query("select distinct new Map(ppp.ObjectJenisPetugasPeId as jenisPetugasId," + @Query("select distinct new Map(ppp.ObjectJenisPetugasPeId as jenisPetugasId," + "pg.id as pegawaiId," + "pr.id as produkId,pr.namaProduk as namaProduk," + "pp.noRec as noRec,pp.tglPelayanan as tglPelayanan,pp.jumlah as jumlah,pp.hargaDiscount as hargaDiskon," + "ru.departemenId as departemenId,ru.id as ruanganId," + "pd.isDiskonPegawai as statusDiskon) " @@ -186,12 +186,13 @@ public interface IkiDanRemunerasiDao extends PagingAndSortingRepository :karcisId " - + "and pg.id = :pegawaiId " + "order by pr.namaProduk, pp.tglPelayanan") + + "and pg.id in (:listPegawaiId) " + "order by pr.namaProduk, pp.tglPelayanan") public List> getDataLogbookJamKerjaDokter(@Param("bulan") String bulan, @Param("psbbAwal") Date psbbAwal, @Param("psbbAkhir") Date psbbAkhir, @Param("listNonjadwalId") List listIdNonjadwal, @Param("jenisPegawaiId") Integer idJenisPegawai, - @Param("pegawaiId") Integer idPegawai, @Param("listNontindakanId") List listIdNontindakan, - @Param("listBpjsId") List listIdBpjs, @Param("karcisId") Integer idKarcis); + @Param("listPegawaiId") List listIdPegawai, + @Param("listNontindakanId") List listIdNontindakan, @Param("listBpjsId") List listIdBpjs, + @Param("karcisId") Integer idKarcis); // Logbook_kinerja_luar_jam_kerja_dokter @Query("select distinct new Map(ppp.ObjectJenisPetugasPeId as jenisPetugasId," diff --git a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/LogbookKinerjaDao.java b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/LogbookKinerjaDao.java index 5656a810..813a1c63 100644 --- a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/LogbookKinerjaDao.java +++ b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/LogbookKinerjaDao.java @@ -185,4 +185,10 @@ public interface LogbookKinerjaDao extends PagingAndSortingRepository findKontrakByLogbook(@Param("bulan") String bulan, @Param("pegawaiId") Integer idPegawai, @Param("indikatorId") Integer idIndikator); + @Query("select distinct lkt.pegawaiId " + "from LogbookKinerja lkt " + + "where lkt.indikatorKinerjaId = :indikatorId " + "and to_char(lkt.bulan,'yyyy-MM') = :bulan " + + "and lkt.statusEnabled is true " + "and lkt.statusVerifikasi is true") + List findPegawaiKontrakByIndikator(@Param("bulan") String bulan, + @Param("indikatorId") Integer idIndikator); + } diff --git a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/SkoringTindakanMedisDao.java b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/SkoringTindakanMedisDao.java index 2fc7b5bd..fa8263b1 100644 --- a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/SkoringTindakanMedisDao.java +++ b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/dao/SkoringTindakanMedisDao.java @@ -124,7 +124,8 @@ public interface SkoringTindakanMedisDao extends PagingAndSortingRepository> findLatestActiveSkorByKelompokKerja(); @Query("select new Map(pg.id as pegawaiId,pg.namaLengkap as namaLengkap," + "jb.id as jabatanId," @@ -139,15 +140,15 @@ public interface SkoringTindakanMedisDao extends PagingAndSortingRepository> findLatestActiveSkorByDokter(); - @Query("select distinct new Map(pr.id as produkId,pr.namaProduk as namaProduk," + @Query("select distinct new Map(mj.pegawaiId as pegawaiId," + "pr.id as produkId,pr.namaProduk as namaProduk," + "stm.skor as skor,stm.tanggalMulaiBerlaku as tglMulaiBerlaku,stm.tanggalPembaharuanData as tglPembaharuanData) " + "from SkoringTindakanMedis stm, MapPegawaiJabatanToUnitKerja mj " + "inner join stm.produk pr " + "where stm.kelompokKerjaId = mj.subUnitKerjaPegawaiId " + "and stm.statusEnabled is true and stm.statusVerifikasi is true " + "and pr.statusEnabled is true " + "and mj.statusEnabled is true " + "and to_char(stm.tanggalMulaiBerlaku,'yyyy-MM') <= :bulan " - + "and mj.pegawaiId = :pegawaiId and mj.unitKerjaPegawaiId in (:listKsmId) " + + "and mj.pegawaiId in (:listPegawaiId) and mj.unitKerjaPegawaiId in (:listKsmId) " + "order by pr.namaProduk, stm.skor desc, stm.tanggalPembaharuanData desc") List> findSkoringLogbookDokter(@Param("bulan") String bulan, - @Param("pegawaiId") Integer idPegawai, @Param("listKsmId") List listIdKsm); + @Param("listPegawaiId") List listIdPegawai, @Param("listKsmId") List listIdKsm); } diff --git a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/service/LogbookKinerjaService.java b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/service/LogbookKinerjaService.java index a97338c4..c0d2a575 100644 --- a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/service/LogbookKinerjaService.java +++ b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/service/LogbookKinerjaService.java @@ -1,5 +1,6 @@ package com.jasamedika.medifirst2000.service; +import java.util.Date; import java.util.List; import java.util.Map; @@ -51,4 +52,6 @@ public interface LogbookKinerjaService extends BaseVoService> findRekapPenilaianKinerja(Long bulan, Integer idUnitKerja, Integer idSubunitKerja, Integer idPegawai) throws JpaSystemException; + public void autoVerifLogbookJamKerjaDokter(Date bulan); + } diff --git a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/service/impl/LogbookKinerjaServiceImpl.java b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/service/impl/LogbookKinerjaServiceImpl.java index c734968e..c1ccd9c9 100644 --- a/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/service/impl/LogbookKinerjaServiceImpl.java +++ b/jasamedika-business/src/main/java/com/jasamedika/medifirst2000/service/impl/LogbookKinerjaServiceImpl.java @@ -459,7 +459,8 @@ public class LogbookKinerjaServiceImpl extends BaseVoServiceImpl implements Logb jenisIndikator.put("jenisIndikator", ji); for (Map map : rs) { if (map.get("jenisIndikator").equals(ji)) { - if (map.get("idIndikator").equals(Master.IndikatorKinerja.PELAYANAN_MEDIS_JAM_KERJA)) { + if (map.get("idIndikator").equals(Master.IndikatorKinerja.PELAYANAN_MEDIS_JAM_KERJA) + && Double.valueOf(map.get("fragCapaian").toString()).equals(0.0)) { List> logbookDokter = findLogbookJamKerjaDokter(idPegawai, bulan); double capaian = 0.0; for (Map ld : logbookDokter) { @@ -634,12 +635,12 @@ public class LogbookKinerjaServiceImpl extends BaseVoServiceImpl implements Logb List listIdNonjadwal = shiftKerjaDao.findListNonjadwal(); List> dataLayanan = ikiDanRemunerasiDao.getDataLogbookJamKerjaDokter( - mf.format(new Date(bulan)), pssbAwal, pssbAkhir, listIdNonjadwal, Master.JenisPegawai.DOKTER, idPegawai, - Arrays.asList(Master.JenisProduk.NONTINDAKAN), Arrays.asList(Master.KelompokPasien.KELOMPOK_BPJS), - Master.Produk.KARCIS); + mf.format(new Date(bulan)), pssbAwal, pssbAkhir, listIdNonjadwal, Master.JenisPegawai.DOKTER, + Arrays.asList(idPegawai), Arrays.asList(Master.JenisProduk.NONTINDAKAN), + Arrays.asList(Master.KelompokPasien.KELOMPOK_BPJS), Master.Produk.KARCIS); - List> dataSkor = skoringTindakanMedisDao - .findSkoringLogbookDokter(mf.format(new Date(bulan)), idPegawai, Arrays.asList(Master.UnitKerja.KSM)); + List> dataSkor = skoringTindakanMedisDao.findSkoringLogbookDokter( + mf.format(new Date(bulan)), Arrays.asList(idPegawai), Arrays.asList(Master.UnitKerja.KSM)); // SCORE for (Map mapLayanan : dataLayanan) { @@ -845,8 +846,8 @@ public class LogbookKinerjaServiceImpl extends BaseVoServiceImpl implements Logb Arrays.asList(Master.JenisProduk.NONTINDAKAN), Arrays.asList(Master.KelompokPasien.KELOMPOK_BPJS), Master.Produk.KARCIS); - List> dataSkor = skoringTindakanMedisDao - .findSkoringLogbookDokter(mf.format(new Date(bulan)), idPegawai, Arrays.asList(Master.UnitKerja.KSM)); + List> dataSkor = skoringTindakanMedisDao.findSkoringLogbookDokter( + mf.format(new Date(bulan)), Arrays.asList(idPegawai), Arrays.asList(Master.UnitKerja.KSM)); // SCORE for (Map mapLayanan : dataLayanan) { @@ -1984,4 +1985,98 @@ public class LogbookKinerjaServiceImpl extends BaseVoServiceImpl implements Logb return result; } + @Override + public void autoVerifLogbookJamKerjaDokter(Date bulan) { + DateFormat mf = new SimpleDateFormat("yyyy-MM"); + + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + DecimalFormat decf = new DecimalFormat("0.00"); + decf.setRoundingMode(RoundingMode.HALF_UP); + + LocalDateTime PSBBDate = LocalDateTime.of(2020, 9, 14, 0, 0, 0); + LocalDateTime PSBBEnd = LocalDateTime.parse(GetSettingDataFixed("psbbperiod"), dtf); + + Date pssbAwal = Date.from(PSBBDate.atZone(ZoneId.systemDefault()).toInstant()); + Date pssbAkhir = Date.from(PSBBEnd.atZone(ZoneId.systemDefault()).toInstant()); + + List listRuangEks = splitDataSettingDatafixed("IdRuanganEksekutif"); + + List listIdNonjadwal = shiftKerjaDao.findListNonjadwal(); + + List listIdPegawai = logbookKinerjaDao.findPegawaiKontrakByIndikator(mf.format(bulan), + Master.IndikatorKinerja.PELAYANAN_MEDIS_JAM_KERJA); + + List> dataLayanan = ikiDanRemunerasiDao.getDataLogbookJamKerjaDokter(mf.format(bulan), + pssbAwal, pssbAkhir, listIdNonjadwal, Master.JenisPegawai.DOKTER, listIdPegawai, + Arrays.asList(Master.JenisProduk.NONTINDAKAN), Arrays.asList(Master.KelompokPasien.KELOMPOK_BPJS), + Master.Produk.KARCIS); + + List> dataSkor = skoringTindakanMedisDao.findSkoringLogbookDokter(mf.format(bulan), + listIdPegawai, Arrays.asList(Master.UnitKerja.KSM)); + + // SCORE + for (Map mapLayanan : dataLayanan) { + for (Map mapSkor : dataSkor) { + if (mapLayanan.get("pegawaiId").equals(mapSkor.get("pegawaiId")) + && mapLayanan.get("produkId").equals(mapSkor.get("produkId")) + && (((Date) mapLayanan.get("tglPelayanan")).after((Date) mapSkor.get("tglMulaiBerlaku")) + || ((Date) mapLayanan.get("tglPelayanan")) + .equals((Date) mapSkor.get("tglMulaiBerlaku")))) { + mapLayanan.put("skor", mapSkor.get("skor")); + break; + } + } + if (!mapLayanan.containsKey("skor")) { + mapLayanan.put("skor", 1.0); + } + } + + // RULES + for (Map mapLayanan : dataLayanan) { + if (Double.valueOf(mapLayanan.get("hargaDiskon").toString()) > 0.0 + && (CommonUtil.isNullOrEmpty(mapLayanan.get("statusDiskon")) + || !Boolean.valueOf(mapLayanan.get("statusDiskon").toString()))) { + // tidak_dapat_skor_untuk_diskon_dpjp + mapLayanan.put("skor", 0.0); + mapLayanan.put("tSkor", 0.0); + } else if (!mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.KONSUL) + && !mapLayanan.get("namaProduk").toString().toLowerCase().contains(Master.VISIT) + && listRuangEks.contains(mapLayanan.get("ruanganId"))) { + mapLayanan.put("skor", + Double.valueOf(mapLayanan.get("skor").toString()) * Master.Remunerasi.PERSEN_SKOR_EKSEKUTIF); + mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString()) + * Double.valueOf(mapLayanan.get("jumlah").toString())))); + } else if (mapLayanan.get("jenisPetugasId").equals(Master.JenisPetugasPelaksana.ASISTEN_SPESIALIS)) { + mapLayanan.put("skor", Double.valueOf(mapLayanan.get("skor").toString()) + * Master.Remunerasi.PERSEN_SKOR_ASISTEN_SPESIALIS); + mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString()) + * Double.valueOf(mapLayanan.get("jumlah").toString())))); + } else { + mapLayanan.put("tSkor", Double.parseDouble(decf.format(Double.valueOf(mapLayanan.get("skor").toString()) + * Double.valueOf(mapLayanan.get("jumlah").toString())))); + } + } + + for (Integer idPegawai : listIdPegawai) { + double capaian = 0.0; + for (Map mapLayanan : dataLayanan) { + if (mapLayanan.get("pegawaiId").equals(idPegawai)) { + capaian += Double.valueOf(mapLayanan.get("tSkor").toString()); + } + } + + LogbookKinerjaVO vo = new LogbookKinerjaVO(); + PegawaiVO pegawai = new PegawaiVO(); + pegawai.setId(idPegawai); + vo.setPegawai(pegawai); + IndikatorKinerjaVO indikator = new IndikatorKinerjaVO(); + indikator.setId(Master.IndikatorKinerja.PELAYANAN_MEDIS_JAM_KERJA); + vo.setIndikatorKinerja(indikator); + vo.setBulan(bulan); + vo.setCapaian(capaian); + this.verify(vo); + } + } + } diff --git a/jasamedika-sdm/src/main/java/com/jasamedika/medifirst2000/asynctask/AutoLogbookVerification.java b/jasamedika-sdm/src/main/java/com/jasamedika/medifirst2000/asynctask/AutoLogbookVerification.java new file mode 100644 index 00000000..5053ed02 --- /dev/null +++ b/jasamedika-sdm/src/main/java/com/jasamedika/medifirst2000/asynctask/AutoLogbookVerification.java @@ -0,0 +1,62 @@ +package com.jasamedika.medifirst2000.asynctask; + +import java.util.Calendar; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import com.jasamedika.medifirst2000.asynctask.timer.LogbookVerificationTimer; +import com.jasamedika.medifirst2000.controller.base.LocaleController; +import com.jasamedika.medifirst2000.service.LogbookKinerjaService; +import com.jasamedika.medifirst2000.util.CommonUtil; +import com.jasamedika.medifirst2000.vo.LogbookKinerjaVO; + +@Component +public class AutoLogbookVerification extends LocaleController { + private final static Logger LOGGER = LoggerFactory.getLogger(AutoLogbookVerification.class); + + @Autowired + private LogbookKinerjaService logbookKinerjaService; + + public AutoLogbookVerification() { + int day = 4; + int hour = 23; + int minute = 59; + LogbookVerificationTimer.schedule(new Runnable() { + @Override + public void run() { + try { + LOGGER.info("Task Logbook Verification : Running Task Logbook Verification"); + autoLogbookVerification(); + } catch (Exception ex) { + LOGGER.error("Task Logbook Verification : Task Logbook Verification " + ex.getMessage()); + } finally { + LOGGER.info("Task Logbook Verification : Finishing Task Logbook Verification"); + } + } + }, day, hour, minute); + } + + @Async + public void autoLogbookVerification() { + try { + if (CommonUtil.isNotNullOrEmpty(logbookKinerjaService)) { + LOGGER.info("Task Logbook Verification : Running Automatic Logbook Verification"); + + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.MONTH, -1); + logbookKinerjaService.autoVerifLogbookJamKerjaDokter(cal.getTime()); + } else { + LOGGER.warn("Task Logbook Verification : Undefined service"); + } + } catch (Exception ex) { + LOGGER.error("Task Logbook Verification : Automatic Logbook Verification " + ex.getMessage()); + } finally { + LOGGER.info("Task Logbook Verification : Finishing Automatic Logbook Verification"); + } + } + +} \ No newline at end of file diff --git a/jasamedika-sdm/src/main/java/com/jasamedika/medifirst2000/asynctask/timer/LogbookVerificationTimer.java b/jasamedika-sdm/src/main/java/com/jasamedika/medifirst2000/asynctask/timer/LogbookVerificationTimer.java new file mode 100644 index 00000000..c59f18ea --- /dev/null +++ b/jasamedika-sdm/src/main/java/com/jasamedika/medifirst2000/asynctask/timer/LogbookVerificationTimer.java @@ -0,0 +1,90 @@ +package com.jasamedika.medifirst2000.asynctask.timer; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LogbookVerificationTimer { + private final static Logger LOGGER = LoggerFactory.getLogger(LogbookVerificationTimer.class); + + // What to do + private final Runnable whatToDo; + + // when + private final int dayOfMonth; + private final int hourOfDay; + private final int minuteOfHour; + + // The current timer + private Timer current = new Timer(); + + public void cancelCurrent() { + LOGGER.info("LogbookVerificationTimer : Cancel current execution"); + current.cancel(); + + LOGGER.info("LogbookVerificationTimer : Removes the timertask so it can be garbage collected"); + current.purge(); + } + + public static LogbookVerificationTimer schedule(Runnable runnable, int dayOfMonth, int hourOfDay, int minuteOfHour) { + LOGGER.info("LogbookVerificationTimer : Create a new instance"); + return new LogbookVerificationTimer(runnable, dayOfMonth, hourOfDay, minuteOfHour); + } + + private LogbookVerificationTimer(Runnable runnable, int day, int hour, int minute) { + this.whatToDo = runnable; + this.dayOfMonth = day; + this.hourOfDay = hour; + this.minuteOfHour = minute; + + schedule(); + } + + private void schedule() { + cancelCurrent(); + + LOGGER.info( + "LogbookVerificationTimer : Assigning a new instance of Timer, allow the previous Timer to be garbage collected"); + current = new Timer(); + current.schedule(new TimerTask() { + public void run() { + try { + LOGGER.info("LogbookVerificationTimer : Running schedule"); + whatToDo.run(); + } finally { + LOGGER.info("LogbookVerificationTimer : Schedule for the next month"); + schedule(); + } + } + }, nextDate()); + } + + private Date nextDate() { + Calendar curDate = Calendar.getInstance(); + Calendar runDate = Calendar.getInstance(); + + // set_for_compare + runDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + runDate.set(Calendar.HOUR_OF_DAY, hourOfDay); + runDate.set(Calendar.MINUTE, minuteOfHour); + runDate.set(Calendar.SECOND, 0); + runDate.set(Calendar.MILLISECOND, 0); + + if (curDate.getTime().after(runDate.getTime())) { + runDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + runDate.set(Calendar.HOUR_OF_DAY, hourOfDay); + runDate.set(Calendar.MINUTE, minuteOfHour); + runDate.set(Calendar.SECOND, 0); + runDate.set(Calendar.MILLISECOND, 0); + runDate.add(Calendar.MONTH, 1); + } + + LOGGER.info("LogbookVerificationTimer : Set to next month " + runDate.getTime()); + + return runDate.getTime(); + } +}