feat: create export laporan cico

This commit is contained in:
kur0nek-o 2024-04-04 00:11:19 +07:00
parent 0114347427
commit f2259e7f2c
2 changed files with 573 additions and 30 deletions

View File

@ -1,5 +1,11 @@
<template>
<Filters @run-search="() => filterData(filters)" :report-button="true" class="mb-4">
<Filters
@run-report="() => exportToPDF(reportMeta, data, true)"
@reset-form="data = []"
@run-search="() => filterData(filters)"
:report-button="true"
class="mb-4"
>
<Type1 @update:filters="(value) => (filters = value)" />
</Filters>
@ -193,7 +199,7 @@
:hover-state-enabled="true"
@selection-changed="onDataSubSelectionChanged"
:column-width="100"
@exporting="onExporting"
@exporting="onExportingDetail"
:allow-column-resizing="true"
column-resizing-mode="widget"
>
@ -868,14 +874,8 @@ import {
DxSummary,
DxTotalItem
} from 'devextreme-vue/data-grid'
import { jsPDF } from 'jspdf'
import { exportDataGrid as exportToPdf } from 'devextreme/pdf_exporter'
import { exportDataGrid as exportToExcel } from 'devextreme/excel_exporter'
import { saveAs } from 'file-saver'
import { Workbook } from 'exceljs'
import Filters from '@/components/Form/Filters.vue'
import { Type1 } from '@/components/Form/FiltersType'
import { useQuery } from '@vue/apollo-composable'
import { queries, requestGraphQl } from '@/utils/api/api.graphql'
import { formatNumber, formatPercentage, isNumber } from '@/utils/numbers'
import DetailDialog from '@/components/Dialogs/DetailDialog.vue'
@ -884,6 +884,12 @@ import { formatWaktu } from '@/components/Form/FiltersType/reference'
import { apolloClient } from '@/utils/api/api.graphql'
import { provideApolloClient } from '@vue/apollo-composable'
import BufferDialog from '@/components/Dialogs/BufferDialog.vue'
import {
exportToPDF,
exportToXLSX,
exportDetailToPDF,
exportDetailToXLSX
} from '@/report/Cico/LaporanCICO'
const client = apolloClient()
provideApolloClient(client)
@ -899,6 +905,12 @@ const dataSub = ref<any[]>([])
const dialogDetail = ref(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 closedialogDetail = () => (dialogDetail.value = false)
@ -951,30 +963,19 @@ const showDetail = () => {
const onExporting = (e: any) => {
if (e.format === 'pdf') {
const doc = new jsPDF()
exportToPdf({
jsPDFDocument: doc,
component: e.component,
indent: 5
}).then(() => {
doc.save(`.pdf`)
})
exportToPDF(reportMeta.value, data.value)
} else if (e.format === 'xlsx') {
exportToXLSX(reportMeta.value, e)
} else {
const workbook = new Workbook()
const worksheet = workbook.addWorksheet('Employees')
}
}
exportToExcel({
component: e.component,
worksheet,
autoFilterEnabled: true
}).then(() => {
workbook.xlsx.writeBuffer().then((buffer: any) => {
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx')
})
})
e.cancel = true
const onExportingDetail = (e: any) => {
if (e.format === 'pdf') {
exportDetailToPDF(reportMeta.value, dataSub.value)
} else if (e.format === 'xlsx') {
exportDetailToXLSX(reportMeta.value, e)
} else {
}
}
@ -1021,6 +1022,8 @@ const filterData = async (params: any) => {
} else {
data.value = []
}
reportMeta.value = filters.value
})
.catch((err) => {
console.error(err)

View File

@ -0,0 +1,540 @@
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 { setHeaderStyle } from '@/report/utils/xlsx'
import { formatNumber, formatPercentage } from '@/utils/numbers'
const reportName = 'Laporan Check In Check Out (CICO)'
const fontSize = 5
const detailFontSize = 3
const formatData = (rawData: any) => {
const formattedData: any = []
const total: any = {
jumlah_wo_gangguan_individual: 0,
avg_durasi_wo_gangguan_individual: [],
avg_rpt_wo_gangguan_individual: [],
avg_rct_wo_gangguan_individual: [],
jumlah_wo_penugasan_khusus: 0,
avg_wo_penugasan_khusus: []
}
rawData.forEach((data: any) => {
formattedData.push([
data.user_regu,
data.personil_yantek,
data.jumlah_wo_gangguan_individual,
data.avg_durasi_wo_gangguan_individual,
data.avg_rpt_wo_gangguan_individual,
data.avg_rct_wo_gangguan_individual,
data.jumlah_wo_penugasan_khusus,
data.avg_wo_penugasan_khusus
])
total.jumlah_wo_gangguan_individual += data.jumlah_wo_gangguan_individual
total.avg_durasi_wo_gangguan_individual.push(data.avg_durasi_wo_gangguan_individual)
total.avg_rpt_wo_gangguan_individual.push(data.avg_rpt_wo_gangguan_individual)
total.avg_rct_wo_gangguan_individual.push(data.avg_rct_wo_gangguan_individual)
total.jumlah_wo_penugasan_khusus += data.jumlah_wo_penugasan_khusus
total.avg_wo_penugasan_khusus.push(data.avg_wo_penugasan_khusus)
})
formattedData.push([
{
content: 'TOTAL',
colSpan: 2
},
formatNumber(total.jumlah_wo_gangguan_individual),
formatNumber(
total.avg_durasi_wo_gangguan_individual.reduce((a: any, b: any) => a + b, 0) /
total.avg_durasi_wo_gangguan_individual.length
),
formatNumber(
total.avg_rpt_wo_gangguan_individual.reduce((a: any, b: any) => a + b, 0) /
total.avg_rpt_wo_gangguan_individual.length
),
formatNumber(
total.avg_rct_wo_gangguan_individual.reduce((a: any, b: any) => a + b, 0) /
total.avg_rct_wo_gangguan_individual.length
),
formatNumber(total.jumlah_wo_penugasan_khusus),
formatNumber(
total.avg_wo_penugasan_khusus.reduce((a: any, b: any) => a + b, 0) /
total.avg_wo_penugasan_khusus.length
)
])
return formattedData
}
const formatMetaData = (reportMeta: any) => {
const periode = reportMeta.periode ? reportMeta.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('id-ID', {
month: 'long'
})}-${dateFrom.getFullYear()}`
dateToFormat = `${dateTo.getDate()}-${dateTo.toLocaleString('id-ID', {
month: 'long'
})}-${dateTo.getFullYear()}`
dayTo = dateTo.toLocaleString('id-ID', { weekday: 'long' })
}
return { dateFromFormat, dateToFormat, dayTo }
}
const exportToPDF = (reportMeta: any, rawData: any, preview: boolean = false) => {
const data = formatData(rawData)
console.log(data)
const meta = formatMetaData(reportMeta)
const doc = new jsPDF({
orientation: 'landscape'
})
autoTable(doc, {
head: [
['PT. PLN(Persero)', '', ''],
[
{ 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()
],
[
'POSKO',
':',
reportMeta.posko ? reportMeta.posko.name.toUpperCase() : 'Semua Posko'.toUpperCase()
]
],
styles: {
fontSize,
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,
cellPadding: 0.1,
textColor: [0, 0, 0],
fontStyle: 'bold',
halign: 'center'
},
theme: 'plain',
startY: 23
})
autoTable(doc, {
head: [
[
'User Regu',
'Personil Yantek',
'Jumlah WO Gangguan Individual',
'Rata-rata Durasi WO Gangguan',
'Rata-rata RPT WO Gangguan',
'Rata-rata RCT WO Gangguan',
'Jumlah WO Penugasan Khusus',
'Rata-rata WO Penugasan Khusus'
]
],
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] === 'TOTAL') {
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: [
[`${meta.dayTo}, ${meta.dateToFormat}`],
[
{
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 meta = formatMetaData(reportMeta)
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()],
[`PERIODE TANGGAL : ${meta.dateFromFormat} SD TGL ${meta.dateToFormat}`]
],
styles: {
fontSize: detailFontSize,
cellPadding: 0.1,
textColor: [0, 0, 0],
fontStyle: 'bold',
halign: 'center'
},
theme: 'plain',
startY: 18,
margin: 5
})
autoTable(doc, {
head: [
[
'No',
'UID/UIW',
'UP3',
'Posko',
'Sumber Lapor',
'Create By',
'Dispacth By',
'User Regu',
'Nama Regu',
'Nama Petugas',
'Shift',
'Check In Petugas',
'No Laporan',
'Tgl Lapor',
'Tgl Penugasan Baru',
'Tgl Dalam Perjalanan',
'Tgl Pengerjaan',
'Tgl Nyala Sementara',
'Tgl Nyala',
'Tgl Selesai',
'Durasi Perjalanan',
'Durasi WO',
'Check Out Petugas',
'RPT',
'RCT',
'Rating',
'Jml Pelanggan Padam',
'Fasilitas',
'Sub Fasilitas',
'Peralatan',
'Dampak Kerusakan',
'Penyebab',
'Kelompok Penyebab',
'Cuaca',
'Keterangan Pelapor',
'Keterangan',
'Penyebab Padam',
'Tindakan',
'APKT Status',
'Referensi Marking',
'BLTH'
]
],
body: rawData.map((item: any, i: any) => [
{ content: i + 1, styles: { halign: 'right' } },
item.nama_uid,
item.nama_up3,
item.nama_posko,
item.media,
item.pembuat_laporan,
item.dispacth_by,
item.waktu_dispacth,
item.user_regu,
item.nama_regu,
item.personil_yantek,
item.shift,
item.check_in_petugas,
item.no_laporan,
item.waktu_lapor,
item.waktu_dispacth,
item.waktu_perjalanan,
item.waktu_response,
item.waktu_nyala_sementara,
item.waktu_nyala,
item.waktu_selesai,
item.durasi_waktu_response,
item.durasi_wo,
item.check_out_petugas,
item.durasi_menit_response,
item.durasi_menit_recovery,
item.rating,
item.jml_pelanggan_padam,
item.fasilitas,
item.sub_fasilitas,
item.peralatan,
item.dampak_kerusakan,
item.penyebab,
item.kelompok_penyebab,
item.cuaca,
item.keterangan_pelapor,
item.keterangan,
item.penyebab_padam,
item.tindakan,
item.status_akhir,
item.referensi_marking,
item.blth
]),
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',
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: [
[`${meta.dayTo}, ${meta.dateToFormat}`],
[
{
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 meta = formatMetaData(reportMeta)
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,
`POSKO : ${
reportMeta.posko ? reportMeta.posko.name.toUpperCase() : 'Semua Posko'.toUpperCase()
}`
)
setHeaderStyle(worksheet, 6, 1, `${reportName}`.toUpperCase(), true)
setHeaderStyle(
worksheet,
7,
1,
`PERIODE TANGGAL : ${meta.dateFromFormat} SD TGL ${meta.dateToFormat}`,
true
)
worksheet.mergeCells('A1:H1')
worksheet.mergeCells('A2:H2')
worksheet.mergeCells('A3:H3')
worksheet.mergeCells('A4:H4')
worksheet.mergeCells('A6:H6')
worksheet.mergeCells('A7:H7')
exportToExcel({
component: e.component,
worksheet,
autoFilterEnabled: true,
topLeftCell: { row: 9, 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 meta = formatMetaData(reportMeta)
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,
`PERIODE TANGGAL : ${meta.dateFromFormat} SD TGL ${meta.dateToFormat}`,
true
)
worksheet.mergeCells('A3:AP3')
worksheet.mergeCells('A4:AP4')
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
}
export { exportToPDF, exportToXLSX, exportDetailToPDF, exportDetailToXLSX }