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..bc40bc99 --- /dev/null +++ b/app/Filament/Pages/ExportReport.php @@ -0,0 +1,200 @@ +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 ? $data->completion_report : '', + ]); + + $this->saved = $data ? true : false; + } + + public function updatedYear(): void + { + $state = $this->form->getState(); + $this->updatedMonth($state['month'] ?? null, 'month'); // 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/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 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 @@ +
| + 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 Dibuat | +Jumlah Tiket Terselesaikan | +Aplikasi Beban Utama | +Server Beban Utama | +Masalah berulang / menyita waktu | +
|---|---|---|---|---|
| {{ $ticketTotal->count() }} | +{{ $ticketTotal->count() }} | + + {{-- aplikasi --}} +
+ @foreach ($ticketByApplication as $app)
+ {{ $app->name }} ({{ $app->total }}) + @endforeach + |
+
+ {{-- server --}}
+
+ @foreach ($ticketByService as $srv)
+ {{ $srv->name }} ({{ $srv->total }}) + @endforeach + |
+
+ {{-- masalah berulang --}}
+
+ @foreach ($ticketDuplicate as $dup)
+ {{ $dup->clean_name }} ({{ $dup->total }}) + @endforeach + |
+
| Aksi untuk mengurangi tiket | ||||
| + {!! $completionReport !!} + | +||||