Merge branch 'production' of https://git.abbauf.com/Magang-2025/Kasir into production
This commit is contained in:
commit
428fedb944
@ -64,12 +64,17 @@ class DetailNampanExport implements FromCollection, WithHeadings, WithTitle, Wit
|
|||||||
public function styles(Worksheet $sheet)
|
public function styles(Worksheet $sheet)
|
||||||
{
|
{
|
||||||
$styles = [
|
$styles = [
|
||||||
1 => ['font' => ['bold' => true]], // Header row
|
1 => ['font' => ['bold' => true]],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Style for recap row if exists
|
|
||||||
if (isset($this->data['rekap_harian'])) {
|
if (isset($this->data['rekap_harian'])) {
|
||||||
$styles[2] = [
|
$lastRow = 1;
|
||||||
|
if (isset($this->data['nampan'])) {
|
||||||
|
$lastRow += count($this->data['nampan']);
|
||||||
|
}
|
||||||
|
$lastRow++;
|
||||||
|
|
||||||
|
$styles[$lastRow] = [
|
||||||
'font' => ['bold' => true],
|
'font' => ['bold' => true],
|
||||||
'fill' => [
|
'fill' => [
|
||||||
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
|
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
|
||||||
|
|||||||
@ -70,12 +70,17 @@ class DetailProdukExport implements FromCollection, WithHeadings, WithTitle, Wit
|
|||||||
public function styles(Worksheet $sheet)
|
public function styles(Worksheet $sheet)
|
||||||
{
|
{
|
||||||
$styles = [
|
$styles = [
|
||||||
1 => ['font' => ['bold' => true]], // Header row
|
1 => ['font' => ['bold' => true]],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Style for recap row if exists
|
|
||||||
if (isset($this->data['rekap_harian'])) {
|
if (isset($this->data['rekap_harian'])) {
|
||||||
$styles[2] = [
|
$lastRow = 1;
|
||||||
|
if (isset($this->data['nampan'])) {
|
||||||
|
$lastRow += count($this->data['nampan']);
|
||||||
|
}
|
||||||
|
$lastRow++;
|
||||||
|
|
||||||
|
$styles[$lastRow] = [
|
||||||
'font' => ['bold' => true],
|
'font' => ['bold' => true],
|
||||||
'fill' => [
|
'fill' => [
|
||||||
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
|
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
|
||||||
@ -83,7 +88,7 @@ class DetailProdukExport implements FromCollection, WithHeadings, WithTitle, Wit
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $styles;
|
return $styles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,7 +47,6 @@ class RingkasanExport implements FromCollection, WithHeadings, WithStyles
|
|||||||
'Pendapatan' => $totalPendapatan,
|
'Pendapatan' => $totalPendapatan,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Tambahkan baris kosong biar rapi
|
|
||||||
$rows->push(['Tanggal' => '', 'Nama Sales' => '', 'Item Terjual' => '', 'Berat' => '', 'Pendapatan' => '']);
|
$rows->push(['Tanggal' => '', 'Nama Sales' => '', 'Item Terjual' => '', 'Berat' => '', 'Pendapatan' => '']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +67,7 @@ class RingkasanExport implements FromCollection, WithHeadings, WithStyles
|
|||||||
public function styles(Worksheet $sheet)
|
public function styles(Worksheet $sheet)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
1 => ['font' => ['bold' => true]], // Header bold
|
1 => ['font' => ['bold' => true]],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ use App\Models\Produk;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class LaporanHelper
|
class LaporanHelper
|
||||||
{
|
{
|
||||||
@ -30,16 +31,19 @@ class LaporanHelper
|
|||||||
|
|
||||||
public function getAllNampanWithPagination(int $page, int $perPage): LengthAwarePaginator
|
public function getAllNampanWithPagination(int $page, int $perPage): LengthAwarePaginator
|
||||||
{
|
{
|
||||||
$semuaNampan = Nampan::select('id', 'nama')->orderBy('nama')->get();
|
$semuaPosisi = DB::table('item_transaksis')
|
||||||
$brankasEntry = (object) ['id' => 0, 'nama' => 'Brankas'];
|
->select('posisi_asal')
|
||||||
$semuaNampanCollection = $semuaNampan->prepend($brankasEntry);
|
->distinct()
|
||||||
|
->pluck('posisi_asal')
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
|
||||||
$offset = ($page - 1) * $perPage;
|
$offset = ($page - 1) * $perPage;
|
||||||
$itemsForCurrentPage = $semuaNampanCollection->slice($offset, $perPage);
|
$itemsForCurrentPage = $semuaPosisi->slice($offset, $perPage);
|
||||||
|
|
||||||
return new LengthAwarePaginator(
|
return new LengthAwarePaginator(
|
||||||
$itemsForCurrentPage,
|
$itemsForCurrentPage,
|
||||||
$semuaNampanCollection->count(),
|
$semuaPosisi->count(),
|
||||||
$perPage,
|
$perPage,
|
||||||
$page,
|
$page,
|
||||||
['path' => request()->url(), 'query' => request()->query()]
|
['path' => request()->url(), 'query' => request()->query()]
|
||||||
@ -71,10 +75,10 @@ class LaporanHelper
|
|||||||
public function mapNampanWithSalesData($paginatedData, Collection $salesData): Collection
|
public function mapNampanWithSalesData($paginatedData, Collection $salesData): Collection
|
||||||
{
|
{
|
||||||
return $paginatedData->getCollection()->map(function ($item) use ($salesData) {
|
return $paginatedData->getCollection()->map(function ($item) use ($salesData) {
|
||||||
if ($salesData->has($item->id)) {
|
if ($salesData->has($item)) {
|
||||||
$dataTerjual = $salesData->get($item->id);
|
$dataTerjual = $salesData->get($item);
|
||||||
return [
|
return [
|
||||||
'nama_nampan' => $item->nama,
|
'nama_nampan' => $item, // sekarang langsung string posisi
|
||||||
'jumlah_item_terjual' => (int) $dataTerjual->jumlah_item_terjual,
|
'jumlah_item_terjual' => (int) $dataTerjual->jumlah_item_terjual,
|
||||||
'berat_terjual' => $this->formatWeight($dataTerjual->berat_terjual),
|
'berat_terjual' => $this->formatWeight($dataTerjual->berat_terjual),
|
||||||
'pendapatan' => $this->formatCurrency($dataTerjual->pendapatan),
|
'pendapatan' => $this->formatCurrency($dataTerjual->pendapatan),
|
||||||
@ -82,7 +86,7 @@ class LaporanHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'nama_nampan' => $item->nama,
|
'nama_nampan' => $item,
|
||||||
'jumlah_item_terjual' => self::DEFAULT_DISPLAY,
|
'jumlah_item_terjual' => self::DEFAULT_DISPLAY,
|
||||||
'berat_terjual' => self::DEFAULT_DISPLAY,
|
'berat_terjual' => self::DEFAULT_DISPLAY,
|
||||||
'pendapatan' => self::DEFAULT_DISPLAY,
|
'pendapatan' => self::DEFAULT_DISPLAY,
|
||||||
@ -153,11 +157,12 @@ class LaporanHelper
|
|||||||
public function hitungDataSales(Collection $transaksisPerSales): array
|
public function hitungDataSales(Collection $transaksisPerSales): array
|
||||||
{
|
{
|
||||||
$itemTerjual = $transaksisPerSales->sum(fn($t) => $t->itemTransaksi->count());
|
$itemTerjual = $transaksisPerSales->sum(fn($t) => $t->itemTransaksi->count());
|
||||||
|
|
||||||
|
// UBAH BAGIAN INI: Hapus ->item dari path relasi
|
||||||
$beratTerjual = $transaksisPerSales->sum(
|
$beratTerjual = $transaksisPerSales->sum(
|
||||||
fn($t) => $t->itemTransaksi->sum(fn($it) => $it->item?->produk?->berat ?? 0)
|
fn($t) => $t->itemTransaksi->sum(fn($it) => $it->produk?->berat ?? 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
$pendapatan = $transaksisPerSales->sum('total_harga');
|
$pendapatan = $transaksisPerSales->sum('total_harga');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@ -182,9 +187,9 @@ class LaporanHelper
|
|||||||
{
|
{
|
||||||
return $salesData->map(function ($sale) {
|
return $salesData->map(function ($sale) {
|
||||||
$sale['item_terjual'] = $sale['item_terjual'] > 0 ? $sale['item_terjual'] : self::DEFAULT_DISPLAY;
|
$sale['item_terjual'] = $sale['item_terjual'] > 0 ? $sale['item_terjual'] : self::DEFAULT_DISPLAY;
|
||||||
$sale['berat_terjual'] = $sale['berat_terjual_raw'] > 0 ?
|
$sale['berat_terjual'] = $sale['berat_terjual_raw'] > 0 ?
|
||||||
$this->formatWeight($sale['berat_terjual_raw']) : self::DEFAULT_DISPLAY;
|
$this->formatWeight($sale['berat_terjual_raw']) : self::DEFAULT_DISPLAY;
|
||||||
$sale['pendapatan'] = $sale['pendapatan_raw'] > 0 ?
|
$sale['pendapatan'] = $sale['pendapatan_raw'] > 0 ?
|
||||||
$this->formatCurrency($sale['pendapatan_raw']) : self::DEFAULT_DISPLAY;
|
$this->formatCurrency($sale['pendapatan_raw']) : self::DEFAULT_DISPLAY;
|
||||||
|
|
||||||
unset($sale['berat_terjual_raw'], $sale['pendapatan_raw']);
|
unset($sale['berat_terjual_raw'], $sale['pendapatan_raw']);
|
||||||
@ -201,4 +206,4 @@ class LaporanHelper
|
|||||||
{
|
{
|
||||||
return number_format($weight, 2, ',', '.') . self::WEIGHT_UNIT;
|
return number_format($weight, 2, ',', '.') . self::WEIGHT_UNIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,7 @@ class ItemController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function show(int $id)
|
public function show(int $id)
|
||||||
{
|
{
|
||||||
$item = Item::with('produk.foto','nampan','itemTransaksi.transaksi')->findOrFail($id);
|
$item = Item::with('produk.foto','nampan')->findOrFail($id);
|
||||||
return response()->json($item);
|
return response()->json($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ class ItemController extends Controller
|
|||||||
|
|
||||||
// custom methods
|
// custom methods
|
||||||
public function brankasItem(){
|
public function brankasItem(){
|
||||||
$items = Item::with('produk.foto','nampan')->whereNull('id_nampan')->belumTerjual()->get();
|
$items = Item::with('produk.foto','nampan')->whereNull('id_nampan')->get();
|
||||||
|
|
||||||
return response()->json($items);
|
return response()->json($items);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,7 +67,7 @@ class LaporanController extends Controller
|
|||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Log::error('Error in detailPerNampan method: ' . $e->getMessage());
|
Log::error('Error in detailPerNampan method: ' . $e->getMessage());
|
||||||
return response()->json(['error' => 'Terjadi kesalahan saat mengambil data nampan'], 500);
|
return response()->json(['error' => 'Terjadi kesalahan saat mengambil data nampan' . $e->getMessage()], 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ class TransaksiController extends Controller
|
|||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$limit = request()->query('limit', null);
|
$limit = request()->query('limit', null);
|
||||||
$query = Transaksi::with(['kasir', 'sales', 'itemTransaksi.item.produk'])->latest();
|
$query = Transaksi::with(['kasir', 'sales', 'itemTransaksi.produk'])->latest();
|
||||||
if ($limit) {
|
if ($limit) {
|
||||||
$query->limit((int)$limit);
|
$query->limit((int)$limit);
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ class TransaksiController extends Controller
|
|||||||
// Detail transaksi by ID
|
// Detail transaksi by ID
|
||||||
public function show($id)
|
public function show($id)
|
||||||
{
|
{
|
||||||
$transaksi = Transaksi::with(['kasir', 'sales', 'items.item.produk.foto'])->findOrFail($id);
|
$transaksi = Transaksi::with(['kasir', 'sales', 'items.produk.foto'])->findOrFail($id);
|
||||||
return response()->json($transaksi);
|
return response()->json($transaksi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ class TransaksiController extends Controller
|
|||||||
'ongkos_bikin' => 'nullable|numeric|min:0',
|
'ongkos_bikin' => 'nullable|numeric|min:0',
|
||||||
'total_harga' => 'required|numeric',
|
'total_harga' => 'required|numeric',
|
||||||
'items' => 'required|array',
|
'items' => 'required|array',
|
||||||
'items.*.kode_item' => 'required|exists:items,id',
|
'items.*.kode_item' => 'required|exists:items,id|numeric',
|
||||||
'items.*.harga_deal' => 'required|numeric',
|
'items.*.harga_deal' => 'required|numeric',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -80,24 +80,21 @@ class TransaksiController extends Controller
|
|||||||
// if (!$item) {
|
// if (!$item) {
|
||||||
// throw new \Exception("Item dengan kode_item {$it['kode_item']} tidak ditemukan.");
|
// throw new \Exception("Item dengan kode_item {$it['kode_item']} tidak ditemukan.");
|
||||||
// }
|
// }
|
||||||
$item = Item::find($it['kode_item']);
|
$item = Item::where('id',$it['kode_item'])->with('produk')->first();
|
||||||
|
|
||||||
ItemTransaksi::create([
|
ItemTransaksi::create([
|
||||||
'id_transaksi' => $transaksi->id,
|
'id_transaksi' => $transaksi->id,
|
||||||
'id_item' => $item->id,
|
'id_produk' => $item->produk->id,
|
||||||
'harga_deal' => $it['harga_deal'],
|
'harga_deal' => $it['harga_deal'],
|
||||||
'posisi_asal' => $item->nampan ? 'Nampan ' . $item->nampan->nama : 'Brankas',
|
'posisi_asal' => $it['posisi'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$item->update([
|
$item->forceDelete();
|
||||||
'is_sold' => true,
|
|
||||||
'id_nampan' => null,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DB::commit();
|
DB::commit();
|
||||||
return response()->json(
|
return response()->json(
|
||||||
$transaksi->load(['itemTransaksi.item.produk.foto', 'kasir', 'sales']),
|
$transaksi->load(['itemTransaksi.produk.foto', 'kasir', 'sales']),
|
||||||
201
|
201
|
||||||
);
|
);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
|||||||
@ -13,8 +13,7 @@ class Item extends Model
|
|||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'id_produk',
|
'id_produk',
|
||||||
'id_nampan',
|
'id_nampan',
|
||||||
'is_sold',
|
'kode_item',
|
||||||
'kode_item', // ✅ ditambahkan agar bisa diisi otomatis
|
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = ['created_at', 'updated_at', 'deleted_at'];
|
protected $hidden = ['created_at', 'updated_at', 'deleted_at'];
|
||||||
@ -50,18 +49,8 @@ class Item extends Model
|
|||||||
return $this->belongsTo(Produk::class, 'id_produk');
|
return $this->belongsTo(Produk::class, 'id_produk');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scopeBelumTerjual($query)
|
|
||||||
{
|
|
||||||
return $query->where('is_sold', false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function nampan()
|
public function nampan()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Nampan::class, 'id_nampan');
|
return $this->belongsTo(Nampan::class, 'id_nampan');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function itemTransaksi()
|
|
||||||
{
|
|
||||||
return $this->hasOne(ItemTransaksi::class, 'id_item');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class ItemTransaksi extends Model
|
|||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'id_transaksi',
|
'id_transaksi',
|
||||||
'id_item',
|
'id_produk',
|
||||||
'harga_deal',
|
'harga_deal',
|
||||||
'posisi_asal'
|
'posisi_asal'
|
||||||
];
|
];
|
||||||
@ -24,8 +24,8 @@ class ItemTransaksi extends Model
|
|||||||
return $this->belongsTo(Transaksi::class, 'id_transaksi');
|
return $this->belongsTo(Transaksi::class, 'id_transaksi');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function item()
|
public function produk()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Item::class, 'id_item');
|
return $this->belongsTo(Produk::class, 'id_produk');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,7 @@ class TransaksiRepository
|
|||||||
$totalHariUntukPaginasi = $endDate->diffInDays($startDate) + 1;
|
$totalHariUntukPaginasi = $endDate->diffInDays($startDate) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$transaksis = Transaksi::with(['itemTransaksi.item.produk'])
|
$transaksis = Transaksi::with(['itemTransaksi.produk'])
|
||||||
->whereBetween('created_at', [$startDate->startOfDay(), $endDate->endOfDay()])
|
->whereBetween('created_at', [$startDate->startOfDay(), $endDate->endOfDay()])
|
||||||
->orderBy('created_at', 'desc')
|
->orderBy('created_at', 'desc')
|
||||||
->get();
|
->get();
|
||||||
@ -100,7 +100,7 @@ class TransaksiRepository
|
|||||||
{
|
{
|
||||||
$perPage = self::MONTHLY_PER_PAGE;
|
$perPage = self::MONTHLY_PER_PAGE;
|
||||||
|
|
||||||
$transaksis = Transaksi::with(['itemTransaksi.item.produk'])
|
$transaksis = Transaksi::with(['itemTransaksi.produk'])
|
||||||
->orderBy('created_at', 'desc')
|
->orderBy('created_at', 'desc')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
|||||||
@ -67,7 +67,6 @@ class LaporanService
|
|||||||
$perPage = $params['per_page'] ?? self::DEFAULT_PER_PAGE;
|
$perPage = $params['per_page'] ?? self::DEFAULT_PER_PAGE;
|
||||||
|
|
||||||
// --- Step 1: Calculate overall totals for all filtered items ---
|
// --- Step 1: Calculate overall totals for all filtered items ---
|
||||||
// We need a separate query for totals that is not affected by pagination.
|
|
||||||
$totalsQuery = $this->buildBaseItemQuery($tanggal);
|
$totalsQuery = $this->buildBaseItemQuery($tanggal);
|
||||||
$this->applyFilters($totalsQuery, $params);
|
$this->applyFilters($totalsQuery, $params);
|
||||||
|
|
||||||
@ -79,8 +78,8 @@ class LaporanService
|
|||||||
|
|
||||||
$rekapHarian = [
|
$rekapHarian = [
|
||||||
'total_item_terjual' => (int) $totalsResult->total_item_terjual,
|
'total_item_terjual' => (int) $totalsResult->total_item_terjual,
|
||||||
'total_berat_terjual' => $this->helper->formatWeight($totalsResult->total_berat_terjual), // Assuming formatting helper
|
'total_berat_terjual' => $this->helper->formatWeight($totalsResult->total_berat_terjual),
|
||||||
'total_pendapatan' => $this->helper->formatCurrency($totalsResult->total_pendapatan), // Assuming formatting helper
|
'total_pendapatan' => $this->helper->formatCurrency($totalsResult->total_pendapatan),
|
||||||
];
|
];
|
||||||
|
|
||||||
// --- Step 2: Build the filtered sales data subquery ---
|
// --- Step 2: Build the filtered sales data subquery ---
|
||||||
@ -92,7 +91,7 @@ class LaporanService
|
|||||||
DB::raw('COALESCE(SUM(item_transaksis.harga_deal), 0) as pendapatan')
|
DB::raw('COALESCE(SUM(item_transaksis.harga_deal), 0) as pendapatan')
|
||||||
)
|
)
|
||||||
->groupBy('produks.id');
|
->groupBy('produks.id');
|
||||||
// Apply filters to the subquery
|
|
||||||
$this->applyFilters($salesSubQuery, $params);
|
$this->applyFilters($salesSubQuery, $params);
|
||||||
|
|
||||||
// --- Step 3: Fetch paginated products and LEFT JOIN the sales data subquery ---
|
// --- Step 3: Fetch paginated products and LEFT JOIN the sales data subquery ---
|
||||||
@ -113,7 +112,7 @@ class LaporanService
|
|||||||
$detailItem = $semuaProdukPaginated->map(function ($item) {
|
$detailItem = $semuaProdukPaginated->map(function ($item) {
|
||||||
return [
|
return [
|
||||||
'nama_produk' => $item->nama_produk,
|
'nama_produk' => $item->nama_produk,
|
||||||
'jumlah_item_terjual' => $item->jumlah_item_terjual ? (int) $item->jumlah_item_terjual : 0, // Use 0 or default display value
|
'jumlah_item_terjual' => $item->jumlah_item_terjual ? (int) $item->jumlah_item_terjual : 0,
|
||||||
'berat_terjual' => $item->berat_terjual ? $this->helper->formatWeight($item->berat_terjual) : '-',
|
'berat_terjual' => $item->berat_terjual ? $this->helper->formatWeight($item->berat_terjual) : '-',
|
||||||
'pendapatan' => $item->pendapatan ? $this->helper->formatCurrency($item->pendapatan) : '-',
|
'pendapatan' => $item->pendapatan ? $this->helper->formatCurrency($item->pendapatan) : '-',
|
||||||
];
|
];
|
||||||
@ -140,17 +139,15 @@ class LaporanService
|
|||||||
$this->applyNampanFilters($nampanTerjualQuery, $params);
|
$this->applyNampanFilters($nampanTerjualQuery, $params);
|
||||||
|
|
||||||
$nampanTerjual = $nampanTerjualQuery
|
$nampanTerjual = $nampanTerjualQuery
|
||||||
->leftJoin('nampans', 'items.id_nampan', '=', 'nampans.id')
|
|
||||||
->select(
|
->select(
|
||||||
DB::raw('COALESCE(items.id_nampan, 0) as id_nampan'),
|
DB::raw('COALESCE(item_transaksis.posisi_asal, "Brankas") as nama_nampan'),
|
||||||
DB::raw('COALESCE(nampans.nama, "Brankas") as nama_nampan'),
|
|
||||||
DB::raw('COUNT(item_transaksis.id) as jumlah_item_terjual'),
|
DB::raw('COUNT(item_transaksis.id) as jumlah_item_terjual'),
|
||||||
DB::raw('COALESCE(SUM(produks.berat), 0) as berat_terjual'),
|
DB::raw('COALESCE(SUM(produks.berat), 0) as berat_terjual'),
|
||||||
DB::raw('COALESCE(SUM(item_transaksis.harga_deal), 0) as pendapatan')
|
DB::raw('COALESCE(SUM(item_transaksis.harga_deal), 0) as pendapatan')
|
||||||
)
|
)
|
||||||
->groupBy('id_nampan', 'nama_nampan')
|
->groupBy('nama_nampan')
|
||||||
->get()
|
->get()
|
||||||
->keyBy('id_nampan');
|
->keyBy('nama_nampan');
|
||||||
|
|
||||||
$totals = $this->helper->calculateTotals($nampanTerjual);
|
$totals = $this->helper->calculateTotals($nampanTerjual);
|
||||||
$semuaNampanPaginated = $this->helper->getAllNampanWithPagination($page, $perPage);
|
$semuaNampanPaginated = $this->helper->getAllNampanWithPagination($page, $perPage);
|
||||||
@ -174,7 +171,6 @@ class LaporanService
|
|||||||
$allSalesNames = $this->getAllSalesNames();
|
$allSalesNames = $this->getAllSalesNames();
|
||||||
|
|
||||||
if ($filter === 'hari') {
|
if ($filter === 'hari') {
|
||||||
// Tar kalau mau ubah eksport laporan setiap hari, param ke-3 jadiin false #Bagas
|
|
||||||
$data = $this->processLaporanHarian($allSalesNames, $page, true);
|
$data = $this->processLaporanHarian($allSalesNames, $page, true);
|
||||||
} else {
|
} else {
|
||||||
$data = $this->processLaporanBulanan($allSalesNames, $page, true);
|
$data = $this->processLaporanBulanan($allSalesNames, $page, true);
|
||||||
@ -196,17 +192,14 @@ class LaporanService
|
|||||||
return Excel::download(new RingkasanExport($data, $page), $fileName);
|
return Excel::download(new RingkasanExport($data, $page), $fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method baru untuk export per produk
|
|
||||||
public function exportPerProduk(array $params)
|
public function exportPerProduk(array $params)
|
||||||
{
|
{
|
||||||
$tanggal = $params['tanggal'];
|
$tanggal = $params['tanggal'];
|
||||||
$format = $params['format'];
|
$format = $params['format'];
|
||||||
|
|
||||||
// Get all data tanpa pagination karena untuk export
|
|
||||||
$allParams = $params;
|
$allParams = $params;
|
||||||
unset($allParams['page'], $allParams['per_page']);
|
unset($allParams['page'], $allParams['per_page']);
|
||||||
|
|
||||||
// Get data dengan semua produk (tanpa pagination)
|
|
||||||
$data = $this->getDetailPerProdukForExport($allParams);
|
$data = $this->getDetailPerProdukForExport($allParams);
|
||||||
|
|
||||||
$fileName = "laporan_per_produk_{$tanggal}_" . Carbon::now()->format('Ymd') . ".{$format}";
|
$fileName = "laporan_per_produk_{$tanggal}_" . Carbon::now()->format('Ymd') . ".{$format}";
|
||||||
@ -227,12 +220,10 @@ class LaporanService
|
|||||||
{
|
{
|
||||||
$tanggal = $params['tanggal'];
|
$tanggal = $params['tanggal'];
|
||||||
$format = $params['format'];
|
$format = $params['format'];
|
||||||
|
|
||||||
// Get all data tanpa pagination karena untuk export
|
|
||||||
$allParams = $params;
|
$allParams = $params;
|
||||||
unset($allParams['page'], $allParams['per_page']);
|
unset($allParams['page'], $allParams['per_page']);
|
||||||
|
|
||||||
// Get data dengan semua nampan (tanpa pagination)
|
|
||||||
$data = $this->getDetailPerNampanForExport($allParams);
|
$data = $this->getDetailPerNampanForExport($allParams);
|
||||||
|
|
||||||
$fileName = "laporan_per_nampan_{$tanggal}_" . Carbon::now()->format('Ymd') . ".{$format}";
|
$fileName = "laporan_per_nampan_{$tanggal}_" . Carbon::now()->format('Ymd') . ".{$format}";
|
||||||
@ -249,7 +240,6 @@ class LaporanService
|
|||||||
return Excel::download(new DetailNampanExport($data), $fileName);
|
return Excel::download(new DetailNampanExport($data), $fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method untuk get data produk tanpa pagination (untuk export)
|
|
||||||
private function getDetailPerProdukForExport(array $params)
|
private function getDetailPerProdukForExport(array $params)
|
||||||
{
|
{
|
||||||
$tanggal = Carbon::parse($params['tanggal']);
|
$tanggal = Carbon::parse($params['tanggal']);
|
||||||
@ -270,8 +260,7 @@ class LaporanService
|
|||||||
->keyBy('id_produk');
|
->keyBy('id_produk');
|
||||||
|
|
||||||
$totals = $this->helper->calculateTotals($produkTerjual);
|
$totals = $this->helper->calculateTotals($produkTerjual);
|
||||||
|
|
||||||
// Get all products without pagination
|
|
||||||
$semuaProduk = Produk::select('id', 'nama')->orderBy('nama')->get();
|
$semuaProduk = Produk::select('id', 'nama')->orderBy('nama')->get();
|
||||||
|
|
||||||
$detailItem = collect($semuaProduk)->map(function ($item) use ($produkTerjual) {
|
$detailItem = collect($semuaProduk)->map(function ($item) use ($produkTerjual) {
|
||||||
@ -302,7 +291,6 @@ class LaporanService
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method untuk get data nampan tanpa pagination (untuk export)
|
|
||||||
private function getDetailPerNampanForExport(array $params)
|
private function getDetailPerNampanForExport(array $params)
|
||||||
{
|
{
|
||||||
$tanggal = Carbon::parse($params['tanggal']);
|
$tanggal = Carbon::parse($params['tanggal']);
|
||||||
@ -311,30 +299,30 @@ class LaporanService
|
|||||||
$this->applyNampanFilters($nampanTerjualQuery, $params);
|
$this->applyNampanFilters($nampanTerjualQuery, $params);
|
||||||
|
|
||||||
$nampanTerjual = $nampanTerjualQuery
|
$nampanTerjual = $nampanTerjualQuery
|
||||||
->leftJoin('nampans', 'items.id_nampan', '=', 'nampans.id')
|
|
||||||
->select(
|
->select(
|
||||||
DB::raw('COALESCE(items.id_nampan, 0) as id_nampan'),
|
'item_transaksis.posisi_asal as posisi_asal',
|
||||||
DB::raw('COALESCE(nampans.nama, "Brankas") as nama_nampan'),
|
|
||||||
DB::raw('COUNT(item_transaksis.id) as jumlah_item_terjual'),
|
DB::raw('COUNT(item_transaksis.id) as jumlah_item_terjual'),
|
||||||
DB::raw('COALESCE(SUM(produks.berat), 0) as berat_terjual'),
|
DB::raw('COALESCE(SUM(produks.berat), 0) as berat_terjual'),
|
||||||
DB::raw('COALESCE(SUM(item_transaksis.harga_deal), 0) as pendapatan')
|
DB::raw('COALESCE(SUM(item_transaksis.harga_deal), 0) as pendapatan')
|
||||||
)
|
)
|
||||||
->groupBy('id_nampan', 'nama_nampan')
|
->groupBy('item_transaksis.posisi_asal')
|
||||||
->get()
|
->get()
|
||||||
->keyBy('id_nampan');
|
->keyBy('posisi_asal');
|
||||||
|
|
||||||
$totals = $this->helper->calculateTotals($nampanTerjual);
|
$totals = $this->helper->calculateTotals($nampanTerjual);
|
||||||
|
|
||||||
// Get all nampan without pagination
|
$semuaPosisi = DB::table('item_transaksis')
|
||||||
$semuaNampan = Nampan::select('id', 'nama')->orderBy('nama')->get();
|
->select('posisi_asal')
|
||||||
$brankasEntry = (object) ['id' => 0, 'nama' => 'Brankas'];
|
->distinct()
|
||||||
$semuaNampanCollection = $semuaNampan->prepend($brankasEntry);
|
->pluck('posisi_asal')
|
||||||
|
->sort()
|
||||||
|
->values();
|
||||||
|
|
||||||
$detailItem = $semuaNampanCollection->map(function ($item) use ($nampanTerjual) {
|
$detailItem = $semuaPosisi->map(function ($posisi) use ($nampanTerjual) {
|
||||||
if ($nampanTerjual->has($item->id)) {
|
if ($nampanTerjual->has($posisi)) {
|
||||||
$dataTerjual = $nampanTerjual->get($item->id);
|
$dataTerjual = $nampanTerjual->get($posisi);
|
||||||
return [
|
return [
|
||||||
'nama_nampan' => $item->nama,
|
'nama_nampan' => $posisi,
|
||||||
'jumlah_item_terjual' => (int) $dataTerjual->jumlah_item_terjual,
|
'jumlah_item_terjual' => (int) $dataTerjual->jumlah_item_terjual,
|
||||||
'berat_terjual' => $this->helper->formatWeight($dataTerjual->berat_terjual),
|
'berat_terjual' => $this->helper->formatWeight($dataTerjual->berat_terjual),
|
||||||
'pendapatan' => $this->helper->formatCurrency($dataTerjual->pendapatan),
|
'pendapatan' => $this->helper->formatCurrency($dataTerjual->pendapatan),
|
||||||
@ -342,7 +330,7 @@ class LaporanService
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'nama_nampan' => $item->nama,
|
'nama_nampan' => $posisi,
|
||||||
'jumlah_item_terjual' => LaporanHelper::DEFAULT_DISPLAY,
|
'jumlah_item_terjual' => LaporanHelper::DEFAULT_DISPLAY,
|
||||||
'berat_terjual' => LaporanHelper::DEFAULT_DISPLAY,
|
'berat_terjual' => LaporanHelper::DEFAULT_DISPLAY,
|
||||||
'pendapatan' => LaporanHelper::DEFAULT_DISPLAY,
|
'pendapatan' => LaporanHelper::DEFAULT_DISPLAY,
|
||||||
@ -358,6 +346,7 @@ class LaporanService
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function getAllSalesNames(): Collection
|
private function getAllSalesNames(): Collection
|
||||||
{
|
{
|
||||||
return Cache::remember('all_sales_names', self::CACHE_TTL, function () {
|
return Cache::remember('all_sales_names', self::CACHE_TTL, function () {
|
||||||
@ -377,9 +366,9 @@ class LaporanService
|
|||||||
|
|
||||||
private function buildBaseItemQuery(Carbon $carbonDate)
|
private function buildBaseItemQuery(Carbon $carbonDate)
|
||||||
{
|
{
|
||||||
|
// UBAH: Menghapus join ke tabel 'items' dan join 'produks' langsung dari 'item_transaksis'
|
||||||
return ItemTransaksi::query()
|
return ItemTransaksi::query()
|
||||||
->join('items', 'item_transaksis.id_item', '=', 'items.id')
|
->join('produks', 'item_transaksis.id_produk', '=', 'produks.id')
|
||||||
->join('produks', 'items.id_produk', '=', 'produks.id')
|
|
||||||
->join('transaksis', 'item_transaksis.id_transaksi', '=', 'transaksis.id')
|
->join('transaksis', 'item_transaksis.id_transaksi', '=', 'transaksis.id')
|
||||||
->whereDate('transaksis.created_at', $carbonDate);
|
->whereDate('transaksis.created_at', $carbonDate);
|
||||||
}
|
}
|
||||||
@ -388,14 +377,15 @@ class LaporanService
|
|||||||
{
|
{
|
||||||
if (!empty($params['sales_id'])) {
|
if (!empty($params['sales_id'])) {
|
||||||
$query->join('sales', 'transaksis.id_sales', '=', 'sales.id')
|
$query->join('sales', 'transaksis.id_sales', '=', 'sales.id')
|
||||||
->where('sales.id', $params['sales_id']);
|
->where('sales.id', $params['sales_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($params['nampan_id'])) {
|
if (isset($params['nampan_id'])) {
|
||||||
|
// UBAH: Filter berdasarkan 'item_transaksis.id_nampan'
|
||||||
if ($params['nampan_id'] == 0) {
|
if ($params['nampan_id'] == 0) {
|
||||||
$query->whereNull('items.id_nampan');
|
$query->whereNull('item_transaksis.id_nampan');
|
||||||
} else {
|
} else {
|
||||||
$query->where('items.id_nampan', $params['nampan_id']);
|
$query->where('item_transaksis.id_nampan', $params['nampan_id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,7 +398,7 @@ class LaporanService
|
|||||||
{
|
{
|
||||||
if (!empty($params['sales_id'])) {
|
if (!empty($params['sales_id'])) {
|
||||||
$query->join('sales', 'transaksis.id_sales', '=', 'sales.id')
|
$query->join('sales', 'transaksis.id_sales', '=', 'sales.id')
|
||||||
->where('sales.id', $params['sales_id']);
|
->where('sales.id', $params['sales_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($params['produk_id'])) {
|
if (!empty($params['produk_id'])) {
|
||||||
@ -419,4 +409,4 @@ class LaporanService
|
|||||||
$query->where('transaksis.nama_pembeli', 'like', "%{$params['nama_pembeli']}%");
|
$query->where('transaksis.nama_pembeli', 'like', "%{$params['nama_pembeli']}%");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\Produk;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,9 +18,8 @@ class ItemFactory extends Factory
|
|||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id_produk' => \App\Models\Produk::factory(),
|
'id_produk' => Produk::inRandomOrder()->first()->id,
|
||||||
'id_nampan' => null,
|
'id_nampan' => null,
|
||||||
'is_sold' => false,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\Item;
|
use App\Models\Item;
|
||||||
|
use App\Models\Produk;
|
||||||
use App\Models\Transaksi;
|
use App\Models\Transaksi;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ class ItemTransaksiFactory extends Factory
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id_transaksi' => Transaksi::factory(),
|
'id_transaksi' => Transaksi::factory(),
|
||||||
'id_item' => Item::factory(),
|
'id_produk' => Produk::factory(),
|
||||||
'harga_deal' => $this->faker->randomFloat(2, 100000, 5000000),
|
'harga_deal' => $this->faker->randomFloat(2, 100000, 5000000),
|
||||||
'created_at' => now(),
|
'created_at' => now(),
|
||||||
];
|
];
|
||||||
|
|||||||
@ -15,7 +15,6 @@ return new class extends Migration
|
|||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('id_produk')->constrained('produks')->cascadeOnDelete();
|
$table->foreignId('id_produk')->constrained('produks')->cascadeOnDelete();
|
||||||
$table->foreignId('id_nampan')->nullable()->constrained('nampans');
|
$table->foreignId('id_nampan')->nullable()->constrained('nampans');
|
||||||
$table->boolean('is_sold')->default(false);
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ return new class extends Migration
|
|||||||
Schema::create('item_transaksis', function (Blueprint $table) {
|
Schema::create('item_transaksis', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('id_transaksi')->constrained('transaksis')->onDelete('cascade');
|
$table->foreignId('id_transaksi')->constrained('transaksis')->onDelete('cascade');
|
||||||
$table->foreignId('id_item')->constrained('items');
|
$table->foreignId('id_produk')->constrained('produks');
|
||||||
$table->double('harga_deal');
|
$table->double('harga_deal');
|
||||||
$table->string('posisi_asal', 100);
|
$table->string('posisi_asal', 100);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
|||||||
@ -49,32 +49,59 @@ class DatabaseSeeder extends Seeder
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Produk::factory(10)->create()->each(function ($produk) {
|
// Produk::factory(10)->create()->each(function ($produk) {
|
||||||
// setiap produk punya 1-3 foto
|
// // setiap produk punya 1-3 foto
|
||||||
$jumlah_foto = rand(1, 3);
|
// $jumlah_foto = rand(1, 3);
|
||||||
$fotoData = [];
|
// $fotoData = [];
|
||||||
for ($i = 0; $i < $jumlah_foto; $i++) {
|
// for ($i = 0; $i < $jumlah_foto; $i++) {
|
||||||
$fotoData[] = [
|
// $fotoData[] = [
|
||||||
// 'url' => 'https://random-image-pepebigotes.vercel.app/api/random-image'
|
// // 'url' => 'https://random-image-pepebigotes.vercel.app/api/random-image'
|
||||||
'url' => 'https://static.promediateknologi.id/crop/0x0:0x0/0x0/webp/photo/p2/255/2024/12/10/Screenshot_2024-12-10-11-50-18-88_1c337646f29875672b5a61192b9010f9-1-1282380831.jpg'
|
// 'url' => 'https://static.promediateknologi.id/crop/0x0:0x0/0x0/webp/photo/p2/255/2024/12/10/Screenshot_2024-12-10-11-50-18-88_1c337646f29875672b5a61192b9010f9-1-1282380831.jpg'
|
||||||
];
|
// ];
|
||||||
}
|
// }
|
||||||
$produk->foto()->createMany($fotoData);
|
// $produk->foto()->createMany($fotoData);
|
||||||
|
|
||||||
$jumlah_item = rand(1, 20);
|
// $jumlah_item = rand(1, 20);
|
||||||
Item::factory($jumlah_item)->create([
|
// Item::factory($jumlah_item)->create([
|
||||||
'id_produk' => $produk->id,
|
// 'id_produk' => $produk->id,
|
||||||
'is_sold' => false,
|
// ]);
|
||||||
]);
|
// });
|
||||||
});
|
|
||||||
|
|
||||||
// 30% peluang item masuk nampan, sisanya di brankas
|
$produk1 = Produk::factory()->create([
|
||||||
|
'nama'=>'Gelang serut daun shimmer mp (mas putih)',
|
||||||
|
'id_kategori'=>Kategori::find(2),
|
||||||
|
'berat'=>1.4,
|
||||||
|
'kadar'=>8,
|
||||||
|
'harga_per_gram'=>900000,
|
||||||
|
'harga_jual'=>1260000,
|
||||||
|
]);
|
||||||
|
$produk1->foto()->create([
|
||||||
|
'id_produk'=>$produk1->id,
|
||||||
|
'url'=>'https://i.imgur.com/eGYHzvw.jpeg'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$produk2 = Produk::factory()->create([
|
||||||
|
'nama'=>'Gelang rantai 5 buah clover merah',
|
||||||
|
'id_kategori'=>Kategori::find(2),
|
||||||
|
'berat'=>3.6,
|
||||||
|
'kadar'=>8,
|
||||||
|
'harga_per_gram'=>850000,
|
||||||
|
'harga_jual'=>3060000,
|
||||||
|
]);
|
||||||
|
$produk2->foto()->create([
|
||||||
|
'id_produk'=>$produk2->id,
|
||||||
|
'url'=>'https://i.imgur.com/UjQzYoE.jpeg'
|
||||||
|
]);
|
||||||
|
|
||||||
|
Item::factory(500)->create();
|
||||||
|
|
||||||
|
// 75% peluang item masuk nampan, sisanya di brankas
|
||||||
$nampans = Nampan::all()->pluck('id')->toArray();
|
$nampans = Nampan::all()->pluck('id')->toArray();
|
||||||
$jumlahNampan = count($nampans);
|
$jumlahNampan = count($nampans);
|
||||||
$counter = 0;
|
$counter = 0;
|
||||||
|
|
||||||
foreach (Item::all() as $item) {
|
foreach (Item::all() as $item) {
|
||||||
if (rand(1, 100) <= 30) {
|
if (rand(1, 100) <= 75) {
|
||||||
$item->update([
|
$item->update([
|
||||||
'id_nampan' => $nampans[$counter % $jumlahNampan],
|
'id_nampan' => $nampans[$counter % $jumlahNampan],
|
||||||
]);
|
]);
|
||||||
@ -82,21 +109,18 @@ class DatabaseSeeder extends Seeder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Transaksi::factory(40)->create()->each(function ($transaksi) {
|
Transaksi::factory(250)->create()->each(function ($transaksi) {
|
||||||
$jumlah_item = rand(1, 2);
|
$jumlah_item = rand(1, 2);
|
||||||
$items = Item::where('is_sold', false)->inRandomOrder()->limit($jumlah_item)->get();
|
$items = Item::with('produk')->inRandomOrder()->limit($jumlah_item)->get();
|
||||||
if ($items->isEmpty()) return;
|
if ($items->isEmpty()) return;
|
||||||
$total_harga = $transaksi->total_harga;
|
$total_harga = $transaksi->total_harga;
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
$transaksi->itemTransaksi()->create([
|
$transaksi->itemTransaksi()->create([
|
||||||
'id_item' => $item->id,
|
'id_produk' => $item->produk->id,
|
||||||
'harga_deal' => $item->produk->harga_jual,
|
'harga_deal' => $item->produk->harga_jual,
|
||||||
'posisi_asal' => $item->id_nampan ? 'Nampan ' . $item->nampan->nama : 'Brankas',
|
'posisi_asal' => $item->id_nampan ? $item->nampan->nama : 'Brankas',
|
||||||
]);
|
|
||||||
$item->update([
|
|
||||||
'id_nampan' => null,
|
|
||||||
'is_sold' => true,
|
|
||||||
]);
|
]);
|
||||||
|
$item->delete();
|
||||||
$total_harga += $item->produk->harga_jual;
|
$total_harga += $item->produk->harga_jual;
|
||||||
}
|
}
|
||||||
$transaksi->update(['total_harga' => $total_harga]);
|
$transaksi->update(['total_harga' => $total_harga]);
|
||||||
|
|||||||
@ -371,6 +371,7 @@ const fetchData = async (page = 1) => {
|
|||||||
total: response.data.nampan ? response.data.nampan.length : 0,
|
total: response.data.nampan ? response.data.nampan.length : 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
console.log('Data laporan nampan berhasil diambil:', data.value);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Gagal mengambil data laporan nampan:', error);
|
console.error('Gagal mengambil data laporan nampan:', error);
|
||||||
data.value = null;
|
data.value = null;
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
message="Yakin ingin menghapus item ini?" @confirm="hapusPesanan" @cancel="closeDeleteModal" />
|
message="Yakin ingin menghapus item ini?" @confirm="hapusPesanan" @cancel="closeDeleteModal" />
|
||||||
|
|
||||||
<!-- ==== TAMBAHAN: Struk Overlay ==== -->
|
<!-- ==== TAMBAHAN: Struk Overlay ==== -->
|
||||||
<StrukOverlay v-if="showStruk" :isOpen="showStruk" :pesanan="pesanan" :total="total" @close="closeStruk"/>
|
<StrukOverlay v-if="showStruk" :isOpen="showStruk" :pesanan="pesanan" :total="total" @close="closeStruk" />
|
||||||
<!-- ==== END TAMBAHAN ==== -->
|
<!-- ==== END TAMBAHAN ==== -->
|
||||||
|
|
||||||
<div class="p-2 sm:p-4">
|
<div class="p-2 sm:p-4">
|
||||||
@ -90,7 +90,7 @@
|
|||||||
{{ item.produk.nama }}
|
{{ item.produk.nama }}
|
||||||
</td>
|
</td>
|
||||||
<td class="border border-B p-2 truncate max-w-[80px]">
|
<td class="border border-B p-2 truncate max-w-[80px]">
|
||||||
{{ item.posisi ? item.posisi : "Brankas" }}
|
{{ item.nampan ? item.nampan.nama : "Brankas" }}
|
||||||
</td>
|
</td>
|
||||||
<td class="border border-B p-2 whitespace-nowrap">
|
<td class="border border-B p-2 whitespace-nowrap">
|
||||||
Rp{{ item.harga_deal.toLocaleString() }}
|
Rp{{ item.harga_deal.toLocaleString() }}
|
||||||
@ -150,14 +150,15 @@ const inputItem = async () => {
|
|||||||
item.value = response.data;
|
item.value = response.data;
|
||||||
hargaJual.value = item.value.produk.harga_jual;
|
hargaJual.value = item.value.produk.harga_jual;
|
||||||
|
|
||||||
|
console.log(item.value);
|
||||||
|
|
||||||
if (item.value.is_sold) {
|
if (item.value.is_sold) {
|
||||||
throw new Error("Item sudah terjual");
|
throw new Error("Item sudah terjual");
|
||||||
}
|
}
|
||||||
if (pesanan.value.some((p) => p.id === item.value.id)) {
|
if (pesanan.value.some((p) => p.id === item.value.id)) {
|
||||||
throw new Error("Item sedang dipesan");
|
throw new Error("Item sedang dipesan");
|
||||||
}
|
}
|
||||||
info.value = `Item dipilih: ${item.value.produk.nama} dari ${item.value.posisi ? item.value.posisi : "Brankas"
|
info.value = `Item dipilih: ${item.value.produk.nama} dari ${item.value.nampan ? 'Nampan ' + item.value.nampan.nama : "Brankas"}`;
|
||||||
}`;
|
|
||||||
|
|
||||||
infoTimeout = setTimeout(() => {
|
infoTimeout = setTimeout(() => {
|
||||||
info.value = "";
|
info.value = "";
|
||||||
@ -194,18 +195,10 @@ const tambahItem = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pesanan.value.length >= 2) {
|
|
||||||
error.value = "Maksimal hanya bisa memesan 2 item.";
|
|
||||||
clearTimeout(errorTimeout);
|
|
||||||
errorTimeout = setTimeout(() => {
|
|
||||||
error.value = "";
|
|
||||||
}, 3000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// harga deal
|
// harga deal
|
||||||
item.value.kode_item = kodeItem.value;
|
item.value.kode_item = Number(kodeItem.value);
|
||||||
item.value.harga_deal = Number(hargaJual.value);
|
item.value.harga_deal = Number(hargaJual.value);
|
||||||
|
item.value.posisi = item.value.nampan ? item.value.nampan.nama : "Brankas";
|
||||||
|
|
||||||
pesanan.value.push(item.value);
|
pesanan.value.push(item.value);
|
||||||
|
|
||||||
|
|||||||
@ -78,7 +78,7 @@
|
|||||||
</template>
|
</template>
|
||||||
{{ item.produk?.nama || '' }}
|
{{ item.produk?.nama || '' }}
|
||||||
</td>
|
</td>
|
||||||
<td class="border-r border-D">{{ item.posisi || '' }}</td>
|
<td class="border-r border-D">{{ item.nampan?.nama || 'Brankas' }}</td>
|
||||||
<td class="border-r border-D">
|
<td class="border-r border-D">
|
||||||
<span v-if="item.produk?.berat">{{ item.produk.berat }}g</span>
|
<span v-if="item.produk?.berat">{{ item.produk.berat }}g</span>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@ -42,7 +42,7 @@
|
|||||||
<button class="p-1 rounded" @click="emit('edit', tray)">
|
<button class="p-1 rounded" @click="emit('edit', tray)">
|
||||||
<i class="fa fa-pen fa-sm text-yellow-500 hover:text-yellow-600"></i>
|
<i class="fa fa-pen fa-sm text-yellow-500 hover:text-yellow-600"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="p-1 rounded" @click="emit('delete', tray.id)">
|
<button class="p-1 rounded" @click="emit('delete', tray)">
|
||||||
<i class="fa fa-trash fa-sm text-red-500 hover:text-red-600"></i>
|
<i class="fa fa-trash fa-sm text-red-500 hover:text-red-600"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user