Browse Source

export to excel

andifebri 3 years ago
parent
commit
021a3f58b0

+ 1 - 1
controller/dokumen.controller.js

@@ -5,5 +5,5 @@ exports.getDokumen = handleError(async (req, res) => {
   const { id } = req.params
   const data = await chunkModel.findById(id)
   res.header('Content-Type', data.type)
-  return res.end(new Buffer(data.data, 'base64'))
+  return res.end(Buffer.from(data.data))
 })

+ 154 - 0
controller/graph.controller.js

@@ -1,9 +1,12 @@
 const handleError = require('../utils/handleError')
+const excel = require('../utils/excel')
 const response = require('../utils/responseHandler')
 const {
   cekBanyakDataLaporan,
   dataLaporanAggregate,
 } = require('../utils/cekData')
+const laporanModel = require('../model/laporan.model')
+const moment = require('moment')
 
 exports.laporan = handleError(async (req, res) => {
   const user = req.user
@@ -223,3 +226,154 @@ exports.laporan = handleError(async (req, res) => {
     data,
   })
 })
+
+exports.excel = handleError(async (req, res) => {
+  const user = req.user
+  const w = {}
+  const date = new Date()
+  switch (user.role.id) {
+    case 2020:
+      w['$or'] = [
+        {
+          role_asal: 'dikti',
+        },
+        {
+          role_data: 'dikti',
+        },
+      ]
+      break
+    case 2021:
+      w['$or'] = [
+        {
+          role_asal: 'lldikti',
+        },
+        {
+          role_data: 'lldikti',
+        },
+      ]
+      w['pt.pembina.id'] = user.lembaga.id
+      break
+    default:
+      return response.error(res, {
+        message: 'Forbidden',
+        code: 403,
+      })
+  }
+
+  const { tahun } = req.query
+
+  berdasarkan_tahun = {
+    $and: [
+      {
+        createdAt: {
+          $gte: new Date(`${tahun || date.getFullYear()}`),
+        },
+      },
+      {
+        createdAt: {
+          $lt: new Date(`${parseInt(tahun) + 1 || date.getFullYear() + 1}`),
+        },
+      },
+    ],
+  }
+
+  const laporan = await laporanModel
+    .find({ ...w, ...berdasarkan_tahun })
+    .populate('user')
+
+  const dataDelegasi = laporan.map((value) => ({
+    Tanggal: moment(value.createdAt).format('DD-MMMM-YYYY'),
+    'No. Laporan': value.no_laporan,
+    'Nama Perguruan Tinggi': value.pt.nama,
+    'Keterangan Laporan': value.keterangan,
+    'Dibuat Oleh': value.user.nama,
+    Status: !value.aktif
+      ? 'Ditutup'
+      : (value.role_asal === 'dikti' && value.role_data === 'dikti') ||
+        (value.role_data == 'dikti' && user.role.id === 2020) ||
+        (value.role_asal === 'lldikti' && value.role_data === 'lldikti') ||
+        (value.role_data == 'lldikti' && user.role.id === 2021)
+      ? `Ditindaklanjuti ${value.role_data === 'dikti' ? 'DIKTI' : 'LLDIKTI'}`
+      : `Delegasi Ke ${value.role_data === 'dikti' ? 'DIKTI' : 'LLDIKTI'}`,
+  }))
+
+  const dataLaporan = laporan.map((value) => ({
+    Tanggal: moment(value.createdAt).format('DD-MMMM-YYYY'),
+    'No. Laporan': value.no_laporan,
+    'Nama Perguruan Tinggi': value.pt.nama,
+    'Keterangan Laporan': value.keterangan,
+    'Dibuat Oleh': value.user.nama,
+    Status:
+      value.sanksi || value.aktif === false
+        ? 'Pelaporan Selesai'
+        : 'Pelaporan Belum Selesai',
+  }))
+
+  const dataJadwal = laporan
+    .filter((e) => e.aktif === true)
+    .map((value) => ({
+      Tanggal: moment(value.createdAt).format('DD-MMMM-YYYY'),
+      'No. Laporan': value.no_laporan,
+      'Nama Perguruan Tinggi': value.pt.nama,
+      'Keterangan Laporan': value.keterangan,
+      'Dibuat Oleh': value.user.nama,
+      'Dari Tanggal':
+        value.jadwal.judul &&
+        moment(value.jadwal.dari_tanggal).format('DD-MMMM-YYYY'),
+      'Sampai Tanggal':
+        value.jadwal.judul &&
+        moment(value.jadwal.sampai_tanggal).format('DD-MMMM-YYYY'),
+      Status: value.jadwal.judul ? 'Sudah ada jadwal' : 'Belum ada jadwal',
+    }))
+
+  const dataPemeriksaan = laporan
+    .filter((e) => e.aktif === true && e.jadwal.judul)
+    .map((value) => ({
+      Tanggal: moment(value.createdAt).format('DD-MMMM-YYYY'),
+      'No. Laporan': value.no_laporan,
+      'Nama Perguruan Tinggi': value.pt.nama,
+      'Keterangan Laporan': value.keterangan,
+      'Dibuat Oleh': value.user.nama,
+      Status: value.evaluasi.length ? 'Sudah diperiksa' : 'Belum diperiksa',
+    }))
+
+  const dataSanksi = laporan
+    .filter((e) => e.aktif === true && e.evaluasi.length)
+    .map((value) => ({
+      Tanggal: moment(value.createdAt).format('DD-MMMM-YYYY'),
+      'No. Laporan': value.no_laporan,
+      'Nama Perguruan Tinggi': value.pt.nama,
+      'Keterangan Laporan': value.keterangan,
+      'Dibuat Oleh': value.user.nama,
+      Status: value.sanksi ? 'Sudah ditetapkan' : 'Belum ditetapkan',
+    }))
+
+  const buffer = excel.to_excel([
+    {
+      SheetNames: 'Delegasi',
+      data: dataDelegasi,
+    },
+    {
+      SheetNames: 'Pelaporan',
+      data: dataLaporan,
+    },
+    {
+      SheetNames: 'Penjadwalan',
+      data: dataJadwal,
+    },
+    {
+      SheetNames: 'Pemeriksaan',
+      data: dataPemeriksaan,
+    },
+    {
+      SheetNames: 'Sanksi',
+      data: dataSanksi,
+    },
+  ])
+
+  res.header(
+    'Content-Type',
+    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+  )
+  return res.end(Buffer.from(buffer))
+})

