diff --git a/app/Helpers/LaporanHelper.php b/app/Helpers/LaporanHelper.php index 700c9b1..7d44122 100644 --- a/app/Helpers/LaporanHelper.php +++ b/app/Helpers/LaporanHelper.php @@ -18,9 +18,10 @@ class LaporanHelper public function calculateTotals(Collection $data): array { - $totalPendapatan = $data->sum('pendapatan'); - $totalItemTerjual = $data->sum('jumlah_item_terjual'); - $totalBeratTerjual = $data->sum('berat_terjual'); + // Asumsi $data punya raw numeric (int/float) + $totalPendapatan = $data->sum('pendapatan'); // Raw float + $totalItemTerjual = $data->sum('jumlah_item_terjual'); // Int + $totalBeratTerjual = $data->sum('berat_terjual'); // Float return [ 'total_item_terjual' => $totalItemTerjual, @@ -57,15 +58,15 @@ class LaporanHelper $dataTerjual = $salesData->get($item->id); return [ 'nama_produk' => $item->nama, - 'jumlah_item_terjual' => (int) $dataTerjual->jumlah_item_terjual, + 'jumlah_item_terjual' => (int) $dataTerjual->jumlah_item_terjual, // Selalu int 'berat_terjual' => $this->formatWeight($dataTerjual->berat_terjual), 'pendapatan' => $this->formatCurrency($dataTerjual->pendapatan), ]; } - return [ + return [ // Untuk kosong, return dengan 0 (akan difilter nanti) 'nama_produk' => $item->nama, - 'jumlah_item_terjual' => self::DEFAULT_DISPLAY, + 'jumlah_item_terjual' => 0, 'berat_terjual' => self::DEFAULT_DISPLAY, 'pendapatan' => self::DEFAULT_DISPLAY, ]; @@ -94,12 +95,12 @@ class LaporanHelper }); } - public function buildProdukFilterInfo(Carbon $carbonDate, array $params): array + public function buildProdukFilterInfo(Carbon $startDate, Carbon $endDate, array $params): array { $filterInfo = [ - 'tanggal' => $carbonDate->isoFormat('dddd, D MMMM Y'), + 'periode' => "{$startDate->isoFormat('D MMMM Y')} - {$endDate->isoFormat('D MMMM Y')}", 'nama_sales' => null, - 'nampan' => null, + 'nampan' => null, // Default null 'nama_pembeli' => $params['nama_pembeli'] ?? null, ]; @@ -109,21 +110,23 @@ class LaporanHelper } if (isset($params['nampan_id'])) { - if ($params['nampan_id'] == 0) { + if ($params['nampan_id'] === -1) { $filterInfo['nampan'] = 'Brankas'; - } else { + } elseif ($params['nampan_id'] > 0) { $nampan = Nampan::find($params['nampan_id']); $filterInfo['nampan'] = $nampan?->nama; + } else { // 0: Semua + $filterInfo['nampan'] = 'Semua Nampan'; } } return $filterInfo; } - public function buildNampanFilterInfo(Carbon $carbonDate, array $params): array + public function buildNampanFilterInfo(Carbon $startDate, Carbon $endDate, array $params): array { $filterInfo = [ - 'tanggal' => $carbonDate->isoFormat('dddd, D MMMM Y'), + 'periode' => "{$startDate->isoFormat('D MMMM Y')} - {$endDate->isoFormat('D MMMM Y')}", // FIXED: Range 'nama_sales' => null, 'produk' => null, 'nama_pembeli' => $params['nama_pembeli'] ?? null, diff --git a/app/Http/Controllers/LaporanController.php b/app/Http/Controllers/LaporanController.php index 0f0a4da..3bc6d24 100644 --- a/app/Http/Controllers/LaporanController.php +++ b/app/Http/Controllers/LaporanController.php @@ -88,17 +88,18 @@ class LaporanController extends Controller public function exportDetailNampan(Request $request) { try { - return $this->laporanService->exportPerNampan($request->validate([ - 'tanggal' => 'required|string', + $validated = $request->validate([ + 'start_date' => 'required|date_format:Y-m-d', + 'end_date' => 'required|date_format:Y-m-d|after_or_equal:start_date', 'format' => 'required|string|in:pdf,xlsx,csv', 'page' => 'required|integer|min:1', 'sales_id' => 'nullable|integer|exists:sales,id', 'produk_id' => 'nullable|integer|exists:produks,id', 'nama_pembeli' => 'nullable|string|max:255', - ])); - + ]); + return $this->laporanService->exportPerNampan($validated); } catch (\Exception $e) { - Log::error('Error in exprot per nampan method: ' . $e->getMessage()); + Log::error('Error in export per nampan: ' . $e->getMessage()); return response()->json(['error' => 'Terjadi kesalahan saat export data'], 500); } } @@ -106,17 +107,18 @@ class LaporanController extends Controller public function exportDetailProduk(Request $request) { try { - return $this->laporanService->exportPerProduk($request->validate([ - 'tanggal' => 'required|string', + $validated = $request->validate([ + 'start_date' => 'required|date_format:Y-m-d', + 'end_date' => 'required|date_format:Y-m-d|after_or_equal:start_date', 'format' => 'required|string|in:pdf,xlsx,csv', 'page' => 'required|integer|min:1', 'sales_id' => 'nullable|integer|exists:sales,id', - 'nampan_id' => 'nullable|integer|exists:nampans,id', + 'nampan_id' => 'nullable|integer', 'nama_pembeli' => 'nullable|string|max:255', - ])); - + ]); + return $this->laporanService->exportPerProduk($validated); } catch (\Exception $e) { - Log::error('Error in exprot per nampan method: ' . $e->getMessage()); + Log::error('Error in export per produk: ' . $e->getMessage()); return response()->json(['error' => 'Terjadi kesalahan saat export data'], 500); } } diff --git a/app/Http/Controllers/ProdukController.php b/app/Http/Controllers/ProdukController.php index 681189a..140608a 100644 --- a/app/Http/Controllers/ProdukController.php +++ b/app/Http/Controllers/ProdukController.php @@ -33,7 +33,7 @@ class ProdukController extends Controller $validated = $request->validate( [ - 'nama' => 'required|string|max:100', + 'nama' => 'required|string|max:100|unique:produks,nama', 'id_kategori' => 'required|exists:kategoris,id', 'berat' => 'required|numeric', 'kadar' => 'required|integer', @@ -42,6 +42,7 @@ class ProdukController extends Controller ], [ 'nama.required' => 'Nama produk harus diisi.', + 'nama.unique' => 'Nama produk sudah digunakan.', 'id_kategori' => 'Kategori tidak valid.', 'berat.required' => 'Berat harus diisi.', 'kadar.required' => 'Kadar harus diisi.', @@ -122,7 +123,7 @@ class ProdukController extends Controller $validated = $request->validate( [ - 'nama' => 'required|string|max:100', + 'nama' => 'required|string|max:100|unique:produks,nama,' . $id, 'id_kategori' => 'required|exists:kategoris,id', 'berat' => 'required|numeric', 'kadar' => 'required|integer', @@ -131,6 +132,7 @@ class ProdukController extends Controller ], [ 'nama.required' => 'Nama produk harus diisi.', + 'nama.unique' => 'Nama produk sudah digunakan.', 'id_kategori' => 'Kategori tidak valid.', 'berat.required' => 'Berat harus diisi.', 'kadar.required' => 'Kadar harus diisi', @@ -211,7 +213,7 @@ class ProdukController extends Controller $foto->delete(); } - // Hapus produk (soft delete) + $produk->items()->delete(); $produk->delete(); DB::commit(); diff --git a/app/Http/Requests/DetailLaporanRequest.php b/app/Http/Requests/DetailLaporanRequest.php index 5a2f308..7cfc841 100644 --- a/app/Http/Requests/DetailLaporanRequest.php +++ b/app/Http/Requests/DetailLaporanRequest.php @@ -20,7 +20,8 @@ class DetailLaporanRequest extends FormRequest public function rules(): array { return [ - 'tanggal' => 'required|date_format:Y-m-d|before_or_equal:today', + 'start_date' => 'required|date_format:Y-m-d', + 'end_date' => 'required|date_format:Y-m-d|after_or_equal:start_date', 'sales_id' => 'nullable|integer|exists:sales,id', 'nampan_id' => 'nullable|integer', 'produk_id' => 'nullable|integer|exists:produks,id', @@ -36,9 +37,7 @@ class DetailLaporanRequest extends FormRequest public function messages(): array { return [ - 'tanggal.required' => 'Tanggal harus diisi', - 'tanggal.date_format' => 'Format tanggal harus Y-m-d', - 'tanggal.before_or_equal' => 'Tanggal tidak boleh lebih dari hari ini', + 'end_date.after_or_equal' => 'Tanggal akhir harus sama atau setelah tanggal mulai.', 'sales_id.exists' => 'Sales tidak ditemukan', 'produk_id.exists' => 'Produk tidak ditemukan', 'nama_pembeli.max' => 'Nama pembeli maksimal 255 karakter', diff --git a/app/Models/Item.php b/app/Models/Item.php index 7fcec9e..1fdd3b6 100644 --- a/app/Models/Item.php +++ b/app/Models/Item.php @@ -24,7 +24,7 @@ class Item extends Model parent::boot(); static::creating(function ($item) { - $prefix = 'ITM'; + $prefix = 'TMJC'; $date = now()->format('Ymd'); // Cari item terakhir yg dibuat hari ini diff --git a/app/Services/LaporanService.php b/app/Services/LaporanService.php index 1e280db..76b8923 100644 --- a/app/Services/LaporanService.php +++ b/app/Services/LaporanService.php @@ -54,20 +54,28 @@ 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 */ public function getDetailPerProduk(array $params) { - $tanggal = Carbon::parse($params['tanggal']); + $startDate = Carbon::parse($params['start_date'])->startOfDay(); + $endDate = Carbon::parse($params['end_date'])->endOfDay(); + + // 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: Calculate overall totals for all filtered items --- - $totalsQuery = $this->buildBaseItemQuery($tanggal); + // --- Step 1: Totals --- + $totalsQuery = $this->buildBaseItemQueryForRange($startDate, $endDate); $this->applyFilters($totalsQuery, $params); $totalsResult = $totalsQuery->select( @@ -76,14 +84,14 @@ class LaporanService DB::raw('COALESCE(SUM(item_transaksis.harga_deal), 0) as total_pendapatan') )->first(); - $rekapHarian = [ + $rekapInterval = [ 'total_item_terjual' => (int) $totalsResult->total_item_terjual, 'total_berat_terjual' => $this->helper->formatWeight($totalsResult->total_berat_terjual), 'total_pendapatan' => $this->helper->formatCurrency($totalsResult->total_pendapatan), ]; - // --- Step 2: Build the filtered sales data subquery --- - $salesSubQuery = $this->buildBaseItemQuery($tanggal) + // --- Step 2: Subquery for all products --- + $salesSubQuery = $this->buildBaseItemQueryForRange($startDate, $endDate) ->select( 'produks.id as id_produk', DB::raw('COUNT(item_transaksis.id) as jumlah_item_terjual'), @@ -94,8 +102,8 @@ class LaporanService $this->applyFilters($salesSubQuery, $params); - // --- Step 3: Fetch paginated products and LEFT JOIN the sales data subquery --- - $semuaProdukPaginated = Produk::select( + // --- Step 3: All products (NO PAGINATION) --- + $semuaProduk = Produk::select( 'produks.id', 'produks.nama as nama_produk', 'sales_data.jumlah_item_terjual', @@ -106,36 +114,70 @@ 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 results for final presentation --- - $detailItem = $semuaProdukPaginated->map(function ($item) { + // --- Step 4: Map & filter --- + $detailItem = $semuaProduk->map(function ($item) { return [ 'nama_produk' => $item->nama_produk, 'jumlah_item_terjual' => $item->jumlah_item_terjual ? (int) $item->jumlah_item_terjual : 0, 'berat_terjual' => $item->berat_terjual ? $this->helper->formatWeight($item->berat_terjual) : '-', 'pendapatan' => $item->pendapatan ? $this->helper->formatCurrency($item->pendapatan) : '-', ]; + })->filter(function ($item) { + return $item['jumlah_item_terjual'] > 0; }); - // --- Step 5: Assemble final response --- - $filterInfo = $this->helper->buildProdukFilterInfo($tanggal, $params); + // FIXED: Simple collection without pagination + $filteredCollection = $detailItem->values(); + + // --- Step 5: Response --- + $filterInfo = $this->helper->buildProdukFilterInfo($startDate, $endDate, $params); return [ 'filter' => $filterInfo, - 'rekap_harian' => $rekapHarian, - 'produk' => $detailItem, - 'pagination' => $this->helper->buildPaginationInfo($semuaProdukPaginated), + 'rekap_interval' => $rekapInterval, + '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, + ], ]; } + private function buildBaseItemQueryForRange(Carbon $startDate, Carbon $endDate) + { + return ItemTransaksi::query() + ->join('produks', 'item_transaksis.id_produk', '=', 'produks.id') + ->join('transaksis', 'item_transaksis.id_transaksi', '=', 'transaksis.id') + ->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) { - $tanggal = Carbon::parse($params['tanggal']); + $startDate = Carbon::parse($params['start_date'])->startOfDay(); + $endDate = Carbon::parse($params['end_date'])->endOfDay(); + + if ($startDate->diffInDays($endDate) > 30) { + throw new \InvalidArgumentException('Interval tanggal maksimal 30 hari.'); + } + $page = $params['page'] ?? 1; $perPage = $params['per_page'] ?? self::DEFAULT_PER_PAGE; - $nampanTerjualQuery = $this->buildBaseItemQuery($tanggal); + $nampanTerjualQuery = $this->buildBaseItemQueryForRange($startDate, $endDate); $this->applyNampanFilters($nampanTerjualQuery, $params); $nampanTerjual = $nampanTerjualQuery @@ -149,16 +191,41 @@ class LaporanService ->get() ->keyBy('nama_nampan'); - $totals = $this->helper->calculateTotals($nampanTerjual); - $semuaNampanPaginated = $this->helper->getAllNampanWithPagination($page, $perPage); - $detailItem = $this->helper->mapNampanWithSalesData($semuaNampanPaginated, $nampanTerjual); - $filterInfo = $this->helper->buildNampanFilterInfo($tanggal, $params); + // FIXED: calculateTotals sum raw (bukan formatted string) + $nampanTerjualRaw = $nampanTerjual->map(function ($item) { + return [ + 'jumlah_item_terjual' => (int) $item->jumlah_item_terjual, + 'berat_terjual' => $item->berat_terjual, + 'pendapatan' => $item->pendapatan, + ]; + }); + $totals = $this->helper->calculateTotals($nampanTerjualRaw); + + // 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: Simple collection without pagination + $filteredCollection = $detailItem->values(); + + $filterInfo = $this->helper->buildNampanFilterInfo($startDate, $endDate, $params); return [ 'filter' => $filterInfo, - 'rekap_harian' => $totals, - 'nampan' => $detailItem->values(), - 'pagination' => $this->helper->buildPaginationInfo($semuaNampanPaginated), + '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, + ], ]; } @@ -194,22 +261,22 @@ class LaporanService public function exportPerProduk(array $params) { - $tanggal = $params['tanggal']; $format = $params['format']; - $allParams = $params; unset($allParams['page'], $allParams['per_page']); $data = $this->getDetailPerProdukForExport($allParams); - $fileName = "laporan_per_produk_{$tanggal}_" . Carbon::now()->format('Ymd') . ".{$format}"; + $startDate = Carbon::parse($params['start_date'])->format('Ymd'); + $endDate = Carbon::parse($params['end_date'])->format('Ymd'); + $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', 'potrait'); + $pdf->setPaper('a4', 'portrait'); return $pdf->download($fileName); } @@ -218,22 +285,22 @@ class LaporanService public function exportPerNampan(array $params) { - $tanggal = $params['tanggal']; $format = $params['format']; - $allParams = $params; unset($allParams['page'], $allParams['per_page']); $data = $this->getDetailPerNampanForExport($allParams); - $fileName = "laporan_per_nampan_{$tanggal}_" . Carbon::now()->format('Ymd') . ".{$format}"; + $startDate = Carbon::parse($params['start_date'])->format('Ymd'); + $endDate = Carbon::parse($params['end_date'])->format('Ymd'); + $fileName = "laporan_per_nampan_{$startDate}_to_{$endDate}.{$format}"; if ($format === 'pdf') { $pdf = PDF::loadView('exports.pernampan_pdf', [ 'data' => $data, 'title' => 'Laporan Detail Per Nampan' ]); - $pdf->setPaper('a4', 'potrait'); + $pdf->setPaper('a4', 'portrait'); return $pdf->download($fileName); } @@ -242,9 +309,10 @@ class LaporanService private function getDetailPerProdukForExport(array $params) { - $tanggal = Carbon::parse($params['tanggal']); - - $produkTerjualQuery = $this->buildBaseItemQuery($tanggal); + $startDate = Carbon::parse($params['start_date'])->startOfDay(); + $endDate = Carbon::parse($params['end_date'])->endOfDay(); + + $produkTerjualQuery = $this->buildBaseItemQueryForRange($startDate, $endDate); $this->applyFilters($produkTerjualQuery, $params); $produkTerjual = $produkTerjualQuery @@ -259,7 +327,15 @@ class LaporanService ->get() ->keyBy('id_produk'); - $totals = $this->helper->calculateTotals($produkTerjual); + // FIXED: calculateTotals sum raw + $produkTerjualRaw = $produkTerjual->map(function ($item) { + return [ + 'jumlah_item_terjual' => (int) $item->jumlah_item_terjual, + 'berat_terjual' => $item->berat_terjual, + 'pendapatan' => $item->pendapatan, + ]; + }); + $totals = $this->helper->calculateTotals($produkTerjualRaw); $semuaProduk = Produk::select('id', 'nama')->orderBy('nama')->get(); @@ -273,29 +349,24 @@ class LaporanService 'pendapatan' => $this->helper->formatCurrency($dataTerjual->pendapatan), ]; } + return null; + })->filter(); - return [ - 'nama_produk' => $item->nama, - 'jumlah_item_terjual' => LaporanHelper::DEFAULT_DISPLAY, - 'berat_terjual' => LaporanHelper::DEFAULT_DISPLAY, - 'pendapatan' => LaporanHelper::DEFAULT_DISPLAY, - ]; - }); - - $filterInfo = $this->helper->buildProdukFilterInfo($tanggal, $params); + $filterInfo = $this->helper->buildProdukFilterInfo($startDate, $endDate, $params); return [ 'filter' => $filterInfo, - 'rekap_harian' => $totals, + 'rekap_interval' => $totals, 'produk' => $detailItem->values(), ]; } private function getDetailPerNampanForExport(array $params) { - $tanggal = Carbon::parse($params['tanggal']); + $startDate = Carbon::parse($params['start_date'])->startOfDay(); + $endDate = Carbon::parse($params['end_date'])->endOfDay(); - $nampanTerjualQuery = $this->buildBaseItemQuery($tanggal); + $nampanTerjualQuery = $this->buildBaseItemQueryForRange($startDate, $endDate); $this->applyNampanFilters($nampanTerjualQuery, $params); $nampanTerjual = $nampanTerjualQuery @@ -309,9 +380,18 @@ class LaporanService ->get() ->keyBy('posisi_asal'); - $totals = $this->helper->calculateTotals($nampanTerjual); + // FIXED: Sum raw + $nampanTerjualRaw = $nampanTerjual->map(function ($item) { + return [ + 'jumlah_item_terjual' => (int) $item->jumlah_item_terjual, + 'berat_terjual' => $item->berat_terjual, + 'pendapatan' => $item->pendapatan, + ]; + }); + $totals = $this->helper->calculateTotals($nampanTerjualRaw); $semuaPosisi = DB::table('item_transaksis') + ->whereBetween('created_at', [$startDate, $endDate]) ->select('posisi_asal') ->distinct() ->pluck('posisi_asal') @@ -328,25 +408,18 @@ class LaporanService 'pendapatan' => $this->helper->formatCurrency($dataTerjual->pendapatan), ]; } + return null; + })->filter(); - return [ - 'nama_nampan' => $posisi, - 'jumlah_item_terjual' => LaporanHelper::DEFAULT_DISPLAY, - 'berat_terjual' => LaporanHelper::DEFAULT_DISPLAY, - 'pendapatan' => LaporanHelper::DEFAULT_DISPLAY, - ]; - }); - - $filterInfo = $this->helper->buildNampanFilterInfo($tanggal, $params); + $filterInfo = $this->helper->buildNampanFilterInfo($startDate, $endDate, $params); return [ 'filter' => $filterInfo, - 'rekap_harian' => $totals, + 'rekap_interval' => $totals, 'nampan' => $detailItem->values(), ]; } - private function getAllSalesNames(): Collection { return Cache::remember('all_sales_names', self::CACHE_TTL, function () { @@ -364,15 +437,6 @@ class LaporanService return $this->transaksiRepo->processLaporanBulanan($allSalesNames, $page, $limitPagination); } - private function buildBaseItemQuery(Carbon $carbonDate) - { - // UBAH: Menghapus join ke tabel 'items' dan join 'produks' langsung dari 'item_transaksis' - return ItemTransaksi::query() - ->join('produks', 'item_transaksis.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'])) { @@ -381,11 +445,14 @@ class LaporanService } if (isset($params['nampan_id'])) { - // UBAH: Filter berdasarkan 'item_transaksis.id_nampan' - if ($params['nampan_id'] == 0) { - $query->whereNull('item_transaksis.id_nampan'); - } else { - $query->where('item_transaksis.id_nampan', $params['nampan_id']); + $nampanId = (int) $params['nampan_id']; + if ($nampanId === -1) { + $query->where('item_transaksis.posisi_asal', 'Brankas'); + } elseif ($nampanId > 0) { + $query->join('nampans', function ($join) use ($nampanId) { + $join->on('item_transaksis.posisi_asal', '=', 'nampans.nama') + ->where('nampans.id', $nampanId); + }); } } diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 3e7500e..8d7258c 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -33,11 +33,10 @@ class DatabaseSeeder extends Seeder User::factory(2)->create(); Sales::factory(5)->create(); - $kodeNampan = ['A', 'B']; - foreach ($kodeNampan as $kode) { - for ($i=0; $i < 4; $i++) { + for ($i=0; $i < 30; $i++) { + if ($i != 12) { Nampan::factory()->create([ - 'nama' => $kode . ($i + 1) // A1, A2, ... B4 + 'nama' => 'A' . ($i + 1) ]); } } diff --git a/public/logo.ico b/public/logo.ico new file mode 100644 index 0000000..e8cb3af Binary files /dev/null and b/public/logo.ico differ diff --git a/resources/js/components/BrankasList.vue b/resources/js/components/BrankasList.vue index ffda540..904ea91 100644 --- a/resources/js/components/BrankasList.vue +++ b/resources/js/components/BrankasList.vue @@ -340,40 +340,50 @@ const printQR = () => { Print QR Code - ${selectedItem.value.kode_item}
- QR Code + QR Code
-
${selectedItem.value.kode_item}
-
${selectedItem.value.produk.nama}
-
${selectedItem.value.produk.berat}g
+ ${selectedItem.value.kode_item}
`); printWindow.document.close(); - printWindow.print(); } }; + const handleImageError = (event) => { event.target.style.display = 'none'; }; diff --git a/resources/js/components/CreateItemModal.vue b/resources/js/components/CreateItemModal.vue index fc40955..bd3c622 100644 --- a/resources/js/components/CreateItemModal.vue +++ b/resources/js/components/CreateItemModal.vue @@ -87,7 +87,7 @@ const props = defineProps({ }); // Emits -const emit = defineEmits(['close']); +const emit = defineEmits(['close','itemAdded']); // State const selectedNampan = ref(''); @@ -147,15 +147,17 @@ const createItem = async () => { } const response = await axios.post('/api/item', payload, { - headers: { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }, - });; + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + }); success.value = true; - createdItem.value = response.data.data + createdItem.value = response.data.data; console.log('Item created:', createdItem); + emit('itemAdded'); // 🔔 penting + loadNampanList(); } catch (error) { console.error('Error creating item:', error); @@ -165,6 +167,7 @@ const createItem = async () => { } }; + const addNewItem = () => { success.value = false; selectedNampan.value = ''; diff --git a/resources/js/components/DatePicker.vue b/resources/js/components/DatePicker.vue new file mode 100644 index 0000000..5b0d7bd --- /dev/null +++ b/resources/js/components/DatePicker.vue @@ -0,0 +1,206 @@ + + + diff --git a/resources/js/components/DetailPerNampan.vue b/resources/js/components/DetailPerNampan.vue index c7834e1..d56ce61 100644 --- a/resources/js/components/DetailPerNampan.vue +++ b/resources/js/components/DetailPerNampan.vue @@ -3,11 +3,15 @@
-
+
- - +
@@ -26,26 +30,27 @@
-
-
-
Total Item
-
{{ data.rekap_harian.total_item_terjual }}
-
-
-
Total Berat
-
{{ data.rekap_harian.total_berat_terjual }}
-
-
-
Total Pendapatan
-
{{ data.rekap_harian.total_pendapatan }}
-
-
-
+
Memuat data...
+
+
+
Total Item
+
{{ data.rekap_interval.total_item_terjual }}
+
+
+
Total Berat
+
{{ data.rekap_interval.total_berat_terjual }}
+
+
+
Total Pendapatan
+
{{ data.rekap_interval.total_pendapatan }}
+
+
+
@@ -113,7 +118,7 @@
- + Tidak ada data untuk ditampilkan.