transaksiRepo = $transaksiRepo; $this->helper = $helper; } public function getRingkasan(string $filter, int $page) { $cacheKey = "laporan_ringkasan_{$filter}_page_{$page}"; return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($filter, $page) { $allSalesNames = $this->getAllSalesNames(); if ($filter === 'hari') { return $this->processLaporanHarian($allSalesNames, $page, true); } return $this->processLaporanBulanan($allSalesNames, $page, true); }); } public function getDetailPerProduk(array $params) { $tanggal = Carbon::parse($params['tanggal']); $page = $params['page'] ?? 1; $perPage = $params['per_page'] ?? self::DEFAULT_PER_PAGE; // Validasi nampan_id jika ada if (isset($params['nampan_id']) && $params['nampan_id'] != 0) { if (!Nampan::where('id', $params['nampan_id'])->exists()) { throw new \Exception('Nampan tidak ditemukan'); } } $produkTerjualQuery = $this->buildBaseItemQuery($tanggal); $this->applyFilters($produkTerjualQuery, $params); $produkTerjual = $produkTerjualQuery ->select( 'produks.id as id_produk', 'produks.nama as nama_produk', DB::raw('COUNT(item_transaksis.id) as jumlah_item_terjual'), DB::raw('COALESCE(SUM(produks.berat), 0) as berat_terjual'), DB::raw('COALESCE(SUM(item_transaksis.harga_deal), 0) as pendapatan') ) ->groupBy('produks.id', 'produks.nama') ->get() ->keyBy('id_produk'); $totals = $this->helper->calculateTotals($produkTerjual); $semuaProdukPaginated = Produk::select('id', 'nama') ->orderBy('nama') ->paginate($perPage, ['*'], 'page', $page); $detailItem = $this->helper->mapProductsWithSalesData($semuaProdukPaginated, $produkTerjual); $filterInfo = $this->helper->buildProdukFilterInfo($tanggal, $params); return [ 'filter' => $filterInfo, 'rekap_harian' => $totals, 'produk' => $detailItem->values(), 'pagination' => $this->helper->buildPaginationInfo($semuaProdukPaginated), ]; } public function getDetailPerNampan(array $params) { $tanggal = Carbon::parse($params['tanggal']); $page = $params['page'] ?? 1; $perPage = $params['per_page'] ?? self::DEFAULT_PER_PAGE; $nampanTerjualQuery = $this->buildBaseItemQuery($tanggal); $this->applyNampanFilters($nampanTerjualQuery, $params); $nampanTerjual = $nampanTerjualQuery ->leftJoin('nampans', 'items.id_nampan', '=', 'nampans.id') ->select( DB::raw('COALESCE(items.id_nampan, 0) as id_nampan'), DB::raw('COALESCE(nampans.nama, "Brankas") as nama_nampan'), DB::raw('COUNT(item_transaksis.id) as jumlah_item_terjual'), DB::raw('COALESCE(SUM(produks.berat), 0) as berat_terjual'), DB::raw('COALESCE(SUM(item_transaksis.harga_deal), 0) as pendapatan') ) ->groupBy('id_nampan', 'nama_nampan') ->get() ->keyBy('id_nampan'); $totals = $this->helper->calculateTotals($nampanTerjual); $semuaNampanPaginated = $this->helper->getAllNampanWithPagination($page, $perPage); $detailItem = $this->helper->mapNampanWithSalesData($semuaNampanPaginated, $nampanTerjual); $filterInfo = $this->helper->buildNampanFilterInfo($tanggal, $params); return [ 'filter' => $filterInfo, 'rekap_harian' => $totals, 'nampan' => $detailItem->values(), 'pagination' => $this->helper->buildPaginationInfo($semuaNampanPaginated), ]; } public function exportRingkasan(array $params) { $filter = $params['filter']; $format = $params['format']; $page = $params['page'] ?? 1; $allSalesNames = $this->getAllSalesNames(); if ($filter === 'hari') { // Tar kalau mau ubah eksport laporan setiap hari, param ke-3 jadiin false #Bagas $data = $this->processLaporanHarian($allSalesNames, $page, true); } else { $data = $this->processLaporanBulanan($allSalesNames, $page, true); } $fileName = "laporan_ringkasan_{$filter}_" . Carbon::now()->format('Ymd') . ".{$format}"; if ($format === 'pdf') { $viewData = method_exists($data, 'items') ? $data->items() : $data; $pdf = PDF::loadView('exports.ringkasan_pdf', [ 'data' => $viewData, 'filter' => $filter ]); $pdf->setPaper('a4', 'landscape'); return $pdf->download($fileName); } return Excel::download(new RingkasanExport($data, $page), $fileName); } private function getAllSalesNames(): Collection { return Cache::remember('all_sales_names', self::CACHE_TTL, function () { return Transaksi::select('nama_sales')->distinct()->pluck('nama_sales'); }); } private function processLaporanHarian(Collection $allSalesNames, int $page = 1, bool $limitPagination = true) { return $this->transaksiRepo->processLaporanHarian($allSalesNames, $page, $limitPagination); } private function processLaporanBulanan(Collection $allSalesNames, int $page = 1, bool $limitPagination = true) { return $this->transaksiRepo->processLaporanBulanan($allSalesNames, $page, $limitPagination); } private function buildBaseItemQuery(Carbon $carbonDate) { return ItemTransaksi::query() ->join('items', 'item_transaksis.id_item', '=', 'items.id') ->join('produks', 'items.id_produk', '=', 'produks.id') ->join('transaksis', 'item_transaksis.id_transaksi', '=', 'transaksis.id') ->whereDate('transaksis.created_at', $carbonDate); } private function applyFilters($query, array $params): void { if (!empty($params['sales_id'])) { $query->join('sales', 'transaksis.id_sales', '=', 'sales.id') ->where('sales.id', $params['sales_id']); } if (isset($params['nampan_id'])) { if ($params['nampan_id'] == 0) { $query->whereNull('items.id_nampan'); } else { $query->where('items.id_nampan', $params['nampan_id']); } } if (!empty($params['nama_pembeli'])) { $query->where('transaksis.nama_pembeli', 'like', "%{$params['nama_pembeli']}%"); } } private function applyNampanFilters($query, array $params): void { if (!empty($params['sales_id'])) { $query->join('sales', 'transaksis.id_sales', '=', 'sales.id') ->where('sales.id', $params['sales_id']); } if (!empty($params['produk_id'])) { $query->where('produks.id', $params['produk_id']); } if (!empty($params['nama_pembeli'])) { $query->where('transaksis.nama_pembeli', 'like', "%{$params['nama_pembeli']}%"); } } }