+ 3 - 1
middleware/verifyToken.js

@@ -4,7 +4,9 @@ const response = require('../utils/responseHandler')
 
 module.exports = (req, res, next) => {
   const authHeader = req.headers.authorization
-  const token = authHeader && authHeader.split(' ')[1]
+  const token =
+    (req.params.token && req.params.token.split(' ')[1]) ||
+    (authHeader && authHeader.split(' ')[1])
 
   if (!token)
     return response.error(res, {

+ 61 - 0
package-lock.json

@@ -391,6 +391,11 @@
       "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
       "dev": true
     },
+    "adler-32": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
+      "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A=="
+    },
     "agent-base": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@@ -703,6 +708,15 @@
       "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
       "dev": true
     },
+    "cfb": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
+      "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
+      "requires": {
+        "adler-32": "~1.3.0",
+        "crc-32": "~1.2.0"
+      }
+    },
     "chalk": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -772,6 +786,11 @@
         "mimic-response": "^1.0.0"
       }
     },
+    "codepage": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
+      "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA=="
+    },
     "color-convert": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -905,6 +924,11 @@
         "vary": "^1"
       }
     },
+    "crc-32": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
+      "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
+    },
     "cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -1374,6 +1398,11 @@
       "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
       "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
     },
+    "frac": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
+      "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA=="
+    },
     "fresh": {
       "version": "0.5.2",
       "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@@ -3004,6 +3033,14 @@
       "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
       "dev": true
     },
+    "ssf": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
+      "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
+      "requires": {
+        "frac": "~1.1.2"
+      }
+    },
     "statuses": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
@@ -3401,6 +3438,16 @@
         "string-width": "^4.0.0"
       }
     },
+    "wmf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
+      "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw=="
+    },
+    "word": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
+      "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA=="
+    },
     "word-wrap": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
@@ -3441,6 +3488,20 @@
       "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
       "dev": true
     },
+    "xlsx": {
+      "version": "0.18.5",
+      "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
+      "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
+      "requires": {
+        "adler-32": "~1.3.0",
+        "cfb": "~1.2.1",
+        "codepage": "~1.15.0",
+        "crc-32": "~1.2.1",
+        "ssf": "~0.11.2",
+        "wmf": "~1.0.1",
+        "word": "~0.3.0"
+      }
+    },
     "xtend": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

+ 2 - 1
package.json

@@ -21,7 +21,8 @@
     "moment": "^2.29.1",
     "mongoose": "^6.2.7",
     "morgan": "~1.9.1",
-    "multer": "^1.4.4"
+    "multer": "^1.4.4",
+    "xlsx": "^0.18.5"
   },
   "devDependencies": {
     "eslint": "^8.10.0",

+ 4 - 1
routes/v1/graph.routes.js

@@ -1,6 +1,9 @@
 const router = require('express').Router()
 const graph = require('../../controller/graph.controller')
+const auth = require('../../middleware/verifyToken')
+const roleId = require('../../middleware/role')
 
-router.get('/', graph.laporan)
+router.get('/', auth, roleId([2020, 2021]), graph.laporan)
+router.get('/:token/:nama_file', auth, roleId([2020, 2021]), graph.excel)
 
 module.exports = router

+ 1 - 1
routes/v1/index.js

@@ -18,6 +18,6 @@ router.use('/pemantauan', auth, require('./pemantauan.routes'))
 router.use('/pt', auth, require('./pt.routes'))
 router.use('/pelanggaran', auth, require('./pelanggaran.routes'))
 router.use('/lembaga', auth, roleId(2020), require('./lembaga.routes'))
-router.use('/graph', auth, roleId([2020, 2021]), require('./graph.routes'))
+router.use('/graph', require('./graph.routes'))
 
 module.exports = router

+ 24 - 0
utils/excel.js

@@ -0,0 +1,24 @@
+const XLSX = require('xlsx')
+
+module.exports.to_excel = (
+  table = [
+    {
+      SheetNames,
+      data: [],
+    },
+  ]
+) => {
+  let wb = XLSX.utils.book_new()
+  wb.Props = {
+    Title: 'Laporan',
+    Author: 'RISTEK DIKTI',
+    CreatedDate: new Date(),
+  }
+
+  table.forEach((e) => {
+    wb.SheetNames.push(e.SheetNames)
+    wb.Sheets[e.SheetNames] = XLSX.utils.json_to_sheet(e.data)
+  })
+
+  return XLSX.write(wb, { type: 'buffer' })
+}