laporan.controller.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. const axios = require('../../utils/axios')
  2. const handleError = require('../../utils/v1/handleError')
  3. const response = require('../../utils/responseHandler')
  4. const laporanModel = require('../../model/laporan.model')
  5. const pelanggaranModel = require('../../model/pelanggaran.model')
  6. const pemantauanModel = require('../../model/pemantauan.model')
  7. const { validate } = require('../../utils/v1/validation')
  8. const { notifWA } = require('../../utils/v1/notifFunction')
  9. const { addManyDokumen } = require('../../utils/dokumenFunction')
  10. const userModel = require('../../model/user.model')
  11. const {
  12. cekSatuDataLaporan,
  13. cekBanyakDataLaporan,
  14. cekBanyakDataSanksi,
  15. } = require('../../utils/v1/cekData')
  16. const { TEMPLATE_LAPORAN, PELAPORAN, CREATE_LAPORAN, DIKTI, LLDIKTI, DITUTUP, DELEGASI, TRUE, FALSE } = require('../../utils/constanta')
  17. const logModel = require('../../model/log.model')
  18. const kontakModel = require('../../model/kontak.model')
  19. const sanksiModel = require('../../model/sanksi.model')
  20. const { isValidObjectId } = require('mongoose')
  21. exports.create = handleError(async (req, res) => {
  22. const user = req.user
  23. const files = req.files
  24. const isValid = validate(res, req.body, {
  25. no_laporan: 'string',
  26. pt_id: 'string',
  27. pelanggaran_id: 'string',
  28. keterangan: 'string',
  29. })
  30. if (!isValid) return
  31. const { no_laporan, pt_id, keterangan } = req.body
  32. let { pelanggaran_id } = req.body
  33. const pt = await axios.get(
  34. `https://api.kemdikbud.go.id:8243/pddikti/1.2/pt/${pt_id}`
  35. )
  36. if (pt.length === 0)
  37. return response.error(res, {
  38. message: 'pt_id tidak ditemukan',
  39. })
  40. let dokumen_id = []
  41. if (files.length) {
  42. const dokumen = await addManyDokumen(files)
  43. dokumen_id = dokumen.map((e) => e._id)
  44. }
  45. pelanggaran_id = pelanggaran_id.split(',')
  46. const pelanggaran = await pelanggaranModel.find({
  47. _id: {
  48. $in: pelanggaran_id,
  49. },
  50. })
  51. if (!pelanggaran.length)
  52. return response.error(res, { message: 'pelanggaran_id tidak ada' })
  53. let data = {
  54. no_laporan,
  55. user: user._id,
  56. dokumen: dokumen_id,
  57. pt: pt[0],
  58. pelanggaran: pelanggaran_id,
  59. keterangan,
  60. role_data: user.role.id === 2021 ? LLDIKTI : DIKTI,
  61. role_asal: user.role.id === 2021 ? LLDIKTI : DIKTI,
  62. level: 2,
  63. step: [PELAPORAN],
  64. flag: PELAPORAN,
  65. }
  66. data = await laporanModel.create(data)
  67. let contacts = await kontakModel.find()
  68. contacts = contacts.map((e) => e.nama).join(', ')
  69. try {
  70. const notif = await notifWA(TEMPLATE_LAPORAN, [
  71. {
  72. key: '1',
  73. value: 'nama',
  74. value_text: user.nama,
  75. },
  76. { key: '2', value: 'pt', value_text: pt[0].nama },
  77. { key: '3', value: 'keterangan', value_text: keterangan },
  78. { key: '4', value: 'no_laporan', value_text: no_laporan },
  79. ])
  80. if (notif[0].status == 'success') {
  81. await logModel.create({
  82. aktivitas: `Server berhasil mengirim notif wa kepada ${contacts} untuk Pembuatan Laporan`,
  83. })
  84. } else {
  85. await logModel.create({
  86. aktivitas: `Server gagal mengirim notif wa kepada ${contacts} untuk Pembuatan Laporan, Error: ${JSON.stringify(notif)}`,
  87. })
  88. }
  89. } catch (error) {
  90. await logModel.create({
  91. aktivitas: `Server gagal mengirim notif wa kepada ${contacts} untuk Pembuatan Laporan, Error: ${error.message}`,
  92. })
  93. }
  94. await pemantauanModel.create({
  95. laporan: data._id,
  96. action: CREATE_LAPORAN,
  97. pt_id: pt[0].id,
  98. user: user._id,
  99. keterangan: 'Membuat Laporan',
  100. dokumen: dokumen_id,
  101. for_pt: false,
  102. })
  103. return response.success(res, {
  104. message: 'Berhasil menambah laporan',
  105. data,
  106. })
  107. })
  108. exports.public = handleError(async (req, res) => {
  109. const user = req.user
  110. const no_laporan = req.no_laporan
  111. let level = req.level
  112. const files = req.files
  113. const isValid = validate(res, req.body, {
  114. pt_id: 'string',
  115. pelanggaran_id: 'string',
  116. keterangan: 'string',
  117. // no_verifikasi: 'string',
  118. })
  119. if (!isValid) return
  120. const { pt_id, keterangan, no_verifikasi } = req.body
  121. let { pelanggaran_id } = req.body
  122. if (no_verifikasi && user.no_verifikasi !== no_verifikasi) {
  123. return response.error(res, {
  124. message: 'no_verifikasi tidak sesuai',
  125. error: { no_verifikasi: 'No. Verifikasi tidak sesuai' },
  126. })
  127. } else if (no_verifikasi && user.no_verifikasi === no_verifikasi) {
  128. level = 3
  129. }
  130. const pt = await axios.get(
  131. `https://api.kemdikbud.go.id:8243/pddikti/1.2/pt/${pt_id}`
  132. )
  133. if (pt.length === 0)
  134. return response.error(res, {
  135. message: 'pt_id tidak ditemukan',
  136. })
  137. let dokumen_id = []
  138. if (files.length) {
  139. const dokumen = await addManyDokumen(files)
  140. dokumen_id = dokumen.map((e) => e._id)
  141. }
  142. pelanggaran_id = pelanggaran_id.split(',')
  143. const pelanggaran = await pelanggaranModel.find({
  144. _id: {
  145. $in: pelanggaran_id,
  146. },
  147. })
  148. if (!pelanggaran.length)
  149. return response.error(res, { message: 'pelanggaran_id tidak ada' })
  150. let data = {
  151. no_laporan,
  152. user: user._id,
  153. dokumen: dokumen_id,
  154. pt: pt[0],
  155. pelanggaran: pelanggaran_id,
  156. keterangan,
  157. role_data: 'dikti',
  158. role_asal: 'dikti',
  159. level,
  160. }
  161. data = await laporanModel.create(data)
  162. await pemantauanModel.create({
  163. laporan: data._id,
  164. action: 'CREATE LAPORAN',
  165. pt_id: pt[0].id,
  166. user: user._id,
  167. keterangan: 'Membuat Laporan',
  168. dokumen: dokumen_id,
  169. for_pt: false,
  170. })
  171. if (no_verifikasi) await userModel.findByIdAndUpdate(user._id, { verified: true })
  172. let contacts = await kontakModel.find()
  173. contacts = contacts.map((e) => e.nama).join(', ')
  174. try {
  175. const notif = await notifWA(TEMPLATE_LAPORAN, [
  176. {
  177. key: '1',
  178. value: 'nama',
  179. value_text: user.isPrivate || !user.nama ? 'rahasia' : user.nama,
  180. },
  181. { key: '2', value: 'pt', value_text: pt[0].nama },
  182. { key: '3', value: 'keterangan', value_text: keterangan },
  183. { key: '4', value: 'no_laporan', value_text: no_laporan },
  184. ])
  185. if (notif[0].status == 'success') {
  186. await logModel.create({
  187. aktivitas: `Server berhasil mengirim notif wa kepada ${contacts} untuk Pembuatan Laporan`,
  188. })
  189. } else {
  190. await logModel.create({
  191. aktivitas: `Server gagal mengirim notif wa kepada ${contacts} untuk Pembuatan Laporan, Error: ${JSON.stringify(notif)}`,
  192. })
  193. }
  194. } catch (error) {
  195. await logModel.create({
  196. aktivitas: `Server gagal mengirim notif wa kepada ${contacts} untuk Pembuatan Laporan, Error: ${error.message}`,
  197. })
  198. }
  199. return response.success(res, {
  200. message: 'Berhasil menambah laporan',
  201. data,
  202. })
  203. })
  204. exports.getLaporanByNoLaporanAndId = handleError(async (req, res) => {
  205. const { no_laporan } = req.params
  206. let where = { evaluasi: { $exists: true, $ne: [] } }
  207. if (isValidObjectId(no_laporan)) where._id = no_laporan
  208. else where.no_laporan = no_laporan
  209. const data = await laporanModel.findOne(where)
  210. .populate({ path: 'user', populate: 'foto' })
  211. .populate({ path: 'pelanggaran', select: 'pelanggaran' })
  212. .populate({ path: 'sanksi', populate: ['pelanggaran'] })
  213. .populate('dokumen')
  214. .populate('peserta_penetapan_sanksi.ttd')
  215. .populate({ path: 'evaluasi', populate: ['user', 'dokumen'] })
  216. if (!data) {
  217. return response.error(res, {
  218. message: 'no_laporan atau id tidak ada',
  219. code: 404,
  220. })
  221. }
  222. return response.success(res, {
  223. message: 'Berhasil ambil data laporan',
  224. data,
  225. })
  226. })
  227. exports.getAll = handleError(async (req, res) => {
  228. const user = req.user
  229. const where = {}
  230. const { no_laporan, pt_id, jadwal, evaluasi, aktif, delegasi, all, sanksi, tuntas } =
  231. req.query
  232. if (no_laporan) where.no_laporan = no_laporan
  233. if (pt_id) where['pt.id'] = pt_id
  234. if (aktif) where.aktif = aktif === 'true'
  235. if (all) where.all = true
  236. else if (delegasi) where.delegasi = delegasi === 'true'
  237. if (jadwal === 'true') {
  238. where.jadwal = {
  239. $exists: true,
  240. $ne: null,
  241. }
  242. } else if (evaluasi === 'true') {
  243. where.evaluasi = {
  244. $exists: true,
  245. $ne: null,
  246. $not: {
  247. $size: 0,
  248. },
  249. }
  250. } else if (sanksi === 'true') {
  251. where.sanksi = {
  252. $exists: true,
  253. $ne: null,
  254. }
  255. } else if (tuntas === 'true') {
  256. let dataLaporan = (await cekBanyakDataLaporan(user, { aktif: 'empty', all: true, }, {lean: true}))
  257. .filter(e => e.tuntas?.keterangan || e.aktif === false || e.aktif === true && e.sanksi?.jawaban?.cabut_sanksi?.status === 'Diterima' || e.sanksi?.aktif === false && !e.sanksi?.masa_berlaku?.from_date)
  258. .map(e => ({ ...e, status: e.aktif === false || e.tuntas?.keterangan ? 'Ditutup' : e.sanksi?.jawaban?.cabut_sanksi?.status === 'Diterima' ? 'Diterima' : !e.sanksi?.masa_berlaku ? 'Selesai' : 'Ditutup' }))
  259. // let dataSanksi = await cekBanyakDataSanksi(user, {
  260. // aktif: false, 'jawaban.cabut_sanksi.status': 'Diterima'
  261. // })
  262. // const w = {}
  263. // switch (user.role.id) {
  264. // case 2020:
  265. // w.$or = [{
  266. // role_asal: DIKTI
  267. // }, {
  268. // role_data: DIKTI
  269. // }]
  270. // break
  271. // case 2021:
  272. // w.$or = [{
  273. // role_asal: LLDIKTI
  274. // }, {
  275. // role_data: LLDIKTI
  276. // }]
  277. // w['pt.pembina.id'] = user.lembaga.id
  278. // break
  279. // }
  280. // const dataLaporan = (await laporanModel.find(w).populate('sanksi').lean())
  281. // .filter(e => e.aktif === false || e.tuntas?.keterangan || e.sanksi?.jawaban?.cabut_sanksi === 'Diterima' && e.sanksi?.aktif === false || !e.sanksi?.masa_berlaku)
  282. // .map(e => ({...e, status: e.aktif === false || e.tuntas?.keterangan ? 'Ditutup' : e.sanksi?.jawaban?.cabut_sanksi === 'Diterima'? 'Diterima' : !e.sanksi?.masa_berlaku ? 'Selesai' : 'Ditutup'}))
  283. return response.success(res, {
  284. message: 'Berhasil ambil data laporan dan sanksi tuntas dan ditutup',
  285. data: dataLaporan
  286. })
  287. }
  288. let data = (await cekBanyakDataLaporan(user, where)).filter(e => !e.sanksi || e.sanksi.aktif === true)
  289. return response.success(res, {
  290. message: 'Berhasil ambil data laporan',
  291. data,
  292. })
  293. })
  294. exports.getOne = handleError(async (req, res) => {
  295. const { id } = req.params
  296. const user = req.user
  297. const { aktif, delegasi, all } = req.query
  298. const where = {}
  299. if (aktif) where.aktif = aktif === TRUE
  300. if (all) where.all = true
  301. else if (delegasi) where.delegasi = delegasi === TRUE
  302. const data = await cekSatuDataLaporan(res, user, id, { normal: true })
  303. if (!data) return
  304. return response.success(res, {
  305. message: 'Berhasil ambil data Laporan',
  306. data,
  307. })
  308. })
  309. exports.update = handleError(async (req, res) => {
  310. const { id } = req.params
  311. const user = req.user
  312. const files = req.files
  313. const laporan = await cekSatuDataLaporan(res, user, id, {normal: true})
  314. if (!laporan) return
  315. const isValid = validate(res, req.body, {
  316. change_role: { type: 'string', optional: true, enum: [TRUE, FALSE] },
  317. aktif: { type: 'string', optional: true, enum: [TRUE, FALSE] },
  318. keterangan: 'string',
  319. })
  320. if (!isValid) return
  321. const data = {}
  322. let keterangan = ''
  323. let alasan = ''
  324. const { change_role, aktif } = req.body
  325. const keterangan2 = req.body.keterangan
  326. if (change_role === TRUE) {
  327. data.flag = DELEGASI
  328. data.role_data = user.role.id === 2020 ? 'lldikti' : 'dikti'
  329. keterangan = `Laporan didelegasi ke ${user.role.id === 2020 ? 'LLDIKTI' : 'DIKTI'}`
  330. alasan = keterangan2
  331. data.alasan_delegasi = keterangan2
  332. // if (laporan.jadwal) {
  333. // await laporanModel.findByIdAndUpdate(laporan._id, {
  334. // $unset: { jadwal: 1 },
  335. // })
  336. // }
  337. }
  338. if (aktif) {
  339. let dokumen_id = []
  340. data.aktif = aktif === 'true'
  341. if (files) {
  342. const dokumen = await addManyDokumen(files)
  343. dokumen_id = dokumen.map((e) => e._id)
  344. }
  345. if (aktif === 'true') {
  346. keterangan = 'Laporan dibuka'
  347. } else {
  348. keterangan = `Laporan ditutup`
  349. alasan = keterangan2
  350. data.flag = DITUTUP
  351. data.tuntas = {
  352. keterangan: keterangan2,
  353. dokumen: dokumen_id,
  354. }
  355. }
  356. }
  357. const update = await laporanModel.findByIdAndUpdate(laporan._id, data)
  358. if (change_role || aktif) {
  359. await pemantauanModel.create({
  360. action: 'UPDATE LAPORAN',
  361. laporan: laporan._id,
  362. pt_id: laporan.pt.id,
  363. user: user._id,
  364. keterangan,
  365. alasan,
  366. for_pt: false,
  367. })
  368. }
  369. return response.success(res, {
  370. message: 'Berhasil update laporan',
  371. data: update,
  372. })
  373. })
  374. exports.jumlahLaporan = handleError(async (req, res) => {
  375. const laporan = await laporanModel.aggregate([
  376. {
  377. $match: {
  378. aktif: true,
  379. },
  380. },
  381. {
  382. $group: {
  383. _id: '$pt.pembina.nama',
  384. jumlah_laporan: {
  385. $sum: 1,
  386. },
  387. propinsi: {
  388. $addToSet: '$pt.propinsi.nama',
  389. },
  390. },
  391. },
  392. {
  393. $sort: {
  394. _id: 1,
  395. },
  396. },
  397. ])
  398. return response.success(res, {
  399. message: 'Jumlah Laporan',
  400. data: laporan,
  401. })
  402. })
  403. exports.laporanByPembina = handleError(async (req, res) => {
  404. const { idPembina } = req.params
  405. const {
  406. penjadwalan,
  407. pemeriksaan,
  408. sanksi,
  409. keberatan,
  410. banding,
  411. perbaikan,
  412. cabutSanksi,
  413. delegasi,
  414. ditutup,
  415. diterima
  416. } = req.query
  417. let where = {}
  418. let where2 = {}
  419. let isLaporan = true
  420. let isSanksi = false
  421. if (penjadwalan === 'true') {
  422. where.jadwal = {
  423. $exists: true,
  424. $ne: null,
  425. }
  426. isLaporan = true
  427. isSanksi = false
  428. }
  429. if (pemeriksaan === 'true') {
  430. where.evaluasi = {
  431. $exists: true,
  432. $ne: null,
  433. $not: {
  434. $size: 0,
  435. },
  436. }
  437. isLaporan = true
  438. isSanksi = false
  439. }
  440. if (sanksi === 'true') {
  441. where.sanksi = {
  442. $exists: true,
  443. $ne: null,
  444. }
  445. isLaporan = false
  446. isSanksi = true
  447. }
  448. if (keberatan === 'true') {
  449. where2['pengajuan.keberatan'] = { $exists: true, $ne: null }
  450. isLaporan = false
  451. isSanksi = true
  452. }
  453. if (banding === 'true') {
  454. where2['pengajuan.banding'] = { $exists: true, $ne: null }
  455. isLaporan = false
  456. isSanksi = true
  457. }
  458. if (cabutSanksi === 'true') {
  459. where2['pengajuan.cabut_sanksi'] = {
  460. $exists: true,
  461. $ne: null,
  462. }
  463. isLaporan = false
  464. isSanksi = true
  465. }
  466. if (perbaikan === 'true') {
  467. where2.perbaikan = {
  468. $exists: true,
  469. $ne: null,
  470. $not: {
  471. $size: 0,
  472. },
  473. }
  474. isLaporan = false
  475. isSanksi = true
  476. }
  477. if(delegasi === 'true') {
  478. where = {
  479. role_asal: 'dikti',
  480. role_data: 'lldikti'
  481. }
  482. isLaporan = true
  483. isSanksi = false
  484. }
  485. if(ditutup === 'true') {
  486. where.aktif = false
  487. isLaporan = true
  488. isSanksi = false
  489. }
  490. if(diterima === 'true') {
  491. where2 = {
  492. 'jawaban.cabut_sanksi.status': 'Diterima',
  493. aktif: false
  494. }
  495. isLaporan = false
  496. isSanksi = true
  497. }
  498. let laporan = []
  499. if (isSanksi) {
  500. laporan = (await laporanModel.find({ ...where, 'pt.pembina.id': idPembina }).lean().populate({ path: 'sanksi', match: where2 }).lean())
  501. .filter(e => e.sanksi)
  502. .map(e => {
  503. let step = 'Pelaporan'
  504. if (e.jadwal && !e.evaluasi.length) step = 'Penjadwalan'
  505. else if (e.evaluasi.length && !e.sanksi) step = 'Pemeriksaan'
  506. else if (e.sanksi?.pengajuan?.cabut_sanksi) step = 'Cabut Sanksi'
  507. else if (e.sanksi?.pengajuan?.keberatan && !e.sanksi?.pengajuan?.banding) step = 'Keberatan'
  508. else if (e.sanksi?.aktif === false && !e.sanksi?.masa_berlaku?.from_date) step = 'Selesai'
  509. else if (e.sanksi?.aktif === false && e.jawaban?.cabut_sanksi?.status === 'Diterima') step = 'Diterima'
  510. else if (e.sanksi?.pengajuan?.banding) step = 'Banding'
  511. else if (e.sanksi) step = 'Sanksi'
  512. return { ...e, step }
  513. })
  514. } else if (isLaporan) {
  515. laporan = (await laporanModel.find({ ...where, 'pt.pembina.id': idPembina }).lean().populate({ path: 'sanksi', match: where2 }).lean())
  516. .map(e => {
  517. let step = 'Pelaporan'
  518. if (e.jadwal && !e.evaluasi.length) step = 'Penjadwalan'
  519. else if (e.evaluasi.length && !e.sanksi) step = 'Pemeriksaan'
  520. else if (e.sanksi?.pengajuan?.cabut_sanksi) step = 'Cabut Sanksi'
  521. else if (e.sanksi?.pengajuan?.keberatan && !e.sanksi?.pengajuan?.banding) step = 'Keberatan'
  522. else if (e.sanksi?.aktif === false && !e.sanksi?.masa_berlaku?.from_date) step = 'Selesai'
  523. else if (e.sanksi?.aktif === false && e.jawaban?.cabut_sanksi?.status === 'Diterima') step = 'Diterima'
  524. else if (e.sanksi?.pengajuan?.banding) step = 'Banding'
  525. else if (e.sanksi) step = 'Sanksi'
  526. return { ...e, step }
  527. })
  528. }
  529. return response.success(res, {
  530. message: 'berhasil get laporan by pembina',
  531. data: laporan,
  532. })
  533. })
  534. exports.getOneLaporanPublic = handleError(async (req, res) => {
  535. const { id } = req.params
  536. const data = await laporanModel.findById(id)
  537. .populate({ path: 'user', populate: 'foto' })
  538. .populate({ path: 'pelanggaran', select: 'pelanggaran' })
  539. .populate({ path: 'sanksi', populate: ['pelanggaran'] })
  540. .populate('dokumen')
  541. .populate('peserta_penetapan_sanksi.ttd')
  542. .populate({ path: 'evaluasi', populate: ['user', 'dokumen'] })
  543. console.log(data)
  544. if (!data) return response.error(res, {
  545. code: 404,
  546. message: 'laporan_id tidak ada'
  547. })
  548. return response.success(res, {
  549. message: 'Berhasil ambil satu data Laporan',
  550. data,
  551. })
  552. })