laporan.controller.js 16 KB

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