diff --git a/src/assets/css/style.css b/src/assets/css/style.css index a480c9f..4784f11 100755 --- a/src/assets/css/style.css +++ b/src/assets/css/style.css @@ -1526,6 +1526,10 @@ body { display: inline-flex; } +.table { + display: table; +} + .grid { display: grid; } diff --git a/src/components/Pages/Gangguan/Rekap/RGangguan_ALL.vue b/src/components/Pages/Gangguan/Rekap/RGangguan_ALL.vue index 1ff01ca..420b953 100755 --- a/src/components/Pages/Gangguan/Rekap/RGangguan_ALL.vue +++ b/src/components/Pages/Gangguan/Rekap/RGangguan_ALL.vue @@ -1037,6 +1037,7 @@ import InputText from '@/components/InputText.vue' import { apolloClient } from '@/utils/api/api.graphql' import { provideApolloClient } from '@vue/apollo-composable' import autoTable from 'jspdf-autotable' +import { exportToPDF } from '@/report/Gangguan/Rekap/RGangguan_ALL' const client = apolloClient() provideApolloClient(client) @@ -1052,6 +1053,12 @@ const dialogDetail = ref(false) const closedialogDetail = () => (dialogDetail.value = false) const loadingData = ref(false) const loadingSubData = ref(false) +const reportMeta = ref({ + uid: { id: 0, name: 'Semua Unit Induk Distribusi/Wilayah' }, + up3: { id: 0, name: 'Semua Unit Pelaksanaan Pelayanan Pelanggan' }, + posko: { id: 0, name: 'Semua Posko' }, + periode: '' +}) const calculateCustomSummary = (options: any) => { if (options.name == 'persenSelesai') { @@ -1190,119 +1197,7 @@ const showDetail = () => { const onExporting = (e: any) => { if (e.format === 'pdf') { - const doc = new jsPDF({ - orientation: 'landscape' - }) - - autoTable(doc, { - head: [ - // [ - // 'No', - // 'No Laporan', - // 'Nama Pelapor', - // 'Alamat Pelapor', - // 'No Telp Pelapor', - // 'Keterangan Pelapor', - // 'Status', - // 'Tgl Lapor', - // 'Tgl Response', - // 'Tgl Recovery', - // 'Durasi Response Time', - // 'Durasi Recovery Time', - // 'Sumber Lapor', - // 'Tgl Media', - // 'Keterangan Media' - // ], - // ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15'] - [ - { - content: 'Nama Unit', - rowSpan: 2 - }, - { - content: 'Total', - rowSpan: 2 - }, - { - content: 'Selesai', - rowSpan: 2 - }, - { - content: '%', - rowSpan: 2 - }, - { - content: 'In Proses', - rowSpan: 2 - }, - { - content: '%', - rowSpan: 2 - }, - { - content: 'Dispatching Time', - colSpan: 5 - }, - { - content: 'Response Time', - colSpan: 5 - }, - { - content: 'Recovery Time', - colSpan: 5 - } - ], - ['Rata-Rata', 'Max', 'Min', '>SLA', ' [ - // { content: ++i, styles: { halign: 'right' } }, - // item.no_laporan, - // item.nama_pelapor, - // item.alamat_pelapor, - // item.no_telp_pelapor, - // item.keterangan_pelapor, - // item.status_akhir, - // item.waktu_lapor, - // item.waktu_response, - // item.waktu_recovery, - // parseInt(item.durasi_response_time) ? formatWaktu(item.durasi_response_time) : '-', - // parseInt(item.durasi_recovery_time) ? formatWaktu(item.durasi_recovery_time) : '-', - // item.nama_posko, - // item.waktu_media, - // item.keterangan_media - // ]), - styles: { - fontSize: 3, - cellPadding: 1, - lineColor: [0, 0, 0], - lineWidth: 0.1, - cellWidth: 'auto' - }, - rowPageBreak: 'auto', - headStyles: { - fillColor: [192, 192, 192], - textColor: [0, 0, 0], - fontStyle: 'bold', - cellWidth: 'wrap', - halign: 'center', - valign: 'middle' - }, - bodyStyles: { - textColor: [0, 0, 0] - }, - didParseCell: function (data) { - if (data.row.section === 'head') { - data.cell.text = data.cell.text.map(function (word: any) { - return word.toUpperCase() - }) - } - }, - startY: 23 - }) - - doc.save('Laporan Rekapitulasi Gangguan All.pdf', { returnPromise: true }).then(() => { - console.log('pdf berhasil disimpan') - }) + exportToPDF(reportMeta, data) } else { const workbook = new Workbook() const worksheet = workbook.addWorksheet('Employees') @@ -1334,6 +1229,7 @@ const onDataSubSelectionChanged = ({ selectedRowsData }: any) => { } const filters = ref() + onMounted(() => { if (import.meta.env.DEV) { data.value = dummyData.gangguan.rekap.rekapitulasiAllGangguan diff --git a/src/report/Gangguan/Rekap/RGangguan_ALL.ts b/src/report/Gangguan/Rekap/RGangguan_ALL.ts new file mode 100644 index 0000000..edfc07a --- /dev/null +++ b/src/report/Gangguan/Rekap/RGangguan_ALL.ts @@ -0,0 +1,362 @@ +import { exportDataGrid as exportToExcel } from 'devextreme/excel_exporter' +import { + Document, + AlignmentType, + Packer, + Paragraph, + Table, + TableCell, + TableRow, + VerticalAlign, + TextRun, + WidthType, + PageOrientation +} from 'docx' +import { saveAs } from 'file-saver' +import { jsPDF } from 'jspdf' +import autoTable from 'jspdf-autotable' +import { Workbook } from 'exceljs' +import { formatWaktu } from '@/components/Form/FiltersType/reference' +import { setHeaderStyle } from '@/report/utils/xlsx' +import { formatNumber, formatPercentage } from '@/utils/numbers' + +const reportName = 'Rekapitulasi Gangguan All' + +const groupingData = (data: any) => { + const groupedData: any = {} + + data.value.forEach((item: any) => { + const { nama_regional, nama_uid } = item + + if (!groupedData[nama_regional]) { + groupedData[nama_regional] = {} + } + + if (!groupedData[nama_regional][nama_uid]) { + groupedData[nama_regional][nama_uid] = { data: [] } + } + + groupedData[nama_regional][nama_uid].data.push(item) + }) + + for (const regional in groupedData) { + for (const uid in groupedData[regional]) { + const data = groupedData[regional][uid].data + + data.forEach((item: any) => { + if (!groupedData[regional][uid].summary) { + groupedData[regional][uid].summary = { + total: 0, + total_selesai: 0, + persen_selesai: [], + total_inproses: 0, + persen_inproses: [], + avg_durasi_dispatch: [], + max_durasi_dispatch: 0, + min_durasi_dispatch: 0, + total_diatas_sla_dispatch: 0, + total_dibawah_sla_dispatch: 0, + avg_durasi_response: [], + max_durasi_response: 0, + min_durasi_response: 0, + total_diatas_sla_response: 0, + total_dibawah_sla_response: 0, + avg_durasi_recovery: [], + max_durasi_recovery: 0, + min_durasi_recovery: 0, + total_diatas_sla_recovery: 0, + total_dibawah_sla_recovery: 0 + } + } + + groupedData[regional][uid].summary.total += item.total + groupedData[regional][uid].summary.total_selesai += item.total_selesai + groupedData[regional][uid].summary.persen_selesai.push(item.persen_selesai) + groupedData[regional][uid].summary.total_inproses += item.total_inproses + groupedData[regional][uid].summary.persen_inproses.push(item.persen_inproses) + groupedData[regional][uid].summary.avg_durasi_dispatch.push(item.avg_durasi_dispatch) + groupedData[regional][uid].summary.max_durasi_dispatch += item.max_durasi_dispatch + groupedData[regional][uid].summary.min_durasi_dispatch += item.min_durasi_dispatch + groupedData[regional][uid].summary.total_diatas_sla_dispatch += + item.total_diatas_sla_dispatch + groupedData[regional][uid].summary.total_dibawah_sla_dispatch += + item.total_dibawah_sla_dispatch + groupedData[regional][uid].summary.avg_durasi_response.push(item.avg_durasi_response) + groupedData[regional][uid].summary.max_durasi_response += item.max_durasi_response + groupedData[regional][uid].summary.min_durasi_response += item.min_durasi_response + groupedData[regional][uid].summary.total_diatas_sla_response += + item.total_diatas_sla_response + groupedData[regional][uid].summary.total_dibawah_sla_response += + item.total_dibawah_sla_response + groupedData[regional][uid].summary.avg_durasi_recovery.push(item.avg_durasi_recovery) + groupedData[regional][uid].summary.max_durasi_recovery += item.max_durasi_recovery + groupedData[regional][uid].summary.min_durasi_recovery += item.min_durasi_recovery + groupedData[regional][uid].summary.total_diatas_sla_recovery += + item.total_diatas_sla_recovery + groupedData[regional][uid].summary.total_dibawah_sla_recovery += + item.total_dibawah_sla_recovery + }) + } + } + + return groupedData +} + +const formatData = (rawData: any) => { + const data = groupingData(rawData) + const formattedData: any = [] + + for (const regional in data) { + formattedData.push([{ content: regional, colSpan: 21, styles: { fontStyle: 'bold' } }]) + + for (const uid in data[regional]) { + const summary = data[regional][uid].summary + + formattedData.push([ + uid, + formatNumber(summary.total), + formatNumber(summary.total_selesai), + summary.persen_selesai.length + ? summary.persen_selesai.reduce((a: any, b: any) => a + b) / summary.persen_selesai.length + : 0, + summary.total_inproses, + summary.persen_inproses.length + ? summary.persen_inproses.reduce((a: any, b: any) => a + b) / + summary.persen_inproses.length + : 0, + formatNumber( + summary.avg_durasi_dispatch.length + ? summary.avg_durasi_dispatch.reduce((a: any, b: any) => a + b) / + summary.avg_durasi_dispatch.length + : 0 + ), + formatWaktu(summary.max_durasi_dispatch), + formatWaktu(summary.min_durasi_dispatch), + formatNumber(summary.total_diatas_sla_dispatch), + formatNumber(summary.total_dibawah_sla_dispatch), + formatNumber( + summary.avg_durasi_response.length + ? summary.avg_durasi_response.reduce((a: any, b: any) => a + b) / + summary.avg_durasi_response.length + : 0 + ), + formatWaktu(summary.max_durasi_response), + formatWaktu(summary.min_durasi_response), + formatNumber(summary.total_diatas_sla_response), + formatNumber(summary.total_dibawah_sla_response), + formatNumber( + summary.avg_durasi_recovery.length + ? summary.avg_durasi_recovery.reduce((a: any, b: any) => a + b) / + summary.avg_durasi_recovery.length + : 0 + ), + formatWaktu(summary.max_durasi_recovery), + formatWaktu(summary.min_durasi_recovery), + formatNumber(summary.total_diatas_sla_recovery), + formatNumber(summary.total_dibawah_sla_recovery) + ]) + } + } + + return formattedData +} + +const formatMetaData = (reportMeta: any) => { + const periode = reportMeta.value.periode ? reportMeta.value.periode.split(' s/d ') : '' + + let dateFromFormat = '' + let dateToFormat = '' + let dayTo = '' + + if (periode != '') { + const dateFrom = new Date(periode[0].split('-').reverse().join('-')) + const dateTo = new Date(periode[1].split('-').reverse().join('-')) + + dateFromFormat = `${dateFrom.getDate()}-${dateFrom.toLocaleString('default', { + month: 'long' + })}-${dateFrom.getFullYear()}` + + dateToFormat = `${dateTo.getDate()}-${dateTo.toLocaleString('default', { + month: 'long' + })}-${dateTo.getFullYear()}` + + dayTo = dateTo.toLocaleString('default', { weekday: 'long' }) + } + + return { dateFromFormat, dateToFormat, dayTo } +} + +const exportToPDF = (reportMeta: any, rawData: any) => { + const data = formatData(rawData) + const meta = formatMetaData(reportMeta) + const doc = new jsPDF({ + orientation: 'landscape' + }) + + autoTable(doc, { + head: [ + ['PT. PLN(Persero)', '', ''], + [ + { content: 'UNIT INDUK', styles: { cellWidth: 25 } }, + { content: ':', styles: { cellWidth: 1 } }, + reportMeta.value.uid + ? reportMeta.value.uid.name.toUpperCase() + : 'Semua Unit Induk Distribusi/Wilayah'.toUpperCase() + ], + [ + 'UNIT PELAKSANA PELAYANAN PELANGGAN', + ':', + reportMeta.value.up3 + ? reportMeta.value.up3.name.toUpperCase() + : 'Semua Unit Pelaksanaan Pelayanan Pelanggan'.toUpperCase() + ], + [ + 'POSKO', + ':', + reportMeta.value.posko + ? reportMeta.value.posko.name.toUpperCase() + : 'Semua Posko'.toUpperCase() + ] + ], + styles: { + fontSize: 3, + cellPadding: 0.1, + textColor: [0, 0, 0], + fontStyle: 'bold' + }, + theme: 'plain', + startY: 10 + }) + + autoTable(doc, { + head: [ + [`${reportName}`.toUpperCase()], + [`PERIODE TANGGAL : ${meta.dateFromFormat} SD TGL ${meta.dateToFormat}`] + ], + styles: { + fontSize: 3, + cellPadding: 0.1, + textColor: [0, 0, 0], + fontStyle: 'bold', + halign: 'center' + }, + theme: 'plain', + startY: 18 + }) + + autoTable(doc, { + head: [ + [ + { + content: 'Nama Unit', + rowSpan: 2 + }, + { + content: 'Total', + rowSpan: 2 + }, + { + content: 'Selesai', + rowSpan: 2 + }, + { + content: '%', + rowSpan: 2 + }, + { + content: 'In Proses', + rowSpan: 2 + }, + { + content: '%', + rowSpan: 2 + }, + { + content: 'Dispatching Time', + colSpan: 5 + }, + { + content: 'Response Time', + colSpan: 5 + }, + { + content: 'Recovery Time', + colSpan: 5 + } + ], + [ + 'Rata-Rata', + 'Max', + 'Min', + '>SLA', + 'SLA', + 'SLA', + ' { + console.log('pdf berhasil disimpan') + }) +} + +export { exportToPDF }