From 88d14def41c9340652d6bf12cb4375486e0642ff Mon Sep 17 00:00:00 2001 From: Baghaztra Date: Fri, 19 Sep 2025 13:38:39 +0700 Subject: [PATCH] [Fix] page --- app/Services/LaporanService.php | 102 ++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 44 deletions(-) diff --git a/app/Services/LaporanService.php b/app/Services/LaporanService.php index 5d05a18..76b8923 100644 --- a/app/Services/LaporanService.php +++ b/app/Services/LaporanService.php @@ -54,9 +54,9 @@ class LaporanService } /** - * Get paginated sales detail aggregated by product. + * Get sales detail aggregated by product (NO PAGINATION - all data). * - * @param array $params Filter parameters (tanggal, sales_id, nampan_id, nama_pembeli, page, per_page) + * @param array $params Filter parameters (tanggal, sales_id, nampan_id, nama_pembeli) * @return array Report data structure * @throws \Exception */ @@ -65,16 +65,17 @@ class LaporanService $startDate = Carbon::parse($params['start_date'])->startOfDay(); $endDate = Carbon::parse($params['end_date'])->endOfDay(); - // TAMBAH: Validasi range max 30 hari (backup request) + // TAMBAH: Validasi range max 30 hari if ($startDate->diffInDays($endDate) > 30) { throw new \InvalidArgumentException('Interval tanggal maksimal 30 hari.'); } + // FIXED: Skip pagination params untuk data utama $page = $params['page'] ?? 1; $perPage = $params['per_page'] ?? self::DEFAULT_PER_PAGE; // --- Step 1: Totals --- - $totalsQuery = $this->buildBaseItemQueryForRange($startDate, $endDate); // FIXED: Call benar + $totalsQuery = $this->buildBaseItemQueryForRange($startDate, $endDate); $this->applyFilters($totalsQuery, $params); $totalsResult = $totalsQuery->select( @@ -89,7 +90,7 @@ class LaporanService 'total_pendapatan' => $this->helper->formatCurrency($totalsResult->total_pendapatan), ]; - // --- Step 2: Subquery --- + // --- Step 2: Subquery for all products --- $salesSubQuery = $this->buildBaseItemQueryForRange($startDate, $endDate) ->select( 'produks.id as id_produk', @@ -101,8 +102,8 @@ class LaporanService $this->applyFilters($salesSubQuery, $params); - // --- Step 3: Paginated products --- - $semuaProdukPaginated = Produk::select( + // --- Step 3: All products (NO PAGINATION) --- + $semuaProduk = Produk::select( 'produks.id', 'produks.nama as nama_produk', 'sales_data.jumlah_item_terjual', @@ -113,10 +114,10 @@ class LaporanService $join->on('produks.id', '=', 'sales_data.id_produk'); }) ->orderBy('produks.nama') - ->paginate($perPage, ['*'], 'page', $page); + ->get(); // FIXED: get() instead of paginate() // --- Step 4: Map & filter --- - $detailItem = $semuaProdukPaginated->map(function ($item) { + $detailItem = $semuaProduk->map(function ($item) { return [ 'nama_produk' => $item->nama_produk, 'jumlah_item_terjual' => $item->jumlah_item_terjual ? (int) $item->jumlah_item_terjual : 0, @@ -127,13 +128,8 @@ class LaporanService return $item['jumlah_item_terjual'] > 0; }); - $paginatedFiltered = new \Illuminate\Pagination\LengthAwarePaginator( - $detailItem->forPage($page, $perPage), - $detailItem->count(), // FIXED: Total dari filtered - $perPage, - $page, - ['path' => request()->url(), 'query' => request()->query()] - ); + // FIXED: Simple collection without pagination + $filteredCollection = $detailItem->values(); // --- Step 5: Response --- $filterInfo = $this->helper->buildProdukFilterInfo($startDate, $endDate, $params); @@ -141,8 +137,16 @@ class LaporanService return [ 'filter' => $filterInfo, 'rekap_interval' => $rekapInterval, - 'produk' => $paginatedFiltered->getCollection(), - 'pagination' => $this->helper->buildPaginationInfo($paginatedFiltered), // FIXED: Dari filtered + 'produk' => $filteredCollection, + 'pagination' => [ + 'current_page' => 1, + 'from' => 1, + 'last_page' => 1, + 'per_page' => $filteredCollection->count(), + 'to' => $filteredCollection->count(), + 'total' => $filteredCollection->count(), + 'has_more_pages' => false, + ], ]; } @@ -154,6 +158,13 @@ class LaporanService ->whereBetween('transaksis.created_at', [$startDate, $endDate]); } + /** + * Get sales detail aggregated by nampan (NO PAGINATION - all data). + * + * @param array $params Filter parameters (tanggal, sales_id, produk_id, nama_pembeli) + * @return array Report data structure + * @throws \Exception + */ public function getDetailPerNampan(array $params) { $startDate = Carbon::parse($params['start_date'])->startOfDay(); @@ -166,7 +177,7 @@ class LaporanService $page = $params['page'] ?? 1; $perPage = $params['per_page'] ?? self::DEFAULT_PER_PAGE; - $nampanTerjualQuery = $this->buildBaseItemQueryForRange($startDate, $endDate); // FIXED: Range + $nampanTerjualQuery = $this->buildBaseItemQueryForRange($startDate, $endDate); $this->applyNampanFilters($nampanTerjualQuery, $params); $nampanTerjual = $nampanTerjualQuery @@ -190,27 +201,31 @@ class LaporanService }); $totals = $this->helper->calculateTotals($nampanTerjualRaw); - $semuaNampanPaginated = $this->helper->getAllNampanWithPagination($page, $perPage); - $detailItem = $this->helper->mapNampanWithSalesData($semuaNampanPaginated, $nampanTerjual) + // FIXED: Get all nampan without pagination + $semuaNampan = $this->helper->getAllNampanWithPagination(1, PHP_INT_MAX); // Skip pagination + $detailItem = $this->helper->mapNampanWithSalesData($semuaNampan, $nampanTerjual) ->filter(function ($item) { - return $item['jumlah_item_terjual'] > 0; // FIXED: Int compare, no DEFAULT_DISPLAY check + return $item['jumlah_item_terjual'] > 0; }); - $paginatedFiltered = new \Illuminate\Pagination\LengthAwarePaginator( - $detailItem->forPage($page, $perPage), - $detailItem->count(), - $perPage, - $page, - ['path' => request()->url(), 'query' => request()->query()] - ); + // FIXED: Simple collection without pagination + $filteredCollection = $detailItem->values(); - $filterInfo = $this->helper->buildNampanFilterInfo($startDate, $endDate, $params); // FIXED: Range helper + $filterInfo = $this->helper->buildNampanFilterInfo($startDate, $endDate, $params); return [ 'filter' => $filterInfo, - 'rekap_interval' => $totals, // FIXED: Rename - 'nampan' => $paginatedFiltered->getCollection(), - 'pagination' => $this->helper->buildPaginationInfo($paginatedFiltered), + 'rekap_interval' => $totals, + 'nampan' => $filteredCollection, + 'pagination' => [ + 'current_page' => 1, + 'from' => 1, + 'last_page' => 1, + 'per_page' => $filteredCollection->count(), + 'to' => $filteredCollection->count(), + 'total' => $filteredCollection->count(), + 'has_more_pages' => false, + ], ]; } @@ -254,14 +269,14 @@ class LaporanService $startDate = Carbon::parse($params['start_date'])->format('Ymd'); $endDate = Carbon::parse($params['end_date'])->format('Ymd'); - $fileName = "laporan_per_produk_{$startDate}_to_{$endDate}.{$format}"; // FIXED: Range filename + $fileName = "laporan_per_produk_{$startDate}_to_{$endDate}.{$format}"; if ($format === 'pdf') { $pdf = PDF::loadView('exports.perproduk_pdf', [ 'data' => $data, 'title' => 'Laporan Detail Per Produk' ]); - $pdf->setPaper('a4', 'portrait'); // FIXED: Typo 'potrait' + $pdf->setPaper('a4', 'portrait'); return $pdf->download($fileName); } @@ -278,7 +293,7 @@ class LaporanService $startDate = Carbon::parse($params['start_date'])->format('Ymd'); $endDate = Carbon::parse($params['end_date'])->format('Ymd'); - $fileName = "laporan_per_nampan_{$startDate}_to_{$endDate}.{$format}"; // FIXED: Range + $fileName = "laporan_per_nampan_{$startDate}_to_{$endDate}.{$format}"; if ($format === 'pdf') { $pdf = PDF::loadView('exports.pernampan_pdf', [ @@ -334,14 +349,14 @@ class LaporanService 'pendapatan' => $this->helper->formatCurrency($dataTerjual->pendapatan), ]; } - return null; // Akan difilter - })->filter(); // FIXED: Filter null/kosong + return null; + })->filter(); $filterInfo = $this->helper->buildProdukFilterInfo($startDate, $endDate, $params); return [ 'filter' => $filterInfo, - 'rekap_interval' => $totals, // FIXED: Rename + 'rekap_interval' => $totals, 'produk' => $detailItem->values(), ]; } @@ -376,7 +391,7 @@ class LaporanService $totals = $this->helper->calculateTotals($nampanTerjualRaw); $semuaPosisi = DB::table('item_transaksis') - ->whereBetween('created_at', [$startDate, $endDate]) // FIXED: Filter posisi di range + ->whereBetween('created_at', [$startDate, $endDate]) ->select('posisi_asal') ->distinct() ->pluck('posisi_asal') @@ -393,10 +408,10 @@ class LaporanService 'pendapatan' => $this->helper->formatCurrency($dataTerjual->pendapatan), ]; } - return null; // Filter out + return null; })->filter(); - $filterInfo = $this->helper->buildNampanFilterInfo($startDate, $endDate, $params); // FIXED: Range + $filterInfo = $this->helper->buildNampanFilterInfo($startDate, $endDate, $params); return [ 'filter' => $filterInfo, @@ -405,7 +420,6 @@ class LaporanService ]; } - private function getAllSalesNames(): Collection { return Cache::remember('all_sales_names', self::CACHE_TTL, function () { @@ -434,7 +448,7 @@ class LaporanService $nampanId = (int) $params['nampan_id']; if ($nampanId === -1) { $query->where('item_transaksis.posisi_asal', 'Brankas'); - } elseif ($nampanId > 0) { // FIXED: >0 join, 0 skip (all) + } elseif ($nampanId > 0) { $query->join('nampans', function ($join) use ($nampanId) { $join->on('item_transaksis.posisi_asal', '=', 'nampans.nama') ->where('nampans.id', $nampanId);