657 lines
35 KiB
PHP
657 lines
35 KiB
PHP
@extends(auth()->user()->role == 'admin' ? 'layouts.admin' : 'layouts.app')
|
|
|
|
@section('content')
|
|
<style>
|
|
.page-header {
|
|
background: linear-gradient(90deg, #ff8a00 0%, #ff5e00 100%);
|
|
color: white;
|
|
padding: 30px;
|
|
border-radius: 15px;
|
|
margin-top: 20px;
|
|
margin-bottom: 30px;
|
|
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
.page-header h1 {
|
|
font-weight: 700;
|
|
font-size: 2rem;
|
|
margin-bottom: 5px;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.page-header h1 i {
|
|
margin-right: 15px;
|
|
font-size: 1.8rem;
|
|
}
|
|
.page-header p {
|
|
opacity: 0.9;
|
|
margin-bottom: 0;
|
|
}
|
|
.custom-card {
|
|
border-radius: 15px;
|
|
border: none;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
|
|
overflow: hidden;
|
|
}
|
|
.btn-custom {
|
|
border-radius: 10px;
|
|
padding: 8px 20px;
|
|
font-weight: 600;
|
|
transition: all 0.3s;
|
|
}
|
|
.btn-custom:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
|
|
}
|
|
.header-btn {
|
|
background: rgba(255,255,255,0.2);
|
|
border: 1px solid rgba(255,255,255,0.4);
|
|
color: white;
|
|
flex: 0 0 auto;
|
|
}
|
|
.header-btn:hover {
|
|
background: white;
|
|
color: #ff5e00;
|
|
}
|
|
/* Responsive adjustments */
|
|
@media (max-width: 768px) {
|
|
.page-header { padding: 20px; }
|
|
.page-header .d-flex.justify-content-between {
|
|
flex-direction: column;
|
|
align-items: flex-start !important;
|
|
gap: 15px;
|
|
}
|
|
.header-btn { width: auto; }
|
|
}
|
|
.table thead {
|
|
background-color: #f8f9fa;
|
|
}
|
|
.table thead th {
|
|
border-top: none;
|
|
text-transform: uppercase;
|
|
font-size: 0.8rem;
|
|
letter-spacing: 1px;
|
|
color: #757575;
|
|
}
|
|
.badge-makanan { background-color: #e8f5e9; color: #2e7d32; }
|
|
.badge-minuman { background-color: #e3f2fd; color: #1565c0; }
|
|
.badge-snack { background-color: #fff3e0; color: #ef6c00; }
|
|
</style>
|
|
<div class="container-fluid px-4">
|
|
<!-- Vibrant Header Area -->
|
|
<div class="page-header shadow">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h1><i class="fas fa-utensils"></i> Manajemen Produk</h1>
|
|
<p>Kelola menu makanan dan minuman pada semua cabang</p>
|
|
</div>
|
|
<div class="d-flex align-items-center">
|
|
@if(auth()->user()->role !== 'admin')
|
|
<button type="button" class="btn btn-custom header-btn" data-toggle="modal" data-target="#tambahProdukModal">
|
|
<i class="fas fa-plus mr-2"></i> Tambah Menu Baru
|
|
</button>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Alert Success -->
|
|
@if(session('success'))
|
|
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
|
<i class="fas fa-check-circle mr-2"></i> {{ session('success') }}
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- Alert Error -->
|
|
@if($errors->has('duplicate_error'))
|
|
<div class="alert alert-danger alert-dismissible fade show shadow-sm" role="alert" style="border-left: 5px solid #dc3545;">
|
|
<i class="fas fa-exclamation-triangle mr-2"></i> {{ $errors->first('duplicate_error') }}
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
@endif
|
|
|
|
@if(auth()->user()->role == 'admin')
|
|
<ul class="nav nav-tabs mb-4 font-weight-bold" id="produkTab" role="tablist">
|
|
<li class="nav-item">
|
|
<a class="nav-link active" id="produk-tab" data-toggle="tab" href="#produk" role="tab"><i class="fas fa-boxes mr-2"></i>Daftar Produk</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" id="bahan-baku-tab" data-toggle="tab" href="#bahan-baku" role="tab"><i class="fas fa-leaf mr-2"></i>Manajemen Bahan Baku</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content" id="produkTabContent">
|
|
<div class="tab-pane fade show active" id="produk" role="tabpanel">
|
|
@endif
|
|
|
|
<div class="modal fade" id="tambahProdukModal" tabindex="-1" role="dialog" aria-labelledby="tambahProdukModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg" role="document">
|
|
<div class="modal-content custom-card">
|
|
<div class="modal-header bg-orange text-white" style="background: linear-gradient(90deg, #ff8a00 0%, #ff5e00 100%); border: none;">
|
|
<h5 class="modal-title font-weight-bold" id="tambahProdukModalLabel">
|
|
<i class="fas fa-plus-circle mr-2"></i> Tambah Produk Baru
|
|
</h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<form action="/produk" method="POST" enctype="multipart/form-data" id="addProductForm">
|
|
@csrf
|
|
<div class="modal-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="name">🏷️ Nama Produk</label>
|
|
<input type="text" class="form-control" id="name" name="name" required placeholder="Masukkan nama produk">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="category">📋 Kategori</label>
|
|
<select class="form-control" id="category" name="category" required>
|
|
<option value="">Pilih Kategori</option>
|
|
<option value="makanan">🍛 Makanan</option>
|
|
<option value="minuman">☕ Minuman</option>
|
|
<option value="snack">🍿 Snack</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="purchase_price">🛒 Harga Beli (Rp)</label>
|
|
<input type="number" class="form-control" id="purchase_price" name="purchase_price" min="1000" required placeholder="1000" oninput="if(this.value.length === 1 && this.value === '0') this.value = '';">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="selling_price">💰 Harga Jual (Rp)</label>
|
|
<input type="number" class="form-control" id="selling_price" name="selling_price" min="1000" required placeholder="1000" oninput="if(this.value.length === 1 && this.value === '0') this.value = '';">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="image">🖼️ Gambar Produk</label>
|
|
<input type="file" class="form-control-file" id="image" name="image" accept="image/*">
|
|
<small class="form-text text-muted">Pilih gambar produk (opsional)</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr>
|
|
<h6 class="font-weight-bold"><i class="fas fa-list-alt text-warning mr-2"></i>Resep / Bill of Materials (Opsional)</h6>
|
|
<small class="text-muted d-block mb-2">Tambahkan bahan baku yang dibutuhkan untuk 1 porsi produk ini. Kosongkan jika produk ini tidak membutuhkan bahan baku.</small>
|
|
<div id="recipe-container">
|
|
<div class="recipe-row row align-items-end mb-2">
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-0">
|
|
<label class="small">Bahan Baku</label>
|
|
<select class="form-control form-control-sm" name="recipes[0][raw_material_id]">
|
|
<option value="">-- Pilih Bahan Baku --</option>
|
|
@foreach($rawMaterials as $rm)
|
|
<option value="{{ $rm->id }}">{{ $rm->name }} ({{ $rm->unit }})</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group mb-0">
|
|
<label class="small">Jumlah Dibutuhkan</label>
|
|
<input type="text" class="form-control form-control-sm" name="recipes[0][quantity_needed]" placeholder="Contoh: 300, 0.5, 300 ml">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<button type="button" class="btn btn-sm btn-danger btn-block" onclick="this.closest('.recipe-row').remove()"><i class="fas fa-trash"></i></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<button type="button" class="btn btn-sm btn-outline-primary mt-2" onclick="addRecipeRow('recipe-container')">
|
|
<i class="fas fa-plus"></i> Tambah Bahan Baku
|
|
</button>
|
|
</div>
|
|
<div class="modal-footer border-0">
|
|
<button type="button" class="btn btn-custom btn-secondary" data-dismiss="modal">
|
|
<i class="fas fa-times"></i> Batal
|
|
</button>
|
|
<button type="submit" class="btn btn-custom" style="background-color: #ff5e00; color: white;">
|
|
<i class="fas fa-save"></i> Simpan Produk
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
@if(auth()->user()->role == 'admin')
|
|
<div class="card custom-card">
|
|
<div class="card-header bg-white py-3 border-0 d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0 font-weight-bold text-dark">
|
|
<i class="fas fa-boxes mr-2 text-warning"></i>
|
|
Stok Produk:
|
|
<span class="text-warning">{{ $selectedBranch }}</span>
|
|
</h5>
|
|
<form method="GET" action="/produk" class="form-inline mb-0" id="branchFilterForm">
|
|
@if(request('search'))
|
|
<input type="hidden" name="search" value="{{ request('search') }}">
|
|
@endif
|
|
<label class="mr-2 font-weight-bold"><i class="fas fa-filter mr-1"></i> Filter Cabang:</label>
|
|
<select name="branch" class="form-control form-control-sm" onchange="this.form.submit()" style="min-width:160px;">
|
|
<option value="Total Gabungan" {{ $selectedBranch == 'Total Gabungan' ? 'selected' : '' }}>🏢 Total Gabungan</option>
|
|
@foreach($branches as $branch)
|
|
<option value="{{ $branch->name }}" {{ $selectedBranch == $branch->name ? 'selected' : '' }}>📍 {{ $branch->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</form>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div id="product-table-container">
|
|
@include('partials.table_produk', ['products' => $products, 'readonly' => true, 'selectedBranch' => $selectedBranch])
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@else
|
|
<!-- KARYAWAN VIEW -->
|
|
<div class="card custom-card">
|
|
<div class="card-header bg-white py-3">
|
|
<h5 class="mb-0 font-weight-bold font-weight-bold"><i class="fas fa-list-ul mr-2 text-warning"></i> Daftar Katalog Produk - {{ Auth::user()->branch }}</h5>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div id="product-table-container">
|
|
@include('partials.table_produk', ['products' => $products])
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
@if(auth()->user()->role == 'admin')
|
|
</div> <!-- End of Produk Tab -->
|
|
|
|
<!-- Bahan Baku Tab -->
|
|
<div class="tab-pane fade" id="bahan-baku" role="tabpanel">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<h5 class="mb-0 font-weight-bold"><i class="fas fa-boxes text-warning mr-2"></i>Daftar Bahan Baku & Stok Saat Ini</h5>
|
|
@if(auth()->user()->role !== 'admin')
|
|
<button class="btn btn-custom" style="background-color: #ff5e00; color: white;" data-toggle="modal" data-target="#addRawMaterialModal">
|
|
<i class="fas fa-plus mr-1"></i> Tambah Bahan Baku
|
|
</button>
|
|
@endif
|
|
</div>
|
|
|
|
@if(auth()->user()->role == 'admin')
|
|
<div class="card custom-card mb-3">
|
|
<div class="card-body py-3">
|
|
<form method="GET" action="/produk" class="form-inline mb-0">
|
|
<input type="hidden" name="tab" value="bahan-baku">
|
|
<input type="hidden" name="branch" value="{{ $selectedBranch }}">
|
|
<label class="mr-2 font-weight-bold"><i class="fas fa-filter mr-1"></i> Filter Cabang:</label>
|
|
<select name="raw_material_branch" class="form-control form-control-sm" onchange="this.form.submit()" style="min-width:180px;">
|
|
<option value="Total Gabungan" {{ (isset($selectedRawMaterialBranch) && $selectedRawMaterialBranch == 'Total Gabungan') ? 'selected' : '' }}>🏢 Total Gabungan</option>
|
|
@foreach($branches as $branch)
|
|
<option value="{{ $branch->name }}" {{ (isset($selectedRawMaterialBranch) && $selectedRawMaterialBranch == $branch->name) ? 'selected' : '' }}>📍 {{ $branch->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="card custom-card mb-4">
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle mb-0">
|
|
<thead class="bg-light">
|
|
<tr>
|
|
<th width="70" class="text-center">#</th>
|
|
<th>Nama Bahan Baku</th>
|
|
@if(auth()->user()->role == 'admin')
|
|
<th width="140" class="text-center">Cabang</th>
|
|
@endif
|
|
<th width="150" class="text-center">Satuan</th>
|
|
<th width="150" class="text-right">Total Stok</th>
|
|
@if(auth()->user()->role !== 'admin')
|
|
<th width="150" class="text-center">Aksi</th>
|
|
@endif
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach($rawMaterials as $rm)
|
|
<tr>
|
|
<td class="text-center text-muted font-weight-bold">{{ $loop->iteration }}</td>
|
|
<td class="font-weight-bold">{{ $rm->name }}</td>
|
|
@if(auth()->user()->role == 'admin')
|
|
<td class="text-center"><span class="badge badge-info px-3 py-2">{{ $rm->branch ?? '-' }}</span></td>
|
|
@endif
|
|
<td class="text-center"><span class="badge badge-secondary px-3 py-2">{{ $rm->unit }}</span></td>
|
|
<td class="text-right font-weight-bold" style="color: #ff5e00;">
|
|
{{ number_format($rm->stock_quantity, 0, ',', '.') }} {{ $rm->unit }}
|
|
</td>
|
|
@if(auth()->user()->role !== 'admin')
|
|
<td class="text-center">
|
|
<button class="btn btn-sm btn-link text-warning" title="Edit" data-toggle="modal" data-target="#editModal{{ $rm->id }}">
|
|
<i class="fas fa-edit fa-lg"></i>
|
|
</button>
|
|
<button class="btn btn-sm btn-link text-danger" title="Hapus" onclick="if(confirm('Yakin ingin menghapus bahan baku ini?')) document.getElementById('delete-form-{{ $rm->id }}').submit();">
|
|
<i class="fas fa-trash fa-lg"></i>
|
|
</button>
|
|
<form id="delete-form-{{ $rm->id }}" action="/bahan-baku/{{ $rm->id }}" method="POST" style="display: none;">
|
|
@csrf
|
|
@method('DELETE')
|
|
</form>
|
|
</td>
|
|
@endif
|
|
</tr>
|
|
|
|
@if(auth()->user()->role !== 'admin')
|
|
<!-- Edit Modal -->
|
|
<div class="modal fade" id="editModal{{ $rm->id }}" tabindex="-1" role="dialog" aria-hidden="true">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content border-0 shadow">
|
|
<div class="modal-header bg-light border-0">
|
|
<h5 class="modal-title font-weight-bold text-dark"><i class="fas fa-edit text-warning mr-2"></i>Edit Bahan Baku</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<form action="/bahan-baku/{{ $rm->id }}" method="POST">
|
|
@csrf
|
|
@method('PUT')
|
|
<div class="modal-body">
|
|
<div class="form-group">
|
|
<label class="font-weight-bold">Nama Bahan Baku</label>
|
|
<input type="text" name="name" class="form-control bg-light" value="{{ $rm->name }}" required>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="font-weight-bold">Satuan Dasar</label>
|
|
<select name="unit" class="form-control bg-light" required>
|
|
@php $units = ['Gram','Kilogram','Mililiter','Liter','Pcs','Botol','Lembar','Sendok Makan','Sendok Teh']; @endphp
|
|
@foreach($units as $u)
|
|
<option value="{{ $u }}" {{ $rm->unit == $u ? 'selected' : '' }}>{{ $u }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 bg-light">
|
|
<button type="button" class="btn btn-secondary font-weight-bold" data-dismiss="modal">Batal</button>
|
|
<button type="submit" class="btn btn-primary font-weight-bold"><i class="fas fa-save mr-1"></i> Simpan Perubahan</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
@endforeach
|
|
@if(isset($rawMaterials) && $rawMaterials->isEmpty())
|
|
<tr>
|
|
<td colspan="5" class="text-center py-4 text-muted">Belum ada bahan baku yang terdaftar.</td>
|
|
</tr>
|
|
@endif
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@if(auth()->user()->role !== 'admin')
|
|
<!-- Add Raw Material Modal -->
|
|
<div class="modal fade" id="addRawMaterialModal" tabindex="-1" role="dialog" aria-hidden="true">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content border-0 shadow">
|
|
<div class="modal-header bg-light border-0">
|
|
<h5 class="modal-title font-weight-bold text-dark"><i class="fas fa-plus-circle text-primary mr-2"></i>Tambah Bahan Baku</h5>
|
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<form action="/bahan-baku" method="POST">
|
|
@csrf
|
|
<div class="modal-body">
|
|
<div class="form-group">
|
|
<label class="font-weight-bold">Nama Bahan Baku</label>
|
|
<input type="text" name="name" class="form-control bg-light" placeholder="Misal: Kopi Bubuk" required>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="font-weight-bold">Satuan Dasar</label>
|
|
<select name="unit" class="form-control bg-light" required>
|
|
<option value="">-- Pilih Satuan --</option>
|
|
<option value="Gram">Gram</option>
|
|
<option value="Kilogram">Kilogram</option>
|
|
<option value="Mililiter">Mililiter</option>
|
|
<option value="Liter">Liter</option>
|
|
<option value="Pcs">Pcs</option>
|
|
<option value="Botol">Botol</option>
|
|
<option value="Lembar">Lembar</option>
|
|
<option value="Sendok Makan">Sendok Makan</option>
|
|
<option value="Sendok Teh">Sendok Teh</option>
|
|
</select>
|
|
<small class="form-text text-warning mt-2"><i class="fas fa-info-circle mr-1"></i>Gunakan satuan terkecil agar mudah dibuat resepnya. Misal beli per Kg, tapi resep butuh <strong>Gram</strong>.</small>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0 bg-light">
|
|
<button type="button" class="btn btn-secondary font-weight-bold" data-dismiss="modal">Batal</button>
|
|
<button type="submit" class="btn btn-primary font-weight-bold"><i class="fas fa-save mr-1"></i> Simpan</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
</div> <!-- End of Bahan Baku Tab -->
|
|
</div> <!-- End of Tab Content -->
|
|
@endif
|
|
</div>
|
|
|
|
<div class="modal fade" id="editProdukModal" tabindex="-1" role="dialog" aria-labelledby="editProdukModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg" role="document">
|
|
<div class="modal-content custom-card">
|
|
<div class="modal-header text-white" style="background: linear-gradient(90deg, #ff8a00 0%, #ff5e00 100%); border: none;">
|
|
<h5 class="modal-title font-weight-bold" id="editProdukModalLabel">
|
|
<i class="fas fa-edit mr-2"></i> Edit Produk
|
|
</h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<form id="editProductForm" method="POST" enctype="multipart/form-data">
|
|
@csrf
|
|
@method('PUT')
|
|
<div class="modal-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="edit_name">🏷️ Nama Produk</label>
|
|
<input type="text" class="form-control" id="edit_name" name="name" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="edit_category">📋 Kategori</label>
|
|
<select class="form-control" id="edit_category" name="category" required>
|
|
<option value="makanan">🍛 Makanan</option>
|
|
<option value="minuman">☕ Minuman</option>
|
|
<option value="snack">🍿 Snack</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="edit_purchase_price">🛒 Harga Beli (Rp)</label>
|
|
<input type="number" class="form-control" id="edit_purchase_price" name="purchase_price" min="1000" required placeholder="1000" oninput="if(this.value.length === 1 && this.value === '0') this.value = '';">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="edit_selling_price">💰 Harga Jual (Rp)</label>
|
|
<input type="number" class="form-control" id="edit_selling_price" name="selling_price" min="1000" required placeholder="1000" oninput="if(this.value.length === 1 && this.value === '0') this.value = '';">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="edit_image">🖼️ Gambar Produk (Opsional)</label>
|
|
<input type="file" class="form-control-file" id="edit_image" name="image" accept="image/*">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr>
|
|
<h6 class="font-weight-bold"><i class="fas fa-list-alt text-warning mr-2"></i>Resep / Bill of Materials (Opsional)</h6>
|
|
<small class="text-muted d-block mb-2">Tambahkan bahan baku yang dibutuhkan untuk 1 porsi produk ini. Resep lama akan dihapus dan diganti dengan yang baru (jika diisi).</small>
|
|
<div id="edit-recipe-container">
|
|
<!-- Filled by JS -->
|
|
</div>
|
|
<button type="button" class="btn btn-sm btn-outline-primary mt-2" onclick="addRecipeRow('edit-recipe-container')">
|
|
<i class="fas fa-plus"></i> Tambah Bahan Baku
|
|
</button>
|
|
</div>
|
|
<div class="modal-footer border-0">
|
|
<button type="button" class="btn btn-custom btn-secondary" data-dismiss="modal">Batal</button>
|
|
<button type="submit" class="btn btn-custom" style="background-color: #ff5e00; color: white;">Simpan Perubahan</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@push('scripts')
|
|
<script>
|
|
let recipeIndex = 1;
|
|
const rawMaterials = @json($rawMaterials);
|
|
|
|
function addRecipeRow(containerId, data = null) {
|
|
const container = document.getElementById(containerId);
|
|
if (!container) return;
|
|
|
|
let rmOptions = '<option value="">-- Pilih Bahan Baku --</option>';
|
|
rawMaterials.forEach(rm => {
|
|
let selected = (data && data.raw_material_id == rm.id) ? 'selected' : '';
|
|
rmOptions += `<option value="${rm.id}" ${selected}>${rm.name} (${rm.unit})</option>`;
|
|
});
|
|
|
|
const quantity = data ? data.quantity_needed : '';
|
|
|
|
const rowHtml = `
|
|
<div class="recipe-row row align-items-end mb-2">
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-0">
|
|
<label class="small">Bahan Baku</label>
|
|
<select class="form-control form-control-sm" name="recipes[${recipeIndex}][raw_material_id]" required>
|
|
${rmOptions}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group mb-0">
|
|
<label class="small">Jumlah Dibutuhkan</label>
|
|
<input type="text" class="form-control form-control-sm" name="recipes[${recipeIndex}][quantity_needed]" value="${quantity}" placeholder="Contoh: 300, 0.5, 300 ml" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<button type="button" class="btn btn-sm btn-danger btn-block" onclick="this.closest('.recipe-row').remove()"><i class="fas fa-trash"></i></button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
container.insertAdjacentHTML('beforeend', rowHtml);
|
|
recipeIndex++;
|
|
}
|
|
|
|
function editProduct(product, recipes) {
|
|
const form = document.getElementById('editProductForm');
|
|
const nameField = document.getElementById('edit_name');
|
|
const categoryField = document.getElementById('edit_category');
|
|
const purchaseField = document.getElementById('edit_purchase_price');
|
|
const sellingField = document.getElementById('edit_selling_price');
|
|
const recipeContainer = document.getElementById('edit-recipe-container');
|
|
|
|
if (!form || !nameField || !categoryField || !purchaseField || !sellingField || !recipeContainer) return;
|
|
|
|
form.action = '/produk/' + product.id;
|
|
nameField.value = product.name || '';
|
|
categoryField.value = product.category || '';
|
|
purchaseField.value = product.purchase_price || 0;
|
|
sellingField.value = product.selling_price || 0;
|
|
|
|
recipeContainer.innerHTML = '';
|
|
if (recipes && recipes.length > 0) {
|
|
recipes.forEach(recipe => {
|
|
addRecipeRow('edit-recipe-container', recipe);
|
|
});
|
|
} else {
|
|
addRecipeRow('edit-recipe-container');
|
|
}
|
|
|
|
$('#editProdukModal').modal('show');
|
|
}
|
|
|
|
window.editProduct = editProduct;
|
|
|
|
$(document).ready(function() {
|
|
$(document).on('click', '.edit-product-btn', function() {
|
|
var product = $(this).data('product');
|
|
var recipes = $(this).data('recipes');
|
|
|
|
if (typeof recipes === 'string') {
|
|
try {
|
|
recipes = JSON.parse(recipes);
|
|
} catch (e) {
|
|
recipes = [];
|
|
}
|
|
}
|
|
|
|
editProduct(product || {}, recipes || []);
|
|
});
|
|
|
|
const addProductForm = document.getElementById('addProductForm');
|
|
if (addProductForm) {
|
|
addProductForm.addEventListener('submit', function(e) {
|
|
var purchasePrice = parseInt(document.getElementById('purchase_price').value);
|
|
var sellingPrice = parseInt(document.getElementById('selling_price').value);
|
|
|
|
if (purchasePrice < 1000 || sellingPrice < 1000) {
|
|
e.preventDefault();
|
|
alert('Nominal harga beli dan harga jual minimal adalah Rp 1.000!');
|
|
}
|
|
});
|
|
}
|
|
|
|
const editProductForm = document.getElementById('editProductForm');
|
|
if (editProductForm) {
|
|
editProductForm.addEventListener('submit', function(e) {
|
|
var purchasePrice = parseInt(document.getElementById('edit_purchase_price').value);
|
|
var sellingPrice = parseInt(document.getElementById('edit_selling_price').value);
|
|
|
|
if (purchasePrice < 1000 || sellingPrice < 1000) {
|
|
e.preventDefault();
|
|
alert('Nominal harga beli dan harga jual minimal adalah Rp 1.000!');
|
|
}
|
|
});
|
|
}
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
if (urlParams.get('tab') === 'bahan-baku') {
|
|
$('#bahan-baku-tab').tab('show');
|
|
}
|
|
});
|
|
</script>
|
|
@endpush
|
|
|
|
|
|
@endsection
|