import { exportDataGrid as exportToExcel } from 'devextreme/excel_exporter' import { saveAs } from 'file-saver' import { jsPDF } from 'jspdf' import autoTable from 'jspdf-autotable' import { Workbook } from 'exceljs' import { setHeaderStyle } from '@/report/utils/xlsx' import { formatNumber, formatPercentage } from '@/utils/numbers' import { formatWaktu } from '@/components/Form/FiltersType/reference' import { getMonthNameShort } from '@/utils/texts' import { exportDetailToWord, exportToWord } from './doc/MonalisaLB_AgingComplaint_DOC' const reportName = '(Monalisa) Aging Complaint' const fontSize = 5 const detailFontSize = 3 const groupingData = (data: any, reportMeta: any) => { const groupedData: any = {} const reportMetaMapping: any = { ulp: 'nama_ulp', up3: 'nama_ulp', uid: 'nama_up3', regional: 'nama_uid', default: 'nama_regional' } let key = 'nama_regional' for (const prop in reportMetaMapping) { if (reportMeta[prop] && reportMeta[prop].id != 0) { key = reportMetaMapping[prop] break } } data.forEach((item: any) => { const groupKey = item[key] if (!groupedData[groupKey]) { groupedData[groupKey] = { data: [] } } groupedData[groupKey].data.push(item) }) for (const key in groupedData) { const data = groupedData[key].data data.forEach((item: any) => { if (!groupedData[key].summary) { groupedData[key].summary = { avg_durasi_recovery_gangguan: [], sla_gangguan: [], avg_durasi_recovery_keluhan: [], sla_keluhan: [], aging_complaint_gangguan: [], aging_complaint_keluhan: [], avg_aging_complaint: [] } } groupedData[key].summary.avg_durasi_recovery_gangguan.push(item.avg_durasi_recovery_gangguan) groupedData[key].summary.sla_gangguan.push(item.sla_gangguan) groupedData[key].summary.avg_durasi_recovery_keluhan.push(item.avg_durasi_recovery_keluhan) groupedData[key].summary.sla_keluhan.push(item.sla_keluhan) groupedData[key].summary.aging_complaint_gangguan.push(item.aging_complaint_gangguan) groupedData[key].summary.aging_complaint_keluhan.push(item.aging_complaint_keluhan) groupedData[key].summary.avg_aging_complaint.push(item.avg_aging_complaint) }) } return groupedData } const getTitle = (reportMeta: any) => { if (reportMeta.ulp.id != 0) { return reportMeta.ulp.name } if (reportMeta.up3.id != 0) { return reportMeta.up3.name } if (reportMeta.uid.id != 0) { return reportMeta.uid.name } if (reportMeta.regional.id != 0) { return reportMeta.regional.name } return 'NASIONAL' } const formatData = (rawData: any, reportMeta: any) => { const formattedData: any = [] const total: any = { avg_durasi_recovery_gangguan: [], sla_gangguan: [], avg_durasi_recovery_keluhan: [], sla_keluhan: [], aging_complaint_gangguan: [], aging_complaint_keluhan: [], avg_aging_complaint: [] } const data = groupingData(rawData, reportMeta) const title = getTitle(reportMeta) formattedData.push([{ content: title, colSpan: 8, styles: { fontStyle: 'bold' } }]) for (const regional in data) { const summary = data[regional].summary const avg_durasi_recovery_gangguan = summary.avg_durasi_recovery_gangguan.reduce((a: number, b: number) => a + b, 0) / summary.avg_durasi_recovery_gangguan.length const sla_gangguan = summary.sla_gangguan.reduce((a: number, b: number) => a + b, 0) / summary.sla_gangguan.length const avg_durasi_recovery_keluhan = summary.avg_durasi_recovery_keluhan.reduce((a: number, b: number) => a + b, 0) / summary.avg_durasi_recovery_keluhan.length const sla_keluhan = summary.sla_keluhan.reduce((a: number, b: number) => a + b, 0) / summary.sla_keluhan.length const aging_complaint_gangguan = summary.aging_complaint_gangguan.reduce((a: number, b: number) => a + b, 0) / summary.aging_complaint_gangguan.length const aging_complaint_keluhan = summary.aging_complaint_keluhan.reduce((a: number, b: number) => a + b, 0) / summary.aging_complaint_keluhan.length const avg_aging_complaint = summary.avg_aging_complaint.reduce((a: number, b: number) => a + b, 0) / summary.avg_aging_complaint.length formattedData.push([ regional, formatNumber(avg_durasi_recovery_gangguan), formatNumber(sla_gangguan), formatNumber(avg_durasi_recovery_keluhan), formatNumber(sla_keluhan), formatPercentage(aging_complaint_gangguan), formatPercentage(aging_complaint_keluhan), formatPercentage(avg_aging_complaint) ]) total.avg_durasi_recovery_gangguan.push(avg_durasi_recovery_gangguan) total.sla_gangguan.push(sla_gangguan) total.avg_durasi_recovery_keluhan.push(avg_durasi_recovery_keluhan) total.sla_keluhan.push(sla_keluhan) total.aging_complaint_gangguan.push(aging_complaint_gangguan) total.aging_complaint_keluhan.push(aging_complaint_keluhan) total.avg_aging_complaint.push(avg_aging_complaint) } formattedData.push([ { content: 'RATA-RATA', styles: { fontStyle: 'bold' } }, formatNumber( total.avg_durasi_recovery_gangguan.reduce((a: number, b: number) => a + b, 0) / total.avg_durasi_recovery_gangguan.length ), formatNumber( total.sla_gangguan.reduce((a: number, b: number) => a + b, 0) / total.sla_gangguan.length ), formatNumber( total.avg_durasi_recovery_keluhan.reduce((a: number, b: number) => a + b, 0) / total.avg_durasi_recovery_keluhan.length ), formatNumber( total.sla_keluhan.reduce((a: number, b: number) => a + b, 0) / total.sla_keluhan.length ), formatPercentage( total.aging_complaint_gangguan.reduce((a: number, b: number) => a + b, 0) / total.aging_complaint_gangguan.length ), formatPercentage( total.aging_complaint_keluhan.reduce((a: number, b: number) => a + b, 0) / total.aging_complaint_keluhan.length ), formatPercentage( total.avg_aging_complaint.reduce((a: number, b: number) => a + b, 0) / total.avg_aging_complaint.length ) ]) return formattedData } const exportToPDF = (reportMeta: any, rawData: any, preview: boolean = false) => { const day = new Date().toLocaleString('id-ID', { weekday: 'long' }) const date = new Date().getDate() const month = new Date().toLocaleString('id-ID', { month: 'long' }) const year = new Date().getFullYear() const data = formatData(rawData, reportMeta) const doc = new jsPDF({ orientation: 'landscape' }) const img = new Image() img.src = '/assets/images/pln-icon.png' doc.addImage(img, 'png', 13.5, 9, 9.5, 13) autoTable(doc, { head: [ ['PT. PLN(Persero)', '', ''], [ 'REGIONAL', ':', reportMeta.regional ? reportMeta.regional.name.toUpperCase() : 'Semua Regional'.toUpperCase() ], [ { content: 'UNIT INDUK', styles: { cellWidth: 40 } }, { content: ':', styles: { cellWidth: 1 } }, reportMeta.uid ? reportMeta.uid.name.toUpperCase() : 'Semua Unit Induk Distribusi/Wilayah'.toUpperCase() ], [ 'UNIT PELAKSANA PELAYANAN PELANGGAN', ':', reportMeta.up3 ? reportMeta.up3.name.toUpperCase() : 'Semua Unit Pelaksanaan Pelayanan Pelanggan'.toUpperCase() ], [ 'UNIT LAYANAN PELANGGAN', ':', reportMeta.ulp ? reportMeta.ulp.name.toUpperCase() : 'Semua Unit Layanan Pelanggan'.toUpperCase() ] ], styles: { fontSize, cellPadding: 0.1, textColor: [0, 0, 0], fontStyle: 'bold' }, theme: 'plain', startY: 10, margin: { left: 25 } }) autoTable(doc, { head: [[`${reportName}`.toUpperCase()], [reportMeta.periode]], styles: { fontSize, cellPadding: 0.1, textColor: [0, 0, 0], fontStyle: 'bold', halign: 'center' }, theme: 'plain', startY: 23 }) autoTable(doc, { head: [ [ { content: 'Nama Unit', rowSpan: 3 }, { content: 'Aging Complains', colSpan: 4 }, { content: '% Aging Complains', colSpan: 2 }, { content: '% Rata2 Aging Complains', rowSpan: 3 } ], [ { content: 'Rata2 RCT Gangguan', colSpan: 2 }, { content: 'Rata2 RCT Keluhan', colSpan: 2 }, { content: 'G', rowSpan: 2 }, { content: 'K', rowSpan: 2 } ], [ getMonthNameShort(reportMeta.currentMonth) + ' ' + reportMeta.currentYear, 'SLA (Menit)', getMonthNameShort(reportMeta.currentMonth) + ' ' + reportMeta.currentYear, 'SLA (Jam)' ], ['1', '2', '3', '4', '5', '6 = 1-((2-3)/3))*100)', '7 = 1-((4-5)/5))*100)', '8 = (6+7)/2'] ], body: data, styles: { fontSize, 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() }) } if (data.cell.text[0] === 'RATA-RATA') { for (const key in data.row.cells) { data.row.cells[key].styles.fillColor = [192, 192, 192] data.row.cells[key].styles.fontStyle = 'bold' } } }, startY: 30 }) autoTable(doc, { head: [ [`${day}, ${date}-${month}-${year}`], [ { content: '(.........................................)', styles: { minCellHeight: 8, valign: 'bottom' } } ] ], styles: { fontSize, cellPadding: 0.1, textColor: [0, 0, 0], fontStyle: 'bold', halign: 'center' }, theme: 'plain', tableWidth: 50, margin: { left: 230 } }) if (preview) { doc.setProperties({ title: `${reportName}` }) window.open(doc.output('bloburl')) } else { doc.save(`Laporan ${reportName}.pdf`, { returnPromise: true }).then(() => { console.log('pdf berhasil disimpan') }) } } const exportDetailToPDF = (reportMeta: any, rawData: any) => { const day = new Date().toLocaleString('id-ID', { weekday: 'long' }) const date = new Date().getDate() const month = new Date().toLocaleString('id-ID', { month: 'long' }) const year = new Date().getFullYear() const doc = new jsPDF({ orientation: 'landscape' }) autoTable(doc, { head: [['PT. PLN(Persero)']], styles: { fontSize: detailFontSize, cellPadding: 0.1, textColor: [0, 0, 0], fontStyle: 'bold' }, theme: 'plain', startY: 10, margin: 5 }) autoTable(doc, { head: [[`Daftar Detail ${reportName}`.toUpperCase()], [reportMeta.periode]], styles: { fontSize: detailFontSize, cellPadding: 0.1, textColor: [0, 0, 0], fontStyle: 'bold', halign: 'center' }, theme: 'plain', startY: 18, margin: 5 }) autoTable(doc, { head: [ [ 'No', 'No Laporan', 'UID/UIW', 'UP3', 'ULP', 'ID Pelanggan', 'Nama Pelanggan', 'Nama Pelaopr', 'Alamat Pelapor', 'No Telp Pelapor', 'Keterangan Pelapor', 'Penyebab', 'Kode Gangguan', 'Jenis Gangguan', 'Durasi Response Time', 'Durasi Recovery Time', 'Tgl Lapor' ] ], body: rawData.map((item: any, i: any) => [ { content: i + 1, styles: { halign: 'right' } }, item.no_laporan, item.nama_uid, item.nama_ulp, item.id_pelanggan, item.nama_pelanggan, item.nama_pelapor, item.alamat_pelapor, item.no_telp_pelapor, item.keterangan_pelapor, item.penyebab, item.kode_gangguan, item.jenis_gangguan, item.durasi_response_time ? formatWaktu(item.durasi_response_time) : '-', item.durasi_recovery_time ? formatWaktu(item.durasi_recovery_time) : '-', item.waktu_lapor ]), styles: { fontSize: detailFontSize, 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: 24, margin: 5 }) autoTable(doc, { head: [ [`${day}, ${date}-${month}-${year}`], [ { content: '(.........................................)', styles: { minCellHeight: 8, valign: 'bottom' } } ] ], styles: { fontSize: detailFontSize, cellPadding: 0.1, textColor: [0, 0, 0], fontStyle: 'bold', halign: 'center' }, theme: 'plain', tableWidth: 50, margin: { left: 230 } }) doc.save(`Laporan Detail ${reportName}.pdf`, { returnPromise: true }).then(() => { console.log('pdf berhasil disimpan') }) } const exportToXLSX = (reportMeta: any, e: any) => { const workbook = new Workbook() const worksheet = workbook.addWorksheet(`${reportName}`) setHeaderStyle(worksheet, 1, 1, 'PT. PLN(Persero)') setHeaderStyle( worksheet, 2, 1, `UNIT INDUK : ${ reportMeta.uid ? reportMeta.uid.name.toUpperCase() : 'Semua Unit Induk Distribusi/Wilayah'.toUpperCase() }` ) setHeaderStyle( worksheet, 3, 1, `UNIT PELAKSANA PELAYANAN PELANGGAN : ${ reportMeta.up3 ? reportMeta.up3.name.toUpperCase() : 'Semua Unit Pelaksanaan Pelayanan Pelanggan'.toUpperCase() }` ) setHeaderStyle( worksheet, 4, 1, `UNIT LAYANAN PELANGGAN : ${ reportMeta.ulp ? reportMeta.ulp.name.toUpperCase() : 'Semua Unit Layanan Pelanggan'.toUpperCase() }` ) setHeaderStyle( worksheet, 5, 1, `REGIONAL : ${ reportMeta.regional ? reportMeta.regional.name.toUpperCase() : 'Semua Regional'.toUpperCase() }` ) setHeaderStyle(worksheet, 7, 1, `${reportName}`.toUpperCase(), true) setHeaderStyle(worksheet, 8, 1, reportMeta.periode, true) worksheet.mergeCells('A1:H1') worksheet.mergeCells('A2:H2') worksheet.mergeCells('A3:H3') worksheet.mergeCells('A4:H4') worksheet.mergeCells('A5:H5') worksheet.mergeCells('A7:H7') worksheet.mergeCells('A8:H8') exportToExcel({ component: e.component, worksheet, autoFilterEnabled: true, topLeftCell: { row: 10, column: 1 }, loadPanel: { enabled: false } }).then(() => { workbook.xlsx.writeBuffer().then((buffer: any) => { saveAs(new Blob([buffer], { type: 'application/octet-stream' }), `Laporan ${reportName}.xlsx`) }) }) e.cancel = true } const exportDetailToXLSX = (reportMeta: any, e: any) => { const workbook = new Workbook() const worksheet = workbook.addWorksheet(`Detail ${reportName}`) setHeaderStyle(worksheet, 1, 1, 'PT. PLN(Persero)') setHeaderStyle(worksheet, 3, 1, `Daftar Detail ${reportName}`.toUpperCase(), true) setHeaderStyle(worksheet, 4, 1, reportMeta.periode, true) worksheet.mergeCells('A1:Q1') worksheet.mergeCells('A3:Q3') worksheet.mergeCells('A4:Q4') exportToExcel({ component: e.component, worksheet, autoFilterEnabled: true, topLeftCell: { row: 6, column: 1 }, loadPanel: { enabled: false } }).then(() => { workbook.xlsx.writeBuffer().then((buffer: any) => { saveAs( new Blob([buffer], { type: 'application/octet-stream' }), `Laporan Detail ${reportName}.xlsx` ) }) }) e.cancel = true } const exportToDOCX = (reportMeta: any, rawData: any) => { exportToWord(reportMeta, formatData(rawData, reportMeta), `Laporan ${reportName}`, null) } const exportDetailToDOCX = (reportMeta: any, rawData: any) => { exportDetailToWord(reportMeta, rawData, `Laporan Detail ${reportName}`, null) } export { exportToPDF, exportToXLSX, exportDetailToPDF, exportDetailToXLSX, exportToDOCX, exportDetailToDOCX }