From c89c20fbdf54d252a12f6b57d9754902a6ee4146 Mon Sep 17 00:00:00 2001 From: Ahmad Affandi Date: Thu, 25 Sep 2025 08:57:36 +0700 Subject: [PATCH 1/8] fitur : ekspor laporan --- app/Exports/ReportExport.php | 69 ++++++ app/Filament/Pages/ExportReport.php | 199 ++++++++++++++++++ app/Filament/Pages/Report.php | 5 + lang/id.json | 6 +- resources/views/export/report.blade.php | 52 +++++ .../filament/pages/export-report.blade.php | 23 ++ 6 files changed, 353 insertions(+), 1 deletion(-) create mode 100644 app/Exports/ReportExport.php create mode 100644 app/Filament/Pages/ExportReport.php create mode 100644 resources/views/export/report.blade.php create mode 100644 resources/views/filament/pages/export-report.blade.php diff --git a/app/Exports/ReportExport.php b/app/Exports/ReportExport.php new file mode 100644 index 00000000..eceb0dfe --- /dev/null +++ b/app/Exports/ReportExport.php @@ -0,0 +1,69 @@ +state = $state; + $this->ticketTotal = $ticketTotal; + $this->ticketByApplication = $ticketByApplication; + $this->ticketByService = $ticketByService; + $this->ticketDuplicate = $ticketDuplicate; + $this->completionReport = $completionReport; + } + + public function view(): View + { + return view('export.report', [ + 'state' => $this->state, + 'ticketTotal' => $this->ticketTotal, + 'ticketByApplication' => $this->ticketByApplication, + 'ticketByService' => $this->ticketByService, + 'ticketDuplicate' => $this->ticketDuplicate, + 'completionReport' => $this->completionReport, + ]); + } + + public function styles(Worksheet $sheet) + { + // Auto wrap text agar height cell mengikuti konten + foreach (range('A', $sheet->getHighestColumn()) as $col) { + $sheet->getStyle($col)->getAlignment()->setWrapText(true); + $sheet->getStyle($col)->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP); + } + + $lastRow = $sheet->getHighestRow(); + + // Atur tinggi row terakhir secara manual + $sheet->getRowDimension($lastRow)->setRowHeight(500); + + return []; + } + + public function columnWidths(): array + { + return [ + 'A' => 30, + 'B' => 30, + 'C' => 30, + 'D' => 30, + 'E' => 30, + ]; + } +} diff --git a/app/Filament/Pages/ExportReport.php b/app/Filament/Pages/ExportReport.php new file mode 100644 index 00000000..6a4e00e9 --- /dev/null +++ b/app/Filament/Pages/ExportReport.php @@ -0,0 +1,199 @@ +month; + $year = now()->year; + + // cari data lama di tabel completion_report + $data = DB::table('completion_report') + ->where('month', $month) + ->where('year', $year) + ->first(); + + $this->form->fill([ + 'month' => $month, + 'year' => $year, + 'completion_report' => $data ? $data->completion_report : '', + ]); + + $this->saved = $data ? true : false; + } + + protected function getFormSchema(): array + { + return [ + Grid::make(4)->schema([ + Select::make('month') + ->label(__('Month')) + ->options($this->getMonths()) + ->reactive(), + + Select::make('year') + ->label(__('Year')) + ->options($this->getYears()) + ->reactive(), + ]), + + RichEditor::make('completion_report') + ->label(__('Completion')) + ->reactive() + ->afterStateUpdated(fn ($state) => $this->completion_report = $state), + ]; + } + + public function updatedMonth($value, $key): void + { + $state = $this->form->getState(); + $data = DB::table('completion_report') + ->where('month', $state['month']) + ->where('year', $state['year']) + ->first(); + // dd($data); + $this->form->fill([ + 'month' => $state['month'], + 'year' => $state['year'], + 'completion_report' => $data->completion_report ?? '', + ]); + + $this->saved = $data ? true : false; + } + + public function updatedYear(): void + { + $this->updatedMonth(); // biar logika sama + } + + protected function getMonths(): array + { + return collect(range(1, 12)) + ->mapWithKeys(fn ($m) => [$m => Carbon::create()->month($m)->translatedFormat('F')]) + ->toArray(); + } + + protected function getYears(): array + { + $now = now()->year; + return collect(range($now - 2, $now)) + ->mapWithKeys(fn ($y) => [$y => $y]) + ->toArray(); + } + + public function save(): void + { + $state = $this->form->getState(); + // dd($state); + if (empty($state['month']) || empty($state['year']) || empty($state['completion_report'])) { + Notification::make() + ->title('Isi semua field terlebih dahulu') + ->danger() + ->send(); + return; + } + + DB::table('completion_report')->updateOrInsert( + ['month' => $state['month'], 'year' => $state['year']], + ['completion_report' => $state['completion_report']] + ); + + $this->saved = true; + + Notification::make() + ->title('Data berhasil disimpan') + ->success() + ->send(); + } + + public function export() + { + if (! $this->saved) { + Notification::make() + ->title('Isi & simpan data dulu sebelum export') + ->danger() + ->send(); + return; + } + $state = $this->form->getState(); + + $ticketTotal = DB::table('tickets') + ->whereYear('created_at', $state['year']) + ->whereMonth('created_at', $state['month']) + ->get(); + + $ticketByApplication = DB::table('tickets') + ->select('master_applications.name', DB::raw('COUNT(*) as total')) + ->join('master_applications', 'tickets.master_application_id', '=', 'master_applications.id') + ->whereYear('tickets.created_at', $state['year']) + ->whereMonth('tickets.created_at', $state['month']) + ->groupBy('master_applications.name') + ->get(); + + $ticketByService = DB::table('tickets') + ->select('projects.name', DB::raw('COUNT(*) as total')) + ->join('projects', 'tickets.project_id', '=', 'projects.id') + ->whereYear('tickets.created_at', $state['year']) + ->whereMonth('tickets.created_at', $state['month']) + ->groupBy('projects.name') + ->get(); + + $ticketDuplicate = DB::table('ticket_relations') + ->join('tickets', 'ticket_relations.relation_id', '=', 'tickets.id') + ->selectRaw(" + TRIM( + SUBSTRING_INDEX(tickets.name, '-', 1) + ) as clean_name, + COUNT(*) as total + ") + ->whereYear('ticket_relations.created_at', $state['year']) + ->whereMonth('ticket_relations.created_at', $state['month']) + ->groupBy('tickets.name') + ->orderByDesc('total') + ->get(); + + $completionReport = DB::table('completion_report') + ->where('month', $state['month']) + ->where('year', $state['year']) + ->value('completion_report'); + + // dd($ticketDuplicate); + return Excel::download( + new ReportExport($state, $ticketTotal, $ticketByApplication, $ticketByService, $ticketDuplicate, $completionReport), + 'laporan-' . $state['year'] . '-' . str_pad($state['month'], 2, '0', STR_PAD_LEFT) . '.xlsx' + ); + } +} diff --git a/app/Filament/Pages/Report.php b/app/Filament/Pages/Report.php index 5ffcbe6f..d4c2ca62 100644 --- a/app/Filament/Pages/Report.php +++ b/app/Filament/Pages/Report.php @@ -15,6 +15,11 @@ public static function getNavigationLabel(): string return __('Report'); } + public function getTitle(): string + { + return __('Report'); + } + public $activeTab = 1; } diff --git a/lang/id.json b/lang/id.json index 13496a04..9e7382ca 100644 --- a/lang/id.json +++ b/lang/id.json @@ -291,5 +291,9 @@ "Month": "Bulan", "Year": "Tahun", "Data not found": "Data tidak ditemukan", - "Tokens": "Token" + "Tokens": "Token", + "Completion": "Penyelesaian", + "Export to Excel": "Ekspor ke Excel", + "Export Report": "Ekspor Laporan", + "This is an action to export data based on the data on the report page, and is equipped with problem solving for the report and then exported to Excel.": "Ini merupakan aksi untuk mengekspor data berdasarkan data yang ada di page laporan, dan dilengkapi penyelesaian masalah untuk laporan kemudian di export ke Excel." } diff --git a/resources/views/export/report.blade.php b/resources/views/export/report.blade.php new file mode 100644 index 00000000..c07486a1 --- /dev/null +++ b/resources/views/export/report.blade.php @@ -0,0 +1,52 @@ + + {{-- Header --}} + + + + + {{-- Summary Tiket --}} + + + + + + + + + + + + {{-- aplikasi --}} + + + {{-- server --}} + + + {{-- masalah berulang --}} + + + + {{-- Aksi untuk mengurangi tiket --}} + + + + +
+ Rilis {{ $state['year'] % 100 }}{{ str_pad($state['month'], 2, '0', STR_PAD_LEFT) }} + ({{ \Carbon\Carbon::createFromDate($state['year'], $state['month'])->translatedFormat('F Y') }}) +
Jumlah Tiket DibuatJumlah Tiket TerselesaikanAplikasi Beban UtamaServer Beban UtamaMasalah berulang / menyita waktu
{{ $ticketTotal->count() }}{{ $ticketTotal->count() }} + @foreach ($ticketByApplication as $app) + {{ $app->name }} ({{ $app->total }})

+ @endforeach +
+ @foreach ($ticketByService as $srv) + {{ $srv->name }} ({{ $srv->total }})

+ @endforeach +
+ @foreach ($ticketDuplicate as $dup) + {{ $dup->clean_name }} ({{ $dup->total }})

+ @endforeach +
Aksi untuk mengurangi tiket
+ {!! $completionReport !!} +
+ diff --git a/resources/views/filament/pages/export-report.blade.php b/resources/views/filament/pages/export-report.blade.php new file mode 100644 index 00000000..19701724 --- /dev/null +++ b/resources/views/filament/pages/export-report.blade.php @@ -0,0 +1,23 @@ + +
+ {{__('This is an action to export data based on the data on the report page, and is equipped with problem solving for the report and then exported to Excel.')}} +
+ {{ $this->form }} + +
+ + Simpan + + +
+ + {{__('Export to Excel')}} + +
+
+
From 71e16d13690c23cb1631a11e45b4cb4c83adc928 Mon Sep 17 00:00:00 2001 From: Afila Date: Tue, 30 Sep 2025 08:22:14 +0700 Subject: [PATCH 2/8] Update app/Filament/Pages/ExportReport.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/Filament/Pages/ExportReport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Filament/Pages/ExportReport.php b/app/Filament/Pages/ExportReport.php index 6a4e00e9..934fcc65 100644 --- a/app/Filament/Pages/ExportReport.php +++ b/app/Filament/Pages/ExportReport.php @@ -88,7 +88,7 @@ public function updatedMonth($value, $key): void $this->form->fill([ 'month' => $state['month'], 'year' => $state['year'], - 'completion_report' => $data->completion_report ?? '', + 'completion_report' => $data ? $data->completion_report : '', ]); $this->saved = $data ? true : false; From e35483c5222c56362a9c45193e324f390c24a22f Mon Sep 17 00:00:00 2001 From: Afila Date: Tue, 30 Sep 2025 08:22:57 +0700 Subject: [PATCH 3/8] Update app/Filament/Pages/ExportReport.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/Filament/Pages/ExportReport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Filament/Pages/ExportReport.php b/app/Filament/Pages/ExportReport.php index 934fcc65..c520350f 100644 --- a/app/Filament/Pages/ExportReport.php +++ b/app/Filament/Pages/ExportReport.php @@ -120,7 +120,7 @@ public function save(): void // dd($state); if (empty($state['month']) || empty($state['year']) || empty($state['completion_report'])) { Notification::make() - ->title('Isi semua field terlebih dahulu') + ->title(__('Isi semua field terlebih dahulu')) ->danger() ->send(); return; From f7ef30561f964a6f5bc839dfbfe8d31815f99522 Mon Sep 17 00:00:00 2001 From: Afila Date: Tue, 30 Sep 2025 08:23:05 +0700 Subject: [PATCH 4/8] Update app/Filament/Pages/ExportReport.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/Filament/Pages/ExportReport.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Filament/Pages/ExportReport.php b/app/Filament/Pages/ExportReport.php index c520350f..8c95e09c 100644 --- a/app/Filament/Pages/ExportReport.php +++ b/app/Filament/Pages/ExportReport.php @@ -96,7 +96,8 @@ public function updatedMonth($value, $key): void public function updatedYear(): void { - $this->updatedMonth(); // biar logika sama + $state = $this->form->getState(); + $this->updatedMonth($state['month'] ?? null, 'month'); // biar logika sama } protected function getMonths(): array From 6bdac429d32938bbd8be3150d4742d796eb3896c Mon Sep 17 00:00:00 2001 From: Afila Date: Tue, 30 Sep 2025 08:23:15 +0700 Subject: [PATCH 5/8] Update app/Filament/Pages/ExportReport.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/Filament/Pages/ExportReport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Filament/Pages/ExportReport.php b/app/Filament/Pages/ExportReport.php index 8c95e09c..a02c499a 100644 --- a/app/Filament/Pages/ExportReport.php +++ b/app/Filament/Pages/ExportReport.php @@ -135,7 +135,7 @@ public function save(): void $this->saved = true; Notification::make() - ->title('Data berhasil disimpan') + ->title(__('Data berhasil disimpan')) ->success() ->send(); } From 4ed39a6ee06be42c4af47fa165473813d676c362 Mon Sep 17 00:00:00 2001 From: Afila Date: Tue, 30 Sep 2025 08:23:22 +0700 Subject: [PATCH 6/8] Update app/Filament/Pages/ExportReport.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/Filament/Pages/ExportReport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Filament/Pages/ExportReport.php b/app/Filament/Pages/ExportReport.php index a02c499a..bc40bc99 100644 --- a/app/Filament/Pages/ExportReport.php +++ b/app/Filament/Pages/ExportReport.php @@ -144,7 +144,7 @@ public function export() { if (! $this->saved) { Notification::make() - ->title('Isi & simpan data dulu sebelum export') + ->title(__('Isi & simpan data dulu sebelum export')) ->danger() ->send(); return; From 505a329676ef5f8b714615e0e28ad4719139f2cb Mon Sep 17 00:00:00 2001 From: Afila Date: Tue, 30 Sep 2025 08:23:33 +0700 Subject: [PATCH 7/8] Update resources/views/filament/pages/export-report.blade.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- resources/views/filament/pages/export-report.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/filament/pages/export-report.blade.php b/resources/views/filament/pages/export-report.blade.php index 19701724..8bede728 100644 --- a/resources/views/filament/pages/export-report.blade.php +++ b/resources/views/filament/pages/export-report.blade.php @@ -6,7 +6,7 @@
- Simpan + {{ __('Save') }}
From 901bfd47b37875b56ab5cbac608f06493d725387 Mon Sep 17 00:00:00 2001 From: Afila Date: Tue, 30 Sep 2025 08:25:08 +0700 Subject: [PATCH 8/8] Update catatan_rilis.md --- catatan_rilis.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/catatan_rilis.md b/catatan_rilis.md index 6158aa51..c0ec010a 100644 --- a/catatan_rilis.md +++ b/catatan_rilis.md @@ -1,9 +1,10 @@ Di rilis v2507.0.0 berisi penambahan fitur dan perbaikan lain sesuai dengan pelayanan ke pelanggan. #### Penambahan Fitur +1. [#41](https://github.com/OpenSID/help-desk/issues/38) fitur : ekspor laporan ke dalam excel #### Perbaikan BUG -8. [#31](https://github.com/OpenSID/help-desk/issues/31) Perbaikan fitur pencarian tiket +1. [#31](https://github.com/OpenSID/help-desk/issues/31) Perbaikan fitur pencarian tiket #### Panduan