diff --git a/app/Exports/LaporanKeseluruhan/AgingTebusAllExportExcel.php b/app/Exports/LaporanKeseluruhan/AgingTebusAllExportExcel.php new file mode 100644 index 0000000..fd83735 --- /dev/null +++ b/app/Exports/LaporanKeseluruhan/AgingTebusAllExportExcel.php @@ -0,0 +1,222 @@ +aging = $aging; + $this->startDate = $startDate; + $this->endDate = $endDate; + } + + public function array(): array + { + $rows = []; + $totals = []; + + foreach ($this->aging as $branch) { + $row = [$branch['cawangan']]; + $i = 0; + + foreach ($branch['summary_by_tempoh'] as $summary) { + $row[] = $summary['count']; + $row[] = $summary['sum_bayaran_keuntungan_rebet']; + + // Totals per column + $totals[$i]['count'] = ($totals[$i]['count'] ?? 0) + $summary['count']; + $totals[$i]['sum_bayaran_keuntungan_rebet'] = ($totals[$i]['sum_bayaran_keuntungan_rebet'] ?? 0) + $summary['sum_bayaran_keuntungan_rebet']; + $i++; + } + + // Total per row (cawangan) + $jumlahBil = collect($branch['summary_by_tempoh'])->sum('count'); + $jumlahRM = collect($branch['summary_by_tempoh'])->sum('sum_bayaran_keuntungan_rebet'); + $row[] = $jumlahBil; + $row[] = $jumlahRM; + + // Add to column totals + $totals['jumlah']['count'] = ($totals['jumlah']['count'] ?? 0) + $jumlahBil; + $totals['jumlah']['sum_bayaran_keuntungan_rebet'] = ($totals['jumlah']['sum_bayaran_keuntungan_rebet'] ?? 0) + $jumlahRM; + + $rows[] = $row; + } + + // Add final total row + $totalRow = ['Jumlah']; + foreach ($totals as $key => $val) { + $totalRow[] = $val['count']; + $totalRow[] = $val['sum_bayaran_keuntungan_rebet']; + } + + $rows[] = $totalRow; + + return $rows; + } + + + /** + * Multi-row headings (2 rows) + */ + public function headings(): array + { + $row1 = ['Cawangan']; + $row2 = ['']; + + if (!empty($this->aging[0]['summary_by_tempoh'])) { + foreach ($this->aging[0]['summary_by_tempoh'] as $summary) { + $row1[] = $summary['label']; + $row1[] = ''; // empty to allow merged cell + $row2[] = 'Bil'; + $row2[] = 'RM'; + } + } + + $row1[] = 'Jumlah'; + $row1[] = ''; // for merged "Jumlah" cell + $row2[] = 'Bil'; + $row2[] = 'RM'; + + return [$row1, $row2]; + } + + public function columnFormats(): array +{ + $formats = []; + $colIndex = 2; // Start at column B (Cawangan is A) + + $tempohCount = count($this->aging[0]['summary_by_tempoh'] ?? []); + for ($i = 0; $i < $tempohCount; $i++) { + // Bil column + $bilCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colIndex++); + $formats[$bilCol] = NumberFormat::FORMAT_NUMBER; // ✅ No decimal + + // RM column + $rmCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colIndex++); + $formats[$rmCol] = NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1; // RM with comma and decimals + } + + // Jumlah Bil + $jumlahBilCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colIndex++); + $formats[$jumlahBilCol] = NumberFormat::FORMAT_NUMBER; // ✅ No decimal + + // Jumlah RM + $jumlahRMCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colIndex++); + $formats[$jumlahRMCol] = NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1; + + return $formats; +} + + + public function bindValue(Cell $cell, $value) + { + if (is_numeric($value)) { + $cell->setValueExplicit($value, DataType::TYPE_NUMERIC); + return true; + } + + return parent::bindValue($cell, $value); + } + + /** + * Merge heading cells using AfterSheet event + */ + public function registerEvents(): array + { + return [ + AfterSheet::class => function(AfterSheet $event) { + + $sheet = $event->sheet->getDelegate(); + + // Tajuk laporan + $sheet->setCellValue('A1', 'LAPORAN AGING PENEBUSAN'); + + // Tarikh laporan + $sheet->setCellValue( + 'A2', + 'Tarikh : ' . + \Carbon\Carbon::parse($this->startDate)->format('d/m/Y') . + ' hingga ' . + \Carbon\Carbon::parse($this->endDate)->format('d/m/Y') + ); + + // Merge tajuk + $lastColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex( + (count($this->aging[0]['summary_by_tempoh'] ?? []) * 2) + 3 + ); + + $sheet->mergeCells("A1:{$lastColumn}1"); + + // Style tajuk + $sheet->getStyle("A1:{$lastColumn}1")->applyFromArray([ + 'font' => [ + 'bold' => true, + 'size' => 14, + ], + 'alignment' => [ + 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, + ], + ]); + + // Merge header tempoh + $colIndex = 2; // Start from column B + $tempohCount = count($this->aging[0]['summary_by_tempoh'] ?? []); + + $headingRow = 3; + + for ($i = 0; $i < $tempohCount; $i++) { + + $startCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colIndex); + + $endCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colIndex + 1); + + $sheet->mergeCells("{$startCol}{$headingRow}:{$endCol}{$headingRow}"); + + $colIndex += 2; + } + + // Merge Jumlah + $startCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colIndex); + + $endCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($colIndex + 1); + + $sheet->mergeCells("{$startCol}{$headingRow}:{$endCol}{$headingRow}"); + }, + ]; + } + + // Mulakan sel untuk data bermula dari A4 (Baris 3 adalah header) + public function startCell(): string + { + return 'A3'; // Data bermula dari baris 4 + } +} diff --git a/app/Http/Controllers/Reports/AgingController.php b/app/Http/Controllers/Reports/AgingController.php index b74b5cc..a8f5905 100644 --- a/app/Http/Controllers/Reports/AgingController.php +++ b/app/Http/Controllers/Reports/AgingController.php @@ -9,7 +9,7 @@ use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Http; use Maatwebsite\Excel\Facades\Excel; use Illuminate\Support\Facades\Auth; -use App\Exports\LaporanKeseluruhan\AgingAllExportExcel; +use App\Exports\LaporanKeseluruhan\AgingTebusAllExportExcel; class AgingController extends Controller { @@ -81,4 +81,77 @@ class AgingController extends Controller } return view('reports.aging.index', compact('aging', 'endDate')); } + + public function agingtebus(Request $request) + { + $current = new Carbon(); + $request->hostname = config('api.url'); + // dd($request->hostname ); + $kod_cawangan = $request->kod_cawangan; + $action = $request->input('action', 'search'); + // dd($action); + + $getReportDate = function ($date_string) use ($current) { + if ($date_string == null) { + return $current->toDateString(); + } + + return $date_string; + }; + + $request->hostname = config('api.url'); + + $startDate = $getReportDate($request->startDate); + + $endDate = $getReportDate($request->endDate); + + $aging = Http::get($request->hostname . '/api/reports/agingtebus', [ + 'startDate' => $startDate, + 'endDate' => $endDate, + ])->json(); + + $aging = $aging ?? []; + + if ($action === 'excel') { + $file_title = sprintf("LaporanAging(%s).xlsx", $kod_cawangan, $startDate, $endDate); + return Excel::download(new AgingTebusAllExportExcel($aging,$startDate,$endDate), $file_title); + } + + return view('reports.agingtebus.index', compact('aging', 'startDate', 'endDate')); + } + public function showagingtebus(Request $request) + { + $current = Carbon::now(); + $action = $request->input('action', 'search'); + + $getReportDate = function ($date_string) use ($current) { + return $date_string ? $date_string : $current->toDateString(); + }; + + $hostname = config('api.url'); + + $startDate = $getReportDate($request->startDate); + $endDate = $getReportDate($request->endDate); + + $response = Http::get("$hostname/api/reports/agingtebus", [ + 'startDate' => $startDate, + 'endDate' => $endDate, + ]); + + $aging = $response->json() ?? []; // Ensure it's an array + + // Debugging: Check the response before using it + if (empty($aging)) { + return back()->with('error', 'Failed to fetch data from API.'); + } + + if ($action === 'excel') { + // Ensure $kod_cawangan is defined (Modify as per your data structure) + $kod_cawangan = $request->input('kod_cawangan', 'DEFAULT'); + + $file_title = sprintf("LaporanAgingTebus(%s).xlsx", $kod_cawangan, $startDate, $endDate); + return Excel::download(new AgingTebusAllExportExcel($aging, $startDate, $endDate), $file_title); + } + return view('reports.agingtebus.index', compact('aging', 'startDate', 'endDate')); + } } diff --git a/resources/views/indexOverallReport.blade.php b/resources/views/indexOverallReport.blade.php index 19abb71..979940d 100644 --- a/resources/views/indexOverallReport.blade.php +++ b/resources/views/indexOverallReport.blade.php @@ -128,6 +128,12 @@

Data Pelanggan By Cawangan

+
+ +

Laporan Aging Penebusan

+
+
diff --git a/resources/views/reports/agingtebus/index.blade.php b/resources/views/reports/agingtebus/index.blade.php new file mode 100644 index 0000000..af13fb6 --- /dev/null +++ b/resources/views/reports/agingtebus/index.blade.php @@ -0,0 +1,276 @@ +@extends('layouts.app') + +@section('content') + +
+
+ +
+ + + + +
+
+
+
+ + + + Laporan Aging Penebusan +
+ +
+ +
+
+ + + +
+ + {{-- Dari --}} +
+ + + +
+ + {{-- Hingga --}} +
+ + + +
+ + + + {{-- Button Group --}} +
+ + {{-- Button Group --}} +
+ + {{-- Search --}} + + + {{-- Excel --}} + + +
+ +
+ +
+ +
+ +
+
+
+
+
+ +
+
+ + +
+
+ + +
+
+ +
+ + @if(empty($aging)) +
+ Tiada data dijumpai untuk tarikh {{ $endDate }}. +
+ @else + + +
+ + + + + + + @foreach ($aging[0]['summary_by_tempoh'] as $summary) + + @endforeach + + + + + + @foreach ($aging[0]['summary_by_tempoh'] as $summary) + + + @endforeach + + + + + + + @php + $counter = 1; + + $totalGrandCountByTempoh = array_fill( + 0, + count($aging[0]['summary_by_tempoh']), + 0 + ); + + $totalGrandKeuntunganByTempoh = array_fill( + 0, + count($aging[0]['summary_by_tempoh']), + 0 + ); + @endphp + + @foreach ($aging as $branch) + + @php + $totalCount = 0; + $totalKeuntungan = 0; + @endphp + + + + + + + @foreach ($branch['summary_by_tempoh'] as $index => $summary) + + {{-- Bil --}} + + + {{-- RM --}} + + + @php + // Total per cawangan + $totalCount += $summary['count']; + + $totalKeuntungan += + $summary['sum_bayaran_keuntungan_rebet']; + + // Grand total + $totalGrandCountByTempoh[$index] += + $summary['count']; + + $totalGrandKeuntunganByTempoh[$index] += + $summary['sum_bayaran_keuntungan_rebet']; + @endphp + + @endforeach + + {{-- Keseluruhan --}} + + + + + + @endforeach + + + + + + + + @foreach ($totalGrandCountByTempoh as $index => $grandCount) + + {{-- Grand total bil --}} + + + {{-- Grand total RM --}} + + + @endforeach + + {{-- Total keseluruhan --}} + + + + + + +
Bil. Cawangan{{ $summary['label'] }} Keseluruhan
Bil RM BilRM
+ {{ $counter++ }} + + {{ $branch['cawangan'] }} + + {{ $summary['count'] }} + + {{ number_format($summary['sum_bayaran_keuntungan_rebet'], 2) }} + + {{ $totalCount }} + + {{ number_format($totalKeuntungan, 2) }} +
+ Total + + {{ $grandCount }} + + {{ number_format($totalGrandKeuntunganByTempoh[$index], 2) }} + + {{ array_sum($totalGrandCountByTempoh) }} + + {{ number_format(array_sum($totalGrandKeuntunganByTempoh), 2) }} +
+
+ + @endif +
+
+
+ @include('layouts.footer') + +
+@endsection + + + diff --git a/routes/reports.php b/routes/reports.php index 2276692..eec89f5 100644 --- a/routes/reports.php +++ b/routes/reports.php @@ -60,4 +60,6 @@ Route::middleware(['roleChecker:admin,akaun,operasi,kpo,callcenter, null'])->gro Route::get('data-pelanggan-bycaw-index', [AnalisaController::class, 'dataPelangganBycaw'])->name('reports.dataPelangganBycaw.index'); Route::get('data-pelanggan-bycaw-show', [AnalisaController::class, 'dataPelangganBycawShow'])->name('reports.dataPelangganBycaw.show'); + Route::get('agingtebus/view', [AgingController::class, 'agingtebus'])->name('reports.agingtebus.index'); + Route::get('laporan-agingtebus/view', [AgingController::class, 'showagingtebus'])->name('reports.agingtebus.show'); });