auto.controller.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. const handleError = require('../../utils/v1/handleError')
  2. const response = require('../../utils/responseHandler')
  3. const { notifWA } = require('../../utils/v1/notifFunction')
  4. const sanksiModel = require('../../model/sanksi.model')
  5. const laporanModel = require('../../model/laporan.model')
  6. const {
  7. TEMPLATE_REMINDER,
  8. TEMPLATE_REMINDER2, TRUE, UPDATE_SANKSI, CREATE_SANKSI, PTB_ADMIN, PTB_DIKTI, PTB_LLDIKTI
  9. } = require('../../utils/constanta')
  10. const moment = require('moment')
  11. const autoSaveModel = require('../../model/autoSave.model')
  12. const { cekSatuDataSanksi, cekSatuDataLaporan } = require('../../utils/v1/cekData')
  13. const logModel = require('../../model/log.model')
  14. const kontakModel = require('../../model/kontak.model')
  15. const pemantauanModel = require('../../model/pemantauan.model')
  16. const batchModel = require('../../model/batch.model')
  17. const pddiktiService = require('../../services/v2/pddikti.service')
  18. exports.keberatan = handleError(async (req, res) => {
  19. const dataSanksi = await sanksiModel
  20. .find({
  21. 'tanggal_akhir_keberatan': {
  22. $lte: moment().toISOString()
  23. },
  24. 'is_pengajuan_keberatan': {
  25. $exists: false,
  26. $eq: null
  27. }
  28. })
  29. .populate('user')
  30. .populate('laporan')
  31. if (!dataSanksi.length) {
  32. return response.success(res, {
  33. message: 'Tidak ada keberatan yang diubah'
  34. })
  35. }
  36. await Promise.all(
  37. dataSanksi.map(
  38. async (sanksi) =>
  39. await sanksiModel.findByIdAndUpdate(sanksi._id, {
  40. is_pengajuan_keberatan: false,
  41. last_step: 'Dokumen Perbaikan'
  42. })
  43. )
  44. )
  45. await logModel.create({
  46. aktivitas: `Server berhasil merubah last_step PT ${dataSanksi.map((e) => e.laporan.pt.nama).join(', ')} menjadi Dokumen Perbaikan`
  47. })
  48. return response.success(res, {
  49. message: 'Notifikasi berhasil terkirim'
  50. })
  51. })
  52. exports.banding = handleError(async (req, res) => {
  53. const dataSanksi = await sanksiModel
  54. .find({
  55. 'tanggal_akhir_banding': {
  56. $lt: moment().toISOString()
  57. },
  58. 'is_pengajuan_banding': {
  59. $exists: false,
  60. $eq: null
  61. },
  62. 'jawaban.keberatan': {
  63. $exists: true,
  64. $ne: null
  65. }
  66. })
  67. .populate('user')
  68. .populate('laporan')
  69. if (!dataSanksi.length) {
  70. return response.success(res, {
  71. message: 'Tidak ada banding yang diubah'
  72. })
  73. }
  74. await Promise.all(
  75. dataSanksi.map(
  76. async (sanksi) => {
  77. await sanksiModel.findByIdAndUpdate(sanksi._id, {
  78. is_pengajuan_banding: false,
  79. last_step: 'Dokumen Perbaikan'
  80. })
  81. }
  82. )
  83. )
  84. await logModel.create({
  85. aktivitas: `Server berhasil merubah last_step PT ${dataSanksi.map((e) => e.laporan.pt.nama).join(', ')} menjadi Dokumen Perbaikan`
  86. })
  87. return response.success(res, {
  88. message: 'Notifikasi berhasil terkirim'
  89. })
  90. })
  91. exports.reminderKeberatan = handleError(async (req, res) => {
  92. let dataSanksi = await sanksiModel
  93. .find({
  94. 'tanggal_akhir_keberatan': {
  95. $exists: true,
  96. $ne: null
  97. },
  98. 'jawaban.keberatan': {
  99. $exists: false,
  100. $eq: null
  101. }
  102. })
  103. .populate('user')
  104. .populate('laporan')
  105. let count = 0
  106. const errors = []
  107. await Promise.all(
  108. dataSanksi.map(async (e) => {
  109. const targetDate = e.batas_waktu?.jawaban_keberatan
  110. const dayLeft = moment(targetDate).diff(new Date(), 'days')
  111. if (dayLeft > 0 && dayLeft <= 7) {
  112. try {
  113. await notifWA(TEMPLATE_REMINDER, [
  114. { key: '1', value: 'no_laporan', value_text: e.laporan.no_laporan },
  115. { key: '2', value: 'keterangan', value_text: 'Proses Menjawab Pengajuan Keberatan' },
  116. { key: '3', value: 'pt', value_text: e.laporan.pt.nama },
  117. { key: '4', value: 'masa', value_text: `menjawab pengajuan keberatan tersisa ${dayLeft} hari lagi.` }
  118. ])
  119. count++
  120. const contacts = await kontakModel.find({ 'role.id': { $in: [PTB_ADMIN, PTB_DIKTI, PTB_LLDIKTI] } })
  121. await logModel.create({
  122. aktivitas: `Server berhasil mengirim notifikasi Whatsapp kepada ${contacts.map((c) => c.nama).join(', ')} dengan Nomor Laporan ${e.laporan.no_laporan} terhadap ${e.laporan.pt.nama} untuk Mengajukan Keberatan`
  123. })
  124. } catch (error) {
  125. errors.push({ laporan: e.laporan.no_laporan, error: error.message })
  126. await logModel.create({ aktivitas: `Server gagal mengirim notifikasi Whatsapp untuk Laporan ${e.laporan.no_laporan}, Error: ${error.message}` })
  127. }
  128. }
  129. })
  130. )
  131. let message = count === 0 ? 'Tidak ada notifikasi yang dikirim' : `Notifikasi berhasil terkirim (${count}/${dataSanksi.length})`
  132. return response.success(res, { message, data: { sent: count, total: dataSanksi.length, errors } })
  133. })
  134. exports.reminderBanding = handleError(async (req, res) => {
  135. let dataSanksi = await sanksiModel
  136. .find({
  137. 'tanggal_akhir_banding': {
  138. $exists: true,
  139. $ne: null
  140. },
  141. 'jawaban.banding': {
  142. $exists: false,
  143. $eq: null
  144. }
  145. })
  146. .populate('user')
  147. .populate('laporan')
  148. let count = 0
  149. const errors = []
  150. await Promise.all(
  151. dataSanksi.map(async (e) => {
  152. const dayLeft = moment(e.batas_waktu.jawaban_banding).diff(new Date(), 'days')
  153. if (dayLeft > 0 && dayLeft <= 7) {
  154. try {
  155. await notifWA(TEMPLATE_REMINDER, [
  156. { key: '1', value: 'no_laporan', value_text: e.laporan.no_laporan },
  157. { key: '2', value: 'keterangan', value_text: 'Proses Menjawab Pengajuan Banding' },
  158. { key: '3', value: 'pt', value_text: e.laporan.pt.nama },
  159. { key: '4', value: 'masa', value_text: `menjawab pengajuan banding tersisa ${dayLeft} hari lagi.` }
  160. ])
  161. count++
  162. const contacts = await kontakModel.find({
  163. 'role.id': { $in: [PTB_ADMIN, PTB_DIKTI, PTB_LLDIKTI] }
  164. })
  165. await logModel.create({
  166. aktivitas: `Server berhasil mengirim notifikasi Whatsapp kepada ${contacts.map((e) => e.nama).join(', ')} dengan Nomor Laporan ${e.laporan.no_laporan} terhadap ${e.laporan.pt.nama} untuk Mengajukan Banding`
  167. })
  168. } catch (error) {
  169. errors.push({ laporan: e.laporan.no_laporan, error: error.message })
  170. await logModel.create({
  171. aktivitas: `Server gagal mengirim notifikasi Whatsapp untuk Laporan ${e.laporan.no_laporan}, Error: ${error.message}`
  172. })
  173. }
  174. }
  175. })
  176. )
  177. let message = count === 0 ? 'Tidak ada notifikasi yang dikirim' : `Notifikasi berhasil terkirim (${count}/${dataSanksi.length})`
  178. return response.success(res, { message, data: { sent: count, total: dataSanksi.length, errors } })
  179. })
  180. exports.updateStatusSanksi = handleError(async (req, res) => {
  181. const sanksi = await sanksiModel.find({
  182. 'masa_berlaku.to_date': {
  183. $lte: new Date().toISOString()
  184. },
  185. aktif: true,
  186. 'masa_berlaku.berakhir': {
  187. $exists: false,
  188. $eq: null
  189. }
  190. }).populate('laporan')
  191. await Promise.all(
  192. sanksi.map(async (e) => {
  193. await pemantauanModel.create({
  194. laporan: e.laporan._id,
  195. sanksi: e._id,
  196. action: UPDATE_SANKSI,
  197. pt_id: e.laporan.pt.id,
  198. keterangan: 'Masa berlaku sanksi sudah melewati TMT',
  199. levelSanksi: 0
  200. })
  201. await sanksiModel.findByIdAndUpdate(e._id, { 'masa_berlaku.berakhir': true })
  202. await batchModel.create({
  203. sanksi: e._id,
  204. type: UPDATE_SANKSI
  205. })
  206. })
  207. )
  208. return response.success(res, {
  209. message: 'update status sanksi berhasil'
  210. })
  211. })
  212. exports.save = handleError(async (req, res) => {
  213. const { id } = req.params
  214. const { laporan: isLaporan, sanksi: isSanksi } = req.query
  215. const user = req.user
  216. let autoData = null
  217. let laporan = null
  218. let sanksi = null
  219. if (isLaporan === TRUE) {
  220. laporan = await cekSatuDataLaporan(res, user, id)
  221. if (!laporan) return
  222. autoData = await autoSaveModel.findOne({ laporan_id: laporan._id })
  223. } else if (isSanksi === TRUE) {
  224. sanksi = await cekSatuDataSanksi(res, user, id)
  225. if (!sanksi) return
  226. autoData = await autoSaveModel.findOne({ sanksi_id: sanksi._id })
  227. } else {
  228. return response.error(res, {
  229. message: 'query harus sanksi atau laporan yg bernilai true'
  230. })
  231. }
  232. if (autoData) {
  233. if (isLaporan) {
  234. const dataSave = await autoSaveModel.findOne({ laporan_id: laporan._id })
  235. await autoSaveModel.updateOne({ laporan_id: laporan._id }, {
  236. laporan: {
  237. ...req.body, PenetapanSanksi: {
  238. dataSuratBA: req.body?.PenetapanSanksi?.dataSuratBA || dataSave.laporan.PenetapanSanksi?.dataSuratBA,
  239. dataUpload: req.body?.PenetapanSanksi?.dataUpload || dataSave.laporan.PenetapanSanksi?.dataUpload,
  240. dataPelanggaran: req.body?.PenetapanSanksi?.dataPelanggaran || dataSave.laporan.PenetapanSanksi?.dataPelanggaran,
  241. activeStep: req.body?.PenetapanSanksi?.activeStep || dataSave.laporan.PenetapanSanksi?.activeStep
  242. }
  243. }
  244. })
  245. } else {
  246. await autoSaveModel.updateOne({ sanksi_id: sanksi._id }, { sanksi: req.body })
  247. }
  248. } else {
  249. if (isLaporan) {
  250. await autoSaveModel.create({ laporan_id: laporan._id, laporan: req.body })
  251. } else {
  252. await autoSaveModel.create({ sanksi_id: sanksi._id, sanksi: req.body })
  253. }
  254. }
  255. return response.success(res, {
  256. message: 'Berhasil menyimpan data auto save'
  257. })
  258. })
  259. exports.getSave = handleError(async (req, res) => {
  260. const { id } = req.params
  261. const { laporan: isLaporan, sanksi: isSanksi } = req.query
  262. let data = null
  263. let laporan = null
  264. let sanksi = null
  265. if (isLaporan === TRUE) {
  266. laporan = await laporanModel.findById(id)
  267. if (!laporan) return response.error(res, {
  268. code: 404,
  269. message: 'laporan_id tidak ada'
  270. })
  271. data = (await autoSaveModel.findOne({ laporan_id: laporan._id })).laporan
  272. } else if (isSanksi === 'true') {
  273. sanksi = await sanksiModel.findById(id)
  274. if (!sanksi) return response.error(res, {
  275. code: 404,
  276. message: 'sanksi_id tidak ada'
  277. })
  278. data = (await autoSaveModel.findOne({ sanksi_id: sanksi._id })).sanksi
  279. } else {
  280. return response.error(res, {
  281. message: 'harus terdapat query sanksi atau laporan yg bernilai true'
  282. })
  283. }
  284. return response.success(res, {
  285. message: 'Berhasil mengambil data auto save',
  286. data: data
  287. })
  288. })
  289. exports.berakhirSanksi = handleError(async (req, res) => {
  290. const sanksi = await sanksiModel.find({
  291. 'masa_berlaku.to_date': {
  292. $ne: null,
  293. $exists: true
  294. }
  295. }).populate('laporan')
  296. let count = 0
  297. await Promise.all(sanksi.map(async e => {
  298. const dayLeft = moment(e.masa_berlaku.to_date).diff(
  299. new Date(),
  300. 'days'
  301. )
  302. if (dayLeft > 0 && dayLeft <= 7) {
  303. try {
  304. await notifWA(TEMPLATE_REMINDER2, [
  305. {
  306. key: '1',
  307. value: 'no_sanksi',
  308. value_text: `nomor sanksi ${e.no_sanksi}`
  309. },
  310. {
  311. key: '2',
  312. value: 'nama_pt',
  313. value_text: `${e.laporan.pt.nama}`
  314. },
  315. {
  316. key: '3',
  317. value: 'keterangan',
  318. value_text: `habis masa berlaku sanksi tersisa ${dayLeft} hari lagi.`
  319. }
  320. ])
  321. count++
  322. const contacts = await kontakModel.find({
  323. 'role.id': {
  324. $in: [PTB_ADMIN, PTB_DIKTI, PTB_LLDIKTI]
  325. }
  326. })
  327. await logModel.create({
  328. aktivitas: `Server berhasil mengirim notifikasi reminder Whatsapp kepada ${contacts.map((e) => e.nama).join(', ')} dengan Nomor Sanksi ${e.no_sanksi} terhadap ${e.laporan.pt.nama} bahwa Masa Berlaku Sanksi tersisa ${dayLeft} hari lagi.`
  329. })
  330. } catch (error) {
  331. return response.error(res, {
  332. message: 'Notifikasi gagal terkirim',
  333. error: error.message
  334. })
  335. }
  336. }
  337. }))
  338. let message = 'Notifikasi berhasil terkirim'
  339. if (count === 0) message = 'tidak ada notifikasi yg dikirim'
  340. return response.success(res, {
  341. message
  342. })
  343. })
  344. exports.batchUpdateSanksi = handleError(async (req, res) => {
  345. const data = await batchModel.find({
  346. type: UPDATE_SANKSI
  347. })
  348. .populate({
  349. path: 'sanksi',
  350. populate: ['laporan']
  351. })
  352. let error = []
  353. await Promise.all(data.map(async e => {
  354. const { sanksi } = e
  355. if (!sanksi?.laporan) return
  356. try {
  357. await pddiktiService.updatePDDIKTI({
  358. ptKode: sanksi.laporan.pt.kode,
  359. noSanksi: sanksi.laporan.no_laporan,
  360. fromDate: moment(sanksi.masa_berlaku.from_date).format('YYYY-MM-DD'),
  361. levelSanksi: sanksi.levelSanksi,
  362. terimaSanksi: moment(sanksi.tanggal_terima_sanksi).format('YYYY-MM-DD')
  363. })
  364. await logModel.create({
  365. aktivitas: `Server berhasil mengirimkan data Ke API PDDIKTI untuk update Status PT ${sanksi.laporan.pt.nama}`
  366. })
  367. await batchModel.deleteOne(e._id)
  368. } catch (e) {
  369. error.push(e.message)
  370. await Promise.all([
  371. logModel.create({
  372. aktivitas: `Server gagal mengirimkan data Ke API PDDIKTI untuk update Status PT ${sanksi.laporan.pt.nama}, dengan error ${e.message}`
  373. }),
  374. pemantauanModel.deleteOne({
  375. laporan: sanksi.laporan._id,
  376. sanksi: sanksi._id,
  377. action: CREATE_SANKSI
  378. })
  379. ])
  380. }
  381. }))
  382. return response.success(res, {
  383. message: error.length ? 'Ada beberapa data yang tidak bisa dikirim ke PDDIKTI' : 'Berhasil mengirim data ke PDDIKTI',
  384. data: { error },
  385. })
  386. })