auto.controller.js 12 KB

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