diff --git a/app/Console/Commands/ClearOpnameData.php b/app/Console/Commands/ClearOpnameData.php
new file mode 100644
index 0000000..fa30c11
--- /dev/null
+++ b/app/Console/Commands/ClearOpnameData.php
@@ -0,0 +1,93 @@
+option('force')) {
+ if (!$this->confirm('This will delete ALL opname data, stocks, stock logs, and reset ALL IDs to 1. This is irreversible! Are you sure?')) {
+ $this->info('Operation cancelled.');
+ return;
+ }
+ }
+
+ $this->info('Starting complete data cleanup...');
+
+ try {
+ // Disable foreign key checks
+ DB::statement('SET FOREIGN_KEY_CHECKS=0;');
+
+ // 1. Clear and reset stock logs
+ if (Schema::hasTable('stock_logs')) {
+ DB::table('stock_logs')->truncate();
+ DB::statement('ALTER TABLE stock_logs AUTO_INCREMENT = 1;');
+ $this->info('✓ Cleared and reset stock_logs table');
+ }
+
+ // 2. Clear and reset stocks
+ if (Schema::hasTable('stocks')) {
+ DB::table('stocks')->truncate();
+ DB::statement('ALTER TABLE stocks AUTO_INCREMENT = 1;');
+ $this->info('✓ Cleared and reset stocks table');
+ }
+
+ // 3. Clear and reset opname details
+ if (Schema::hasTable('opname_details')) {
+ DB::table('opname_details')->truncate();
+ DB::statement('ALTER TABLE opname_details AUTO_INCREMENT = 1;');
+ $this->info('✓ Cleared and reset opname_details table');
+ }
+
+ // 4. Clear and reset opnames
+ if (Schema::hasTable('opnames')) {
+ DB::table('opnames')->truncate();
+ DB::statement('ALTER TABLE opnames AUTO_INCREMENT = 1;');
+ $this->info('✓ Cleared and reset opnames table');
+ }
+
+ // Re-enable foreign key checks
+ DB::statement('SET FOREIGN_KEY_CHECKS=1;');
+
+ $this->info('Successfully cleared all data and reset IDs to 1!');
+ $this->info('Cleared tables:');
+ $this->info('- stock_logs');
+ $this->info('- stocks');
+ $this->info('- opname_details');
+ $this->info('- opnames');
+
+ Log::info('Complete data cleared and IDs reset by command', [
+ 'user' => auth()->user() ? auth()->user()->id : 'system',
+ 'timestamp' => now(),
+ 'tables_cleared' => ['stock_logs', 'stocks', 'opname_details', 'opnames']
+ ]);
+
+ } catch (\Exception $e) {
+ // Re-enable foreign key checks if they were disabled
+ DB::statement('SET FOREIGN_KEY_CHECKS=1;');
+
+ $this->error('Error clearing data: ' . $e->getMessage());
+ Log::error('Error in ClearOpnameData command: ' . $e->getMessage(), [
+ 'exception' => $e,
+ 'trace' => $e->getTraceAsString()
+ ]);
+
+ return 1; // Return error code
+ }
+
+ return 0; // Return success code
+ }
+}
\ No newline at end of file
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index d8bc1d2..9310599 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -28,5 +28,9 @@ class Kernel extends ConsoleKernel
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
+
+ $this->commands = [
+ Commands\ClearOpnameData::class,
+ ];
}
}
diff --git a/app/Enums/StockChangeType.php b/app/Enums/StockChangeType.php
new file mode 100644
index 0000000..0b599c7
--- /dev/null
+++ b/app/Enums/StockChangeType.php
@@ -0,0 +1,21 @@
+ 'Penambahan',
+ self::DECREASE => 'Pengurangan',
+ self::ADJUSTMENT => 'Penyesuaian',
+ self::NO_CHANGE => 'Tidak Ada Perubahan'
+ };
+ }
+}
\ No newline at end of file
diff --git a/app/Http/Controllers/WarehouseManagement/OpnamesController.php b/app/Http/Controllers/WarehouseManagement/OpnamesController.php
index b08c886..43a69fa 100644
--- a/app/Http/Controllers/WarehouseManagement/OpnamesController.php
+++ b/app/Http/Controllers/WarehouseManagement/OpnamesController.php
@@ -8,9 +8,10 @@ use App\Models\Menu;
use App\Models\Opname;
use App\Models\OpnameDetail;
use App\Models\Product;
+use App\Models\Stock;
use Carbon\Carbon;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Yajra\DataTables\Facades\DataTables;
@@ -19,7 +20,7 @@ class OpnamesController extends Controller
public function index(Request $request){
$menu = Menu::where('link','opnames.index')->first();
if($request->ajax()){
- $data = Opname::with('user','dealer');
+ $data = Opname::with('user','dealer')->get();
return DataTables::of($data)
->addColumn('user_name', function ($row){
return $row->user ? $row->user->name : '-';
@@ -49,52 +50,167 @@ class OpnamesController extends Controller
public function create(){
try{
$dealers = Dealer::all();
- $products = Product::all();
- return view('warehouse_management.opnames.create', compact('dealers','products'));
- }catch(\Exception $ex){
+ $products = Product::where('active', true)->get();
+
+ // Get initial stock data for the first dealer (if any)
+ $initialDealerId = $dealers->first()?->id;
+ $stocks = [];
+ if ($initialDealerId) {
+ $stocks = Stock::where('dealer_id', $initialDealerId)
+ ->whereIn('product_id', $products->pluck('id'))
+ ->get()
+ ->keyBy('product_id');
+ }
+
+ return view('warehouse_management.opnames.create', compact('dealers', 'products', 'stocks'));
+ } catch(\Exception $ex) {
Log::error($ex->getMessage());
+ return back()->with('error', 'Terjadi kesalahan saat memuat data');
}
}
- public function store(Request $request){
- try{
- $request->validate([
+ public function store(Request $request)
+ {
+ try {
+ DB::beginTransaction();
+
+ // 1. Validasi input
+ $validated = $request->validate([
'dealer' => 'required|exists:dealers,id',
- 'product' => 'required|array',
- 'product.*' => 'nullable|exists:products,id',
+ 'product' => 'required|array|min:1',
+ 'product.*' => 'required|exists:products,id',
'system_quantity' => 'required|array',
+ 'system_quantity.*' => 'required|numeric|min:0',
'physical_quantity' => 'required|array',
+ 'physical_quantity.*' => 'required|numeric|min:0',
+ 'note' => 'nullable|string|max:1000', // note utama
+ 'item_notes' => 'nullable|array', // notes per item
+ 'item_notes.*' => 'required_if:physical_quantity.*,!=,system_quantity.*|nullable|string|max:255'
]);
-
- // 1. Create Opname master record
- $opname = Opname::create([
- 'dealer_id' => $request->dealer,
- 'opname_date' => now(), // or $request->opname_date if you provide it
- 'user_id' => auth()->id(), // assuming the user is logged in
- 'note' => null, // or $request->note if needed
- ]);
-
- // 2. Loop over products to create OpnameDetails
- foreach ($request->product as $index => $productId) {
- if (!$productId) continue; // Skip empty rows
-
- $system = $request->system_quantity[$index] ?? 0;
- $physical = $request->physical_quantity[$index] ?? 0;
-
- OpnameDetail::create([
- 'opname_id' => $opname->id,
- 'product_id' => $productId,
- 'system_stock' => $system,
- 'physical_stock' => $physical,
- 'difference' => $physical - $system,
- 'note' => null, // or include from input
- ]);
+
+ // 2. Validasi duplikasi produk
+ $productCounts = array_count_values(array_filter($request->product));
+ foreach ($productCounts as $productId => $count) {
+ if ($count > 1) {
+ throw new \Exception('Product tidak boleh duplikat.');
+ }
}
-
- return redirect()->route('opnames.index')
- ->with('success', 'Opname berhasil disimpan.');
- }catch(\Exception $ex){
- Log::error($ex->getMessage());
+
+ // 3. Validasi dealer
+ $dealer = Dealer::findOrFail($request->dealer);
+
+ // 4. Validasi produk aktif
+ $productIds = array_filter($request->product);
+ $inactiveProducts = Product::whereIn('id', $productIds)
+ ->where('active', false)
+ ->pluck('name')
+ ->toArray();
+
+ if (!empty($inactiveProducts)) {
+ throw new \Exception('Produk berikut tidak aktif: ' . implode(', ', $inactiveProducts));
+ }
+
+ // 5. Validasi stock dan note
+ $stockDifferences = [];
+ foreach ($request->product as $index => $productId) {
+ if (!$productId) continue;
+
+ $systemStock = floatval($request->system_quantity[$index] ?? 0);
+ $physicalStock = floatval($request->physical_quantity[$index] ?? 0);
+ $itemNote = $request->input("item_notes.{$index}");
+
+ // Jika ada perbedaan stock dan note kosong
+ if (abs($systemStock - $physicalStock) > 0.01 && empty($itemNote)) {
+ $product = Product::find($productId);
+ $stockDifferences[] = $product->name;
+ }
+ }
+
+ if (!empty($stockDifferences)) {
+ throw new \Exception(
+ 'Catatan harus diisi untuk produk berikut karena ada perbedaan stock: ' .
+ implode(', ', $stockDifferences)
+ );
+ }
+
+ // 6. Create Opname master record with approved status
+ $opname = Opname::create([
+ 'dealer_id' => $request->dealer,
+ 'opname_date' => now(),
+ 'user_id' => auth()->id(),
+ 'note' => $request->note,
+ 'status' => 'approved', // Set status langsung approved
+ 'approved_by' => auth()->id(), // Set current user sebagai approver
+ 'approved_at' => now() // Set waktu approval
+ ]);
+
+ // 7. Create OpnameDetails and update stock
+ $details = [];
+ foreach ($request->product as $index => $productId) {
+ if (!$productId) continue;
+
+ $systemStock = floatval($request->system_quantity[$index] ?? 0);
+ $physicalStock = floatval($request->physical_quantity[$index] ?? 0);
+ $difference = $physicalStock - $systemStock;
+
+ // Create opname detail
+ $details[] = [
+ 'opname_id' => $opname->id,
+ 'product_id' => $productId,
+ 'system_stock' => $systemStock,
+ 'physical_stock' => $physicalStock,
+ 'difference' => $difference,
+ 'note' => $request->input("item_notes.{$index}"),
+ 'created_at' => now(),
+ 'updated_at' => now()
+ ];
+
+ // Update stock langsung karena auto approve
+ $stock = Stock::firstOrCreate(
+ [
+ 'product_id' => $productId,
+ 'dealer_id' => $request->dealer
+ ],
+ ['quantity' => 0]
+ );
+
+ // Update stock dengan physical stock
+ $stock->updateStock(
+ $physicalStock,
+ $opname,
+ "Stock adjustment from auto-approved opname #{$opname->id}"
+ );
+ }
+
+ // Bulk insert untuk performa lebih baik
+ OpnameDetail::insert($details);
+
+ // 8. Log aktivitas
+ Log::info('Opname created and auto-approved', [
+ 'opname_id' => $opname->id,
+ 'dealer_id' => $opname->dealer_id,
+ 'user_id' => auth()->id(),
+ 'approver_id' => auth()->id(),
+ 'product_count' => count($details)
+ ]);
+
+ DB::commit();
+
+ return redirect()
+ ->route('opnames.index')
+ ->with('success', 'Opname berhasil disimpan dan disetujui.');
+
+ } catch (\Illuminate\Validation\ValidationException $e) {
+ DB::rollBack();
+ return back()->withErrors($e->validator)->withInput();
+ } catch (\Exception $e) {
+ DB::rollBack();
+ Log::error('Error in OpnamesController@store: ' . $e->getMessage());
+ Log::error($e->getTraceAsString());
+
+ return back()
+ ->with('error', $e->getMessage())
+ ->withInput();
}
}
@@ -107,7 +223,7 @@ class OpnamesController extends Controller
return DataTables::of($opname->details)
->addIndexColumn()
->addColumn('opname_date', function () use ($opname) {
- return $opname->opname_date->format('d M Y');
+ return Carbon::parse($opname->opname_date)->format('d M Y');
})
->addColumn('user_name', function () use ($opname) {
return $opname->user ? $opname->user->name : '-';
@@ -133,5 +249,29 @@ class OpnamesController extends Controller
abort(500, 'Something went wrong');
}
}
-
+
+ // Add new method to get stock data via AJAX
+ public function getStockData(Request $request)
+ {
+ try {
+ $dealerId = $request->dealer_id;
+ $productIds = $request->product_ids;
+
+ if (!$dealerId || !$productIds) {
+ return response()->json(['error' => 'Dealer ID dan Product IDs diperlukan'], 400);
+ }
+
+ $stocks = Stock::where('dealer_id', $dealerId)
+ ->whereIn('product_id', $productIds)
+ ->get()
+ ->mapWithKeys(function ($stock) {
+ return [$stock->product_id => $stock->quantity];
+ });
+
+ return response()->json(['stocks' => $stocks]);
+ } catch (\Exception $e) {
+ Log::error('Error getting stock data: ' . $e->getMessage());
+ return response()->json(['error' => 'Terjadi kesalahan saat mengambil data stok'], 500);
+ }
+ }
}
diff --git a/app/Http/Controllers/WarehouseManagement/ProductsController.php b/app/Http/Controllers/WarehouseManagement/ProductsController.php
index 62c7d5f..ef2f170 100644
--- a/app/Http/Controllers/WarehouseManagement/ProductsController.php
+++ b/app/Http/Controllers/WarehouseManagement/ProductsController.php
@@ -11,6 +11,7 @@ use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Gate;
use Yajra\DataTables\Facades\DataTables;
use Illuminate\Validation\Rule;
@@ -25,19 +26,19 @@ class ProductsController extends Controller
{
$menu = Menu::where('link','products.index')->first();
if($request->ajax()){
- $data = Product::with(['category','opnameDetails']);
+ $data = Product::with(['category', 'stocks']);
return DataTables::of($data)
->addIndexColumn()
->addColumn('category_name', function ($row) {
return $row->category ? $row->category->name : '-';
})
->addColumn('total_stock', function ($row){
- return $row->opnameDetails->sum('system_stock');
+ return number_format($row->current_total_stock, 2);
})
->addColumn('action', function ($row) use ($menu) {
$btn = '
';
- if (Auth::user()->can('update', $menu)) {
+ if (Gate::allows('update', $menu)) {
$btn .= '
Edit ';
}
@@ -196,7 +197,7 @@ class ProductsController extends Controller
public function all_products(){
try{
- $products = Product::select('id','name')->get();
+ $products = Product::where('is_active', true)->select('id','name')->get();
return response()->json($products);
}catch(\Exception $ex){
Log::error($ex->getMessage());
@@ -206,17 +207,12 @@ class ProductsController extends Controller
public function dealers_stock(Request $request){
$productId = $request->get('product_id');
- $product = Product::with(['opnameDetails.opname.dealer'])->findOrFail($productId);
+ $product = Product::with(['stocks.dealer'])->findOrFail($productId);
- $opnameDetails = $product->opnameDetails;
-
- $data = $opnameDetails->map(function ($detail) {
+ $data = $product->stocks->map(function ($stock) {
return [
- 'dealer_name' => $detail->opname->dealer->name ?? '-',
- 'system_stock' => $detail->system_stock,
- 'physical_stock' => $detail->physical_stock,
- 'difference' => $detail->physical_stock - $detail->system_stock,
- 'opname_date' => optional($detail->opname)->created_at->format('d M Y')
+ 'dealer_name' => $stock->dealer->name ?? '-',
+ 'quantity' => $stock->quantity
];
});
diff --git a/app/Http/Controllers/WarehouseManagement/StocksController.php b/app/Http/Controllers/WarehouseManagement/StocksController.php
new file mode 100644
index 0000000..6ca7341
--- /dev/null
+++ b/app/Http/Controllers/WarehouseManagement/StocksController.php
@@ -0,0 +1,117 @@
+ajax()) {
+ $query = Stock::with(['dealer', 'product'])
+ ->when($request->dealer_id, function($q) use ($request) {
+ return $q->where('dealer_id', $request->dealer_id);
+ })
+ ->when($request->product_id, function($q) use ($request) {
+ return $q->where('product_id', $request->product_id);
+ });
+
+ return datatables()->of($query)
+ ->addColumn('dealer_name', function($stock) {
+ return $stock->dealer->name;
+ })
+ ->addColumn('product_name', function($stock) {
+ return $stock->product->name;
+ })
+ ->addColumn('action', function($stock) {
+ return view('warehouse_management.stocks._action', compact('stock'));
+ })
+ ->toJson();
+ }
+
+ $dealers = Dealer::all();
+ $products = Product::where('active', true)->get();
+
+ return view('warehouse_management.stocks.index', compact('dealers', 'products'));
+ }
+
+ public function adjust(Request $request)
+ {
+ $request->validate([
+ 'stock_id' => 'required|exists:stocks,id',
+ 'type' => 'required|in:add,reduce',
+ 'quantity' => 'required|numeric|min:0.01',
+ 'note' => 'required|string|max:255'
+ ]);
+
+ try {
+ DB::beginTransaction();
+
+ $stock = Stock::findOrFail($request->stock_id);
+ $oldQuantity = $stock->quantity;
+
+ // Calculate new quantity
+ $change = $request->type === 'add' ? $request->quantity : -$request->quantity;
+ $newQuantity = $oldQuantity + $change;
+
+ // Update stock
+ $stock->update(['quantity' => $newQuantity]);
+
+ // Log the change
+ StockLog::create([
+ 'stock_id' => $stock->id,
+ 'user_id' => Auth::id(),
+ 'old_quantity' => $oldQuantity,
+ 'new_quantity' => $newQuantity,
+ 'change' => $change,
+ 'note' => $request->note,
+ 'reference_type' => 'manual_adjustment'
+ ]);
+
+ DB::commit();
+
+ return response()->json([
+ 'success' => true,
+ 'message' => 'Stok berhasil diadjust'
+ ]);
+ } catch (\Exception $e) {
+ DB::rollBack();
+ return response()->json([
+ 'success' => false,
+ 'message' => 'Gagal mengadjust stok: ' . $e->getMessage()
+ ], 500);
+ }
+ }
+
+ public function history(Request $request)
+ {
+ $request->validate([
+ 'stock_id' => 'required|exists:stocks,id'
+ ]);
+
+ $logs = StockLog::with('user')
+ ->where('stock_id', $request->stock_id)
+ ->orderBy('created_at', 'desc')
+ ->get()
+ ->map(function($log) {
+ return [
+ 'date' => $log->created_at->format('d/m/Y H:i'),
+ 'user' => $log->user->name,
+ 'change' => $log->change > 0 ? '+' . $log->change : $log->change,
+ 'old_quantity' => $log->old_quantity,
+ 'new_quantity' => $log->new_quantity,
+ 'note' => $log->note
+ ];
+ });
+
+ return response()->json(['logs' => $logs]);
+ }
+}
\ No newline at end of file
diff --git a/app/Models/Opname.php b/app/Models/Opname.php
index a079251..817f2e6 100644
--- a/app/Models/Opname.php
+++ b/app/Models/Opname.php
@@ -10,17 +10,108 @@ class Opname extends Model
{
use HasFactory, SoftDeletes;
- protected $fillable = ['dealer_id','opname_date','user_id','note'];
+ protected $fillable = [
+ 'dealer_id',
+ 'opname_date',
+ 'user_id',
+ 'note',
+ 'status',
+ 'approved_by',
+ 'approved_at',
+ 'rejection_note'
+ ];
- public function dealer(){
+ protected $casts = [
+ 'approved_at' => 'datetime'
+ ];
+
+ protected static function booted()
+ {
+ static::updated(function ($opname) {
+ // Jika status berubah menjadi approved
+ if ($opname->isDirty('status') && $opname->status === 'approved') {
+ // Update stock untuk setiap detail opname
+ foreach ($opname->details as $detail) {
+ $stock = Stock::firstOrCreate(
+ [
+ 'product_id' => $detail->product_id,
+ 'dealer_id' => $opname->dealer_id
+ ],
+ ['quantity' => 0]
+ );
+
+ // Update stock dengan physical_stock dari opname
+ $stock->updateStock(
+ $detail->physical_stock,
+ $opname,
+ "Stock adjustment from approved opname #{$opname->id}"
+ );
+ }
+ }
+ });
+ }
+
+ public function dealer()
+ {
return $this->belongsTo(Dealer::class);
}
- public function details(){
+ public function details()
+ {
return $this->hasMany(OpnameDetail::class);
}
- public function user(){
+ public function user()
+ {
return $this->belongsTo(User::class);
}
+
+ public function approver()
+ {
+ return $this->belongsTo(User::class, 'approved_by');
+ }
+
+ // Method untuk approve opname
+ public function approve(User $approver)
+ {
+ if ($this->status !== 'pending') {
+ throw new \Exception('Only pending opnames can be approved');
+ }
+
+ $this->status = 'approved';
+ $this->approved_by = $approver->id;
+ $this->approved_at = now();
+ $this->save();
+
+ return $this;
+ }
+
+ // Method untuk reject opname
+ public function reject(User $rejector, string $note)
+ {
+ if ($this->status !== 'pending') {
+ throw new \Exception('Only pending opnames can be rejected');
+ }
+
+ $this->status = 'rejected';
+ $this->approved_by = $rejector->id;
+ $this->approved_at = now();
+ $this->rejection_note = $note;
+ $this->save();
+
+ return $this;
+ }
+
+ // Method untuk submit opname untuk approval
+ public function submit()
+ {
+ if ($this->status !== 'draft') {
+ throw new \Exception('Only draft opnames can be submitted');
+ }
+
+ $this->status = 'pending';
+ $this->save();
+
+ return $this;
+ }
}
diff --git a/app/Models/Product.php b/app/Models/Product.php
index c5d85d2..e2c232d 100644
--- a/app/Models/Product.php
+++ b/app/Models/Product.php
@@ -19,4 +19,14 @@ class Product extends Model
public function opnameDetails(){
return $this->hasMany(OpnameDetail::class);
}
+
+ public function stocks(){
+ return $this->hasMany(Stock::class);
+ }
+
+ // Helper method untuk mendapatkan total stock saat ini
+ public function getCurrentTotalStockAttribute()
+ {
+ return $this->stocks()->sum('quantity');
+ }
}
diff --git a/app/Models/Stock.php b/app/Models/Stock.php
new file mode 100644
index 0000000..812bfe8
--- /dev/null
+++ b/app/Models/Stock.php
@@ -0,0 +1,56 @@
+belongsTo(Product::class);
+ }
+
+ public function dealer()
+ {
+ return $this->belongsTo(Dealer::class);
+ }
+
+ public function stockLogs()
+ {
+ return $this->hasMany(StockLog::class);
+ }
+
+ // Method untuk mengupdate stock
+ public function updateStock($newQuantity, $source, $description = null)
+ {
+ $previousQuantity = $this->quantity;
+ $quantityChange = $newQuantity - $previousQuantity;
+
+ $this->quantity = $newQuantity;
+ $this->save();
+
+ // Buat log perubahan
+ StockLog::create([
+ 'stock_id' => $this->id,
+ 'source_type' => get_class($source),
+ 'source_id' => $source->id,
+ 'previous_quantity' => $previousQuantity,
+ 'new_quantity' => $newQuantity,
+ 'quantity_change' => $quantityChange,
+ 'description' => $description,
+ 'user_id' => auth()->id()
+ ]);
+
+ return $this;
+ }
+}
diff --git a/app/Models/StockLog.php b/app/Models/StockLog.php
new file mode 100644
index 0000000..aa33a4e
--- /dev/null
+++ b/app/Models/StockLog.php
@@ -0,0 +1,70 @@
+ StockChangeType::class,
+ 'previous_quantity' => 'decimal:2',
+ 'new_quantity' => 'decimal:2',
+ 'quantity_change' => 'decimal:2'
+ ];
+
+ protected static function booted()
+ {
+ static::creating(function ($stockLog) {
+ // Hitung quantity_change
+ $stockLog->quantity_change = $stockLog->new_quantity - $stockLog->previous_quantity;
+
+ // Tentukan change_type berdasarkan quantity_change
+ if ($stockLog->quantity_change == 0) {
+ // Jika quantity sama persis (tanpa toleransi)
+ $stockLog->change_type = StockChangeType::NO_CHANGE;
+ } else if ($stockLog->quantity_change > 0) {
+ $stockLog->change_type = StockChangeType::INCREASE;
+ } else {
+ $stockLog->change_type = StockChangeType::DECREASE;
+ }
+ });
+ }
+
+ public function stock()
+ {
+ return $this->belongsTo(Stock::class);
+ }
+
+ public function user()
+ {
+ return $this->belongsTo(User::class);
+ }
+
+ public function source()
+ {
+ return $this->morphTo();
+ }
+
+ // Helper method untuk mendapatkan label change_type
+ public function getChangeTypeLabelAttribute()
+ {
+ return $this->change_type->label();
+ }
+}
diff --git a/ckb.sql b/ckb.sql
index 1037b89..6fb3c5a 100644
--- a/ckb.sql
+++ b/ckb.sql
@@ -144,7 +144,7 @@ CREATE TABLE `migrations` (
`migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`batch` int NOT NULL,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=70 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -153,7 +153,7 @@ CREATE TABLE `migrations` (
LOCK TABLES `migrations` WRITE;
/*!40000 ALTER TABLE `migrations` DISABLE KEYS */;
-INSERT INTO `migrations` VALUES (1,'2014_10_12_100000_create_password_resets_table',1),(2,'2019_08_19_000000_create_failed_jobs_table',1),(3,'2019_12_14_000001_create_personal_access_tokens_table',1),(4,'2022_05_20_100209_create_dealers_table',1),(5,'2022_05_20_100326_create_categories_table',1),(6,'2022_05_20_100335_create_works_table',1),(7,'2022_05_20_100340_create_users_table',1),(8,'2022_05_20_100410_create_transactions_table',1),(9,'2022_05_25_024641_update_works_table',2),(10,'2022_05_25_103839_update_categories_table',3),(13,'2022_05_25_144502_update_transaction_table',4),(18,'2022_05_29_211410_update_table_works_add_shortname_field',5),(20,'2022_05_29_211531_update_dealers_table_add_pic_field',6),(21,'2022_05_29_220642_update_transactions_table_add_status_column',7),(22,'2022_05_31_003725_update_transaction_table_add_dealer_id',8),(23,'2022_06_23_215115_add_deleted_at_at_users_table',9),(24,'2022_06_23_215243_add_deleted_at_at_dealers_table',9),(25,'2022_06_23_215321_add_deleted_at_at_categories_table',9),(26,'2022_06_23_215341_add_deleted_at_at_works_table',9),(27,'2022_06_23_215404_add_deleted_at_at_transactions_table',9),(28,'2023_08_11_140743_create_roles_table',10),(29,'2023_08_11_140957_create_privileges_table',10),(30,'2023_08_11_141029_add_role_id_into_users_table',10),(31,'2023_08_11_144823_create_menus_table',10),(32,'2023_08_11_144857_add_menu_id_in_privileges_table',10),(33,'2023_08_11_145537_remove_name_in_privileges_table',10),(55,'2025_05_28_113228_create_product_categories_table',11),(56,'2025_05_28_113324_create_products_table',11),(59,'2025_06_04_101915_create_opnames_table',12),(60,'2025_06_04_103359_create_opname_details_table',12);
+INSERT INTO `migrations` VALUES (1,'2014_10_12_100000_create_password_resets_table',1),(2,'2019_08_19_000000_create_failed_jobs_table',1),(3,'2019_12_14_000001_create_personal_access_tokens_table',1),(4,'2022_05_20_100209_create_dealers_table',1),(5,'2022_05_20_100326_create_categories_table',1),(6,'2022_05_20_100335_create_works_table',1),(7,'2022_05_20_100340_create_users_table',1),(8,'2022_05_20_100410_create_transactions_table',1),(9,'2022_05_25_024641_update_works_table',2),(10,'2022_05_25_103839_update_categories_table',3),(13,'2022_05_25_144502_update_transaction_table',4),(18,'2022_05_29_211410_update_table_works_add_shortname_field',5),(20,'2022_05_29_211531_update_dealers_table_add_pic_field',6),(21,'2022_05_29_220642_update_transactions_table_add_status_column',7),(22,'2022_05_31_003725_update_transaction_table_add_dealer_id',8),(23,'2022_06_23_215115_add_deleted_at_at_users_table',9),(24,'2022_06_23_215243_add_deleted_at_at_dealers_table',9),(25,'2022_06_23_215321_add_deleted_at_at_categories_table',9),(26,'2022_06_23_215341_add_deleted_at_at_works_table',9),(27,'2022_06_23_215404_add_deleted_at_at_transactions_table',9),(28,'2023_08_11_140743_create_roles_table',10),(29,'2023_08_11_140957_create_privileges_table',10),(30,'2023_08_11_141029_add_role_id_into_users_table',10),(31,'2023_08_11_144823_create_menus_table',10),(32,'2023_08_11_144857_add_menu_id_in_privileges_table',10),(33,'2023_08_11_145537_remove_name_in_privileges_table',10),(55,'2025_05_28_113228_create_product_categories_table',11),(56,'2025_05_28_113324_create_products_table',11),(59,'2025_06_04_101915_create_opnames_table',12),(60,'2025_06_04_103359_create_opname_details_table',12),(66,'2025_06_10_135321_create_stocks_table',13),(67,'2025_06_10_135341_create_stock_logs_table',14),(68,'2025_06_10_135417_add_approval_columns_to_opnames_table',14),(69,'2025_06_10_140540_change_stock_columns_to_decimal_in_opname_details',14);
/*!40000 ALTER TABLE `migrations` ENABLE KEYS */;
UNLOCK TABLES;
@@ -168,9 +168,9 @@ CREATE TABLE `opname_details` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`opname_id` bigint unsigned NOT NULL,
`product_id` bigint unsigned NOT NULL,
- `system_stock` int NOT NULL,
- `physical_stock` int NOT NULL,
- `difference` int NOT NULL DEFAULT '0',
+ `system_stock` decimal(10,2) NOT NULL,
+ `physical_stock` decimal(10,2) NOT NULL,
+ `difference` decimal(10,2) NOT NULL DEFAULT '0.00',
`note` text COLLATE utf8mb4_unicode_ci,
`deleted_at` timestamp NULL DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
@@ -189,7 +189,7 @@ CREATE TABLE `opname_details` (
LOCK TABLES `opname_details` WRITE;
/*!40000 ALTER TABLE `opname_details` DISABLE KEYS */;
-INSERT INTO `opname_details` VALUES (1,1,1,66,88,22,NULL,NULL,'2025-06-05 04:27:30','2025-06-05 04:27:30'),(2,1,3,77,88,11,NULL,NULL,'2025-06-05 04:27:30','2025-06-05 04:27:30');
+INSERT INTO `opname_details` VALUES (1,1,1,0.00,10.00,10.00,'tambah produk baru',NULL,'2025-06-10 10:26:24','2025-06-10 10:26:24'),(2,2,1,0.00,30.00,30.00,'tambah baru',NULL,'2025-06-10 10:27:30','2025-06-10 10:27:30');
/*!40000 ALTER TABLE `opname_details` ENABLE KEYS */;
UNLOCK TABLES;
@@ -209,12 +209,18 @@ CREATE TABLE `opnames` (
`deleted_at` timestamp NULL DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
+ `status` enum('draft','pending','approved','rejected') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'draft',
+ `approved_by` bigint unsigned DEFAULT NULL,
+ `approved_at` timestamp NULL DEFAULT NULL,
+ `rejection_note` text COLLATE utf8mb4_unicode_ci,
PRIMARY KEY (`id`),
KEY `opnames_dealer_id_foreign` (`dealer_id`),
KEY `opnames_user_id_foreign` (`user_id`),
+ KEY `opnames_approved_by_foreign` (`approved_by`),
+ CONSTRAINT `opnames_approved_by_foreign` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`),
CONSTRAINT `opnames_dealer_id_foreign` FOREIGN KEY (`dealer_id`) REFERENCES `dealers` (`id`) ON DELETE CASCADE,
CONSTRAINT `opnames_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
@@ -223,7 +229,7 @@ CREATE TABLE `opnames` (
LOCK TABLES `opnames` WRITE;
/*!40000 ALTER TABLE `opnames` DISABLE KEYS */;
-INSERT INTO `opnames` VALUES (1,20,'2025-06-05',8,NULL,NULL,'2025-06-05 04:27:30','2025-06-05 04:27:30');
+INSERT INTO `opnames` VALUES (1,20,'2025-06-10',8,'test tambah product by opname',NULL,'2025-06-10 10:26:24','2025-06-10 10:26:24','approved',8,'2025-06-10 10:26:24',NULL),(2,24,'2025-06-10',8,'test tambah produk by opname',NULL,'2025-06-10 10:27:30','2025-06-10 10:27:30','approved',8,'2025-06-10 10:27:30',NULL);
/*!40000 ALTER TABLE `opnames` ENABLE KEYS */;
UNLOCK TABLES;
@@ -412,6 +418,77 @@ INSERT INTO `roles` VALUES (2,'admin',NULL,'2023-08-13 11:21:43','2023-08-13 11:
/*!40000 ALTER TABLE `roles` ENABLE KEYS */;
UNLOCK TABLES;
+--
+-- Table structure for table `stock_logs`
+--
+
+DROP TABLE IF EXISTS `stock_logs`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `stock_logs` (
+ `id` bigint unsigned NOT NULL AUTO_INCREMENT,
+ `stock_id` bigint unsigned NOT NULL,
+ `source_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
+ `source_id` bigint unsigned NOT NULL,
+ `previous_quantity` decimal(10,2) NOT NULL,
+ `new_quantity` decimal(10,2) NOT NULL,
+ `quantity_change` decimal(10,2) NOT NULL,
+ `change_type` enum('increase','decrease','adjustment','no_change') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'no_change',
+ `description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
+ `user_id` bigint unsigned NOT NULL,
+ `created_at` timestamp NULL DEFAULT NULL,
+ `updated_at` timestamp NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `stock_logs_stock_id_foreign` (`stock_id`),
+ KEY `stock_logs_user_id_foreign` (`user_id`),
+ KEY `stock_logs_source_type_source_id_index` (`source_type`,`source_id`),
+ CONSTRAINT `stock_logs_stock_id_foreign` FOREIGN KEY (`stock_id`) REFERENCES `stocks` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `stock_logs_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `stock_logs`
+--
+
+LOCK TABLES `stock_logs` WRITE;
+/*!40000 ALTER TABLE `stock_logs` DISABLE KEYS */;
+INSERT INTO `stock_logs` VALUES (1,1,'App\\Models\\Opname',1,0.00,10.00,10.00,'increase','Stock adjustment from auto-approved opname #1',8,'2025-06-10 10:26:24','2025-06-10 10:26:24'),(2,2,'App\\Models\\Opname',2,0.00,30.00,30.00,'increase','Stock adjustment from auto-approved opname #2',8,'2025-06-10 10:27:30','2025-06-10 10:27:30');
+/*!40000 ALTER TABLE `stock_logs` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `stocks`
+--
+
+DROP TABLE IF EXISTS `stocks`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `stocks` (
+ `id` bigint unsigned NOT NULL AUTO_INCREMENT,
+ `product_id` bigint unsigned NOT NULL,
+ `dealer_id` bigint unsigned NOT NULL,
+ `quantity` decimal(10,2) NOT NULL DEFAULT '0.00',
+ `created_at` timestamp NULL DEFAULT NULL,
+ `updated_at` timestamp NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `stocks_product_id_foreign` (`product_id`),
+ KEY `stocks_dealer_id_foreign` (`dealer_id`),
+ CONSTRAINT `stocks_dealer_id_foreign` FOREIGN KEY (`dealer_id`) REFERENCES `dealers` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `stocks_product_id_foreign` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `stocks`
+--
+
+LOCK TABLES `stocks` WRITE;
+/*!40000 ALTER TABLE `stocks` DISABLE KEYS */;
+INSERT INTO `stocks` VALUES (1,1,20,10.00,'2025-06-10 10:26:24','2025-06-10 10:26:24'),(2,1,24,30.00,'2025-06-10 10:27:30','2025-06-10 10:27:30');
+/*!40000 ALTER TABLE `stocks` ENABLE KEYS */;
+UNLOCK TABLES;
+
--
-- Table structure for table `transactions`
--
@@ -569,4 +646,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
--- Dump completed on 2025-06-05 19:06:52
+-- Dump completed on 2025-06-10 18:16:53
diff --git a/database/migrations/2025_06_10_135321_create_stocks_table.php b/database/migrations/2025_06_10_135321_create_stocks_table.php
new file mode 100644
index 0000000..5764502
--- /dev/null
+++ b/database/migrations/2025_06_10_135321_create_stocks_table.php
@@ -0,0 +1,34 @@
+id();
+ $table->foreignId('product_id')->constrained('products')->onDelete('cascade');
+ $table->foreignId('dealer_id')->constrained('dealers')->onDelete('cascade');
+ $table->decimal('quantity', 10, 2)->default(0);
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('stocks');
+ }
+}
diff --git a/database/migrations/2025_06_10_135341_create_stock_logs_table.php b/database/migrations/2025_06_10_135341_create_stock_logs_table.php
new file mode 100644
index 0000000..7d45022
--- /dev/null
+++ b/database/migrations/2025_06_10_135341_create_stock_logs_table.php
@@ -0,0 +1,44 @@
+id();
+ $table->foreignId('stock_id')->constrained('stocks')->onDelete('cascade');
+ $table->string('source_type'); // 'opname' atau 'mutation'
+ $table->unsignedBigInteger('source_id'); // ID dari opname atau mutation
+ $table->decimal('previous_quantity', 10, 2);
+ $table->decimal('new_quantity', 10, 2);
+ $table->decimal('quantity_change', 10, 2); // bisa positif atau negatif
+ $table->enum('change_type', ['increase', 'decrease', 'adjustment', 'no_change'])->default('no_change');
+ $table->string('description')->nullable();
+ $table->foreignId('user_id')->constrained('users');
+ $table->timestamps();
+
+ // Index untuk pencarian berdasarkan source
+ $table->index(['source_type', 'source_id']);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('stock_logs');
+ }
+}
diff --git a/database/migrations/2025_06_10_135417_add_approval_columns_to_opnames_table.php b/database/migrations/2025_06_10_135417_add_approval_columns_to_opnames_table.php
new file mode 100644
index 0000000..4653757
--- /dev/null
+++ b/database/migrations/2025_06_10_135417_add_approval_columns_to_opnames_table.php
@@ -0,0 +1,36 @@
+enum('status', ['draft', 'pending', 'approved', 'rejected'])->default('draft');
+ $table->foreignId('approved_by')->nullable()->constrained('users');
+ $table->timestamp('approved_at')->nullable();
+ $table->text('rejection_note')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('opnames', function (Blueprint $table) {
+ $table->dropForeign(['approved_by']);
+ $table->dropColumn(['status', 'approved_by', 'approved_at', 'rejection_note']);
+ });
+ }
+}
diff --git a/database/migrations/2025_06_10_140540_change_stock_columns_to_decimal_in_opname_details.php b/database/migrations/2025_06_10_140540_change_stock_columns_to_decimal_in_opname_details.php
new file mode 100644
index 0000000..98af8c9
--- /dev/null
+++ b/database/migrations/2025_06_10_140540_change_stock_columns_to_decimal_in_opname_details.php
@@ -0,0 +1,41 @@
+decimal('system_stock', 10, 2)->change();
+
+ // Mengubah kolom physical_stock dari integer ke decimal(10,2)
+ $table->decimal('physical_stock', 10, 2)->change();
+
+ // Mengubah kolom difference dari integer ke decimal(10,2)
+ $table->decimal('difference', 10, 2)->default(0)->change();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('opname_details', function (Blueprint $table) {
+ $table->integer('system_stock')->change();
+ $table->integer('physical_stock')->change();
+ $table->integer('difference')->default(0)->change();
+ });
+ }
+}
diff --git a/public/js/warehouse_management/opnames/create.js b/public/js/warehouse_management/opnames/create.js
index dbc6bf9..d853930 100644
--- a/public/js/warehouse_management/opnames/create.js
+++ b/public/js/warehouse_management/opnames/create.js
@@ -15,7 +15,7 @@
\*************************************************************/
/***/ (() => {
-eval("var productUrl = $(\"#product-container\").data(\"url\");\n\nfunction createProductSelectOptions(callback) {\n $.ajax({\n url: productUrl,\n method: \"GET\",\n success: function success(data) {\n var options = '
Pilih Produk ';\n data.forEach(function (product) {\n options += \"
\").concat(product.name, \" \");\n });\n callback(options);\n },\n error: function error() {\n alert(\"Gagal memuat produk.\");\n }\n });\n}\n\n$(document).ready(function () {\n // Initial load only for the first row\n createProductSelectOptions(function (options) {\n $(\".product-select\").first().html(options);\n }); // When adding a new row\n\n $(document).on(\"click\", \".btn-add-row\", function () {\n var row = \"\\n
\\n \";\n var $newRow = $(row);\n $(\"#product-container\").append($newRow); // Load options only for the new select\n\n createProductSelectOptions(function (options) {\n $newRow.find(\".product-select\").html(options);\n });\n }); // Remove row\n\n $(document).on(\"click\", \".btn-remove-row\", function () {\n $(this).closest(\".product-row\").remove();\n });\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJwcm9kdWN0VXJsIiwiJCIsImRhdGEiLCJjcmVhdGVQcm9kdWN0U2VsZWN0T3B0aW9ucyIsImNhbGxiYWNrIiwiYWpheCIsInVybCIsIm1ldGhvZCIsInN1Y2Nlc3MiLCJvcHRpb25zIiwiZm9yRWFjaCIsInByb2R1Y3QiLCJpZCIsIm5hbWUiLCJlcnJvciIsImFsZXJ0IiwiZG9jdW1lbnQiLCJyZWFkeSIsImZpcnN0IiwiaHRtbCIsIm9uIiwicm93IiwiJG5ld1JvdyIsImFwcGVuZCIsImZpbmQiLCJjbG9zZXN0IiwicmVtb3ZlIl0sInNvdXJjZXMiOlsid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy93YXJlaG91c2VfbWFuYWdlbWVudC9vcG5hbWVzL2NyZWF0ZS5qcz81ZWVmIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHByb2R1Y3RVcmwgPSAkKFwiI3Byb2R1Y3QtY29udGFpbmVyXCIpLmRhdGEoXCJ1cmxcIik7XG5cbmZ1bmN0aW9uIGNyZWF0ZVByb2R1Y3RTZWxlY3RPcHRpb25zKGNhbGxiYWNrKSB7XG4gICAgJC5hamF4KHtcbiAgICAgICAgdXJsOiBwcm9kdWN0VXJsLFxuICAgICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICBsZXQgb3B0aW9ucyA9ICc8b3B0aW9uIHZhbHVlPVwiXCI+UGlsaWggUHJvZHVrPC9vcHRpb24+JztcbiAgICAgICAgICAgIGRhdGEuZm9yRWFjaCgocHJvZHVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMgKz0gYDxvcHRpb24gdmFsdWU9XCIke3Byb2R1Y3QuaWR9XCI+JHtwcm9kdWN0Lm5hbWV9PC9vcHRpb24+YDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY2FsbGJhY2sob3B0aW9ucyk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBhbGVydChcIkdhZ2FsIG1lbXVhdCBwcm9kdWsuXCIpO1xuICAgICAgICB9LFxuICAgIH0pO1xufVxuXG4kKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbiAoKSB7XG4gICAgLy8gSW5pdGlhbCBsb2FkIG9ubHkgZm9yIHRoZSBmaXJzdCByb3dcbiAgICBjcmVhdGVQcm9kdWN0U2VsZWN0T3B0aW9ucygob3B0aW9ucykgPT4ge1xuICAgICAgICAkKFwiLnByb2R1Y3Qtc2VsZWN0XCIpLmZpcnN0KCkuaHRtbChvcHRpb25zKTtcbiAgICB9KTtcblxuICAgIC8vIFdoZW4gYWRkaW5nIGEgbmV3IHJvd1xuICAgICQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIuYnRuLWFkZC1yb3dcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByb3cgPSBgXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tcm93IGFsaWduLWl0ZW1zLWVuZCBwcm9kdWN0LXJvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgY29sLW1kLTRcIj5cbiAgICAgICAgICAgICAgPHNlbGVjdCBuYW1lPVwicHJvZHVjdFtdXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgcHJvZHVjdC1zZWxlY3RcIj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uPkxvYWRpbmcuLi48L29wdGlvbj5cbiAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIGNvbC1tZC0zXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIG5hbWU9XCJzeXN0ZW1fcXVhbnRpdHlbXVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcGxhY2Vob2xkZXI9XCJTdG9rIHNpc3RlbVwiPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBjb2wtbWQtM1wiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBuYW1lPVwicGh5c2ljYWxfcXVhbnRpdHlbXVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcGxhY2Vob2xkZXI9XCJTdG9rIGZpc2lrXCI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIGNvbC1tZC0yXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXIgYnRuLXJlbW92ZS1yb3dcIj48aSBjbGFzcz1cImZsYXRpY29uMi1kZWxldGVcIj48L2k+PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgYDtcblxuICAgICAgICBjb25zdCAkbmV3Um93ID0gJChyb3cpO1xuICAgICAgICAkKFwiI3Byb2R1Y3QtY29udGFpbmVyXCIpLmFwcGVuZCgkbmV3Um93KTtcblxuICAgICAgICAvLyBMb2FkIG9wdGlvbnMgb25seSBmb3IgdGhlIG5ldyBzZWxlY3RcbiAgICAgICAgY3JlYXRlUHJvZHVjdFNlbGVjdE9wdGlvbnMoKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgICRuZXdSb3cuZmluZChcIi5wcm9kdWN0LXNlbGVjdFwiKS5odG1sKG9wdGlvbnMpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIFJlbW92ZSByb3dcbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1yZW1vdmUtcm93XCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJCh0aGlzKS5jbG9zZXN0KFwiLnByb2R1Y3Qtcm93XCIpLnJlbW92ZSgpO1xuICAgIH0pO1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBLElBQU1BLFVBQVUsR0FBR0MsQ0FBQyxDQUFDLG9CQUFELENBQUQsQ0FBd0JDLElBQXhCLENBQTZCLEtBQTdCLENBQW5COztBQUVBLFNBQVNDLDBCQUFULENBQW9DQyxRQUFwQyxFQUE4QztFQUMxQ0gsQ0FBQyxDQUFDSSxJQUFGLENBQU87SUFDSEMsR0FBRyxFQUFFTixVQURGO0lBRUhPLE1BQU0sRUFBRSxLQUZMO0lBR0hDLE9BQU8sRUFBRSxpQkFBVU4sSUFBVixFQUFnQjtNQUNyQixJQUFJTyxPQUFPLEdBQUcsd0NBQWQ7TUFDQVAsSUFBSSxDQUFDUSxPQUFMLENBQWEsVUFBQ0MsT0FBRCxFQUFhO1FBQ3RCRixPQUFPLDhCQUFzQkUsT0FBTyxDQUFDQyxFQUE5QixnQkFBcUNELE9BQU8sQ0FBQ0UsSUFBN0MsY0FBUDtNQUNILENBRkQ7TUFHQVQsUUFBUSxDQUFDSyxPQUFELENBQVI7SUFDSCxDQVRFO0lBVUhLLEtBQUssRUFBRSxpQkFBWTtNQUNmQyxLQUFLLENBQUMsc0JBQUQsQ0FBTDtJQUNIO0VBWkUsQ0FBUDtBQWNIOztBQUVEZCxDQUFDLENBQUNlLFFBQUQsQ0FBRCxDQUFZQyxLQUFaLENBQWtCLFlBQVk7RUFDMUI7RUFDQWQsMEJBQTBCLENBQUMsVUFBQ00sT0FBRCxFQUFhO0lBQ3BDUixDQUFDLENBQUMsaUJBQUQsQ0FBRCxDQUFxQmlCLEtBQXJCLEdBQTZCQyxJQUE3QixDQUFrQ1YsT0FBbEM7RUFDSCxDQUZ5QixDQUExQixDQUYwQixDQU0xQjs7RUFDQVIsQ0FBQyxDQUFDZSxRQUFELENBQUQsQ0FBWUksRUFBWixDQUFlLE9BQWYsRUFBd0IsY0FBeEIsRUFBd0MsWUFBWTtJQUNoRCxJQUFNQyxHQUFHLDgyQkFBVDtJQW1CQSxJQUFNQyxPQUFPLEdBQUdyQixDQUFDLENBQUNvQixHQUFELENBQWpCO0lBQ0FwQixDQUFDLENBQUMsb0JBQUQsQ0FBRCxDQUF3QnNCLE1BQXhCLENBQStCRCxPQUEvQixFQXJCZ0QsQ0F1QmhEOztJQUNBbkIsMEJBQTBCLENBQUMsVUFBQ00sT0FBRCxFQUFhO01BQ3BDYSxPQUFPLENBQUNFLElBQVIsQ0FBYSxpQkFBYixFQUFnQ0wsSUFBaEMsQ0FBcUNWLE9BQXJDO0lBQ0gsQ0FGeUIsQ0FBMUI7RUFHSCxDQTNCRCxFQVAwQixDQW9DMUI7O0VBQ0FSLENBQUMsQ0FBQ2UsUUFBRCxDQUFELENBQVlJLEVBQVosQ0FBZSxPQUFmLEVBQXdCLGlCQUF4QixFQUEyQyxZQUFZO0lBQ25EbkIsQ0FBQyxDQUFDLElBQUQsQ0FBRCxDQUFRd0IsT0FBUixDQUFnQixjQUFoQixFQUFnQ0MsTUFBaEM7RUFDSCxDQUZEO0FBR0gsQ0F4Q0QiLCJmaWxlIjoiLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvb3BuYW1lcy9jcmVhdGUuanMiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/opnames/create.js\n");
+eval("function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _iterableToArray(iter) { if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n$(document).ready(function () {\n // Fungsi untuk mengambil data stok\n function fetchStockData() {\n var dealerId = $(\"#dealer\").val();\n if (!dealerId) return;\n var productIds = $(\".product-select\").map(function () {\n return $(this).val();\n }).get().filter(function (id) {\n return id !== \"\";\n });\n if (productIds.length === 0) return;\n $.ajax({\n url: \"/warehouse/opnames/get-stock-data\",\n method: \"POST\",\n data: {\n _token: $('meta[name=\"csrf-token\"]').attr(\"content\"),\n dealer_id: dealerId,\n product_ids: productIds\n },\n success: function success(response) {\n if (response.stocks) {\n $(\".product-row\").each(function () {\n var productId = $(this).find(\".product-select\").val();\n var systemQtyInput = $(this).find(\".system-quantity\");\n var physicalQtyInput = $(this).find('input[name^=\"physical_quantity\"]'); // Simpan nilai physical quantity yang sudah ada\n\n var currentPhysicalQty = physicalQtyInput.val();\n\n if (productId && response.stocks[productId] !== undefined) {\n systemQtyInput.val(response.stocks[productId]); // Kembalikan nilai physical quantity jika ada\n\n if (currentPhysicalQty) {\n physicalQtyInput.val(currentPhysicalQty);\n }\n\n calculateDifference(systemQtyInput[0]);\n } else {\n systemQtyInput.val(\"0\");\n calculateDifference(systemQtyInput[0]);\n }\n });\n }\n },\n error: function error(xhr) {\n console.error(\"Error fetching stock data:\", xhr.responseText);\n }\n });\n } // Update stok saat dealer berubah\n\n\n $(\"#dealer\").change(function () {\n fetchStockData();\n }); // Update stok saat produk berubah\n\n $(document).on(\"change\", \".product-select\", function () {\n var row = $(this).closest(\"tr\");\n var productId = $(this).val();\n var systemQtyInput = row.find(\".system-quantity\");\n var physicalQtyInput = row.find('input[name^=\"physical_quantity\"]'); // Simpan nilai physical quantity yang sudah ada\n\n var currentPhysicalQty = physicalQtyInput.val();\n\n if (productId) {\n fetchStockData();\n } else {\n systemQtyInput.val(\"0\"); // Kembalikan nilai physical quantity jika ada\n\n if (currentPhysicalQty) {\n physicalQtyInput.val(currentPhysicalQty);\n }\n\n calculateDifference(systemQtyInput[0]);\n }\n }); // Fungsi untuk menambah baris produk\n\n $(\"#btn-add-row\").click(function () {\n var template = document.getElementById(\"product-row-template\");\n var tbody = $(\"#product-table tbody\");\n var newRow = template.content.cloneNode(true);\n var rowIndex = $(\".product-row\").length; // Update name attributes with correct index\n\n $(newRow).find('select[name=\"product[]\"]').attr(\"name\", \"product[\".concat(rowIndex, \"]\"));\n $(newRow).find('input[name=\"system_quantity[]\"]').attr(\"name\", \"system_quantity[\".concat(rowIndex, \"]\"));\n $(newRow).find('input[name=\"physical_quantity[]\"]').attr(\"name\", \"physical_quantity[\".concat(rowIndex, \"]\"));\n $(newRow).find('input[name=\"item_notes[]\"]').attr(\"name\", \"item_notes[\".concat(rowIndex, \"]\")); // Add system-quantity class dan pastikan readonly\n\n var systemQtyInput = $(newRow).find('input[name=\"system_quantity[]\"]');\n systemQtyInput.addClass(\"system-quantity\").attr(\"readonly\", true).val(\"0\"); // Reset semua nilai input di baris baru kecuali system quantity\n\n $(newRow).find(\"select\").val(\"\");\n $(newRow).find(\"input:not(.system-quantity)\").val(\"\");\n tbody.append(newRow);\n updateRemoveButtons();\n }); // Fungsi untuk menghapus baris produk\n\n $(document).on(\"click\", \".btn-remove-row\", function () {\n $(this).closest(\"tr\").remove();\n updateRemoveButtons(); // Reindex semua baris setelah penghapusan\n\n reindexRows();\n }); // Fungsi untuk update status tombol hapus\n\n function updateRemoveButtons() {\n var rows = $(\".product-row\").length;\n $(\".btn-remove-row\").prop(\"disabled\", rows <= 1);\n } // Fungsi untuk reindex semua baris\n\n\n function reindexRows() {\n $(\".product-row\").each(function (index) {\n $(this).find('select[name^=\"product\"]').attr(\"name\", \"product[\".concat(index, \"]\"));\n $(this).find('input[name^=\"system_quantity\"]').attr(\"name\", \"system_quantity[\".concat(index, \"]\"));\n $(this).find('input[name^=\"physical_quantity\"]').attr(\"name\", \"physical_quantity[\".concat(index, \"]\"));\n $(this).find('input[name^=\"item_notes\"]').attr(\"name\", \"item_notes[\".concat(index, \"]\"));\n });\n } // Update calculateDifference function\n\n\n function calculateDifference(input) {\n var row = $(input).closest(\"tr\");\n var systemQty = parseFloat(row.find(\".system-quantity\").val()) || 0;\n var physicalQty = parseFloat(row.find('input[name^=\"physical_quantity\"]').val()) || 0;\n var noteInput = row.find('input[name^=\"item_notes\"]');\n\n if (Math.abs(systemQty - physicalQty) > 0.01) {\n noteInput.addClass(\"is-invalid\");\n noteInput.attr(\"required\", true);\n noteInput.attr(\"placeholder\", \"Catatan wajib diisi karena ada perbedaan stock\");\n row.addClass(\"table-warning\");\n } else {\n noteInput.removeClass(\"is-invalid\");\n noteInput.removeAttr(\"required\");\n noteInput.attr(\"placeholder\", \"Catatan item\");\n row.removeClass(\"table-warning\");\n }\n } // Prevent manual editing of system quantity\n\n\n $(document).on(\"keydown\", \".system-quantity\", function (e) {\n e.preventDefault();\n return false;\n });\n $(document).on(\"paste\", \".system-quantity\", function (e) {\n e.preventDefault();\n return false;\n }); // Validasi form sebelum submit\n\n $(\"#opname-form\").submit(function (e) {\n var dealerId = $(\"#dealer\").val();\n\n if (!dealerId) {\n e.preventDefault();\n alert(\"Silakan pilih dealer terlebih dahulu!\");\n return false;\n }\n\n var products = $('select[name^=\"product\"]').map(function () {\n return $(this).val();\n }).get(); // Cek duplikasi produk\n\n var uniqueProducts = _toConsumableArray(new Set(products));\n\n if (products.length !== uniqueProducts.length) {\n e.preventDefault();\n alert(\"Produk tidak boleh duplikat!\");\n return false;\n } // Cek produk kosong\n\n\n if (products.includes(\"\")) {\n e.preventDefault();\n alert(\"Semua produk harus dipilih!\");\n return false;\n } // Cek catatan untuk perbedaan stock\n\n\n var hasInvalidNotes = false;\n $(\".product-row\").each(function () {\n var systemQty = parseFloat($(this).find('input[name^=\"system_quantity\"]').val()) || 0;\n var physicalQty = parseFloat($(this).find('input[name^=\"physical_quantity\"]').val()) || 0;\n var note = $(this).find('input[name^=\"item_notes\"]').val();\n\n if (Math.abs(systemQty - physicalQty) > 0.01 && !note) {\n hasInvalidNotes = true;\n $(this).addClass(\"table-danger\");\n }\n });\n\n if (hasInvalidNotes) {\n e.preventDefault();\n alert(\"Catatan wajib diisi untuk produk yang memiliki perbedaan stock!\");\n return false;\n }\n }); // Initial stock data load if dealer is selected\n\n if ($(\"#dealer\").val()) {\n fetchStockData();\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyIkIiwiZG9jdW1lbnQiLCJyZWFkeSIsImZldGNoU3RvY2tEYXRhIiwiZGVhbGVySWQiLCJ2YWwiLCJwcm9kdWN0SWRzIiwibWFwIiwiZ2V0IiwiZmlsdGVyIiwiaWQiLCJsZW5ndGgiLCJhamF4IiwidXJsIiwibWV0aG9kIiwiZGF0YSIsIl90b2tlbiIsImF0dHIiLCJkZWFsZXJfaWQiLCJwcm9kdWN0X2lkcyIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsInN0b2NrcyIsImVhY2giLCJwcm9kdWN0SWQiLCJmaW5kIiwic3lzdGVtUXR5SW5wdXQiLCJwaHlzaWNhbFF0eUlucHV0IiwiY3VycmVudFBoeXNpY2FsUXR5IiwidW5kZWZpbmVkIiwiY2FsY3VsYXRlRGlmZmVyZW5jZSIsImVycm9yIiwieGhyIiwiY29uc29sZSIsInJlc3BvbnNlVGV4dCIsImNoYW5nZSIsIm9uIiwicm93IiwiY2xvc2VzdCIsImNsaWNrIiwidGVtcGxhdGUiLCJnZXRFbGVtZW50QnlJZCIsInRib2R5IiwibmV3Um93IiwiY29udGVudCIsImNsb25lTm9kZSIsInJvd0luZGV4IiwiYWRkQ2xhc3MiLCJhcHBlbmQiLCJ1cGRhdGVSZW1vdmVCdXR0b25zIiwicmVtb3ZlIiwicmVpbmRleFJvd3MiLCJyb3dzIiwicHJvcCIsImluZGV4IiwiaW5wdXQiLCJzeXN0ZW1RdHkiLCJwYXJzZUZsb2F0IiwicGh5c2ljYWxRdHkiLCJub3RlSW5wdXQiLCJNYXRoIiwiYWJzIiwicmVtb3ZlQ2xhc3MiLCJyZW1vdmVBdHRyIiwiZSIsInByZXZlbnREZWZhdWx0Iiwic3VibWl0IiwiYWxlcnQiLCJwcm9kdWN0cyIsInVuaXF1ZVByb2R1Y3RzIiwiU2V0IiwiaW5jbHVkZXMiLCJoYXNJbnZhbGlkTm90ZXMiLCJub3RlIl0sInNvdXJjZXMiOlsid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy93YXJlaG91c2VfbWFuYWdlbWVudC9vcG5hbWVzL2NyZWF0ZS5qcz81ZWVmIl0sInNvdXJjZXNDb250ZW50IjpbIiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgICAvLyBGdW5nc2kgdW50dWsgbWVuZ2FtYmlsIGRhdGEgc3Rva1xuICAgIGZ1bmN0aW9uIGZldGNoU3RvY2tEYXRhKCkge1xuICAgICAgICBjb25zdCBkZWFsZXJJZCA9ICQoXCIjZGVhbGVyXCIpLnZhbCgpO1xuICAgICAgICBpZiAoIWRlYWxlcklkKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgcHJvZHVjdElkcyA9ICQoXCIucHJvZHVjdC1zZWxlY3RcIilcbiAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAkKHRoaXMpLnZhbCgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5nZXQoKVxuICAgICAgICAgICAgLmZpbHRlcigoaWQpID0+IGlkICE9PSBcIlwiKTtcblxuICAgICAgICBpZiAocHJvZHVjdElkcy5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBcIi93YXJlaG91c2Uvb3BuYW1lcy9nZXQtc3RvY2stZGF0YVwiLFxuICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBfdG9rZW46ICQoJ21ldGFbbmFtZT1cImNzcmYtdG9rZW5cIl0nKS5hdHRyKFwiY29udGVudFwiKSxcbiAgICAgICAgICAgICAgICBkZWFsZXJfaWQ6IGRlYWxlcklkLFxuICAgICAgICAgICAgICAgIHByb2R1Y3RfaWRzOiBwcm9kdWN0SWRzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5zdG9ja3MpIHtcbiAgICAgICAgICAgICAgICAgICAgJChcIi5wcm9kdWN0LXJvd1wiKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RJZCA9ICQodGhpcykuZmluZChcIi5wcm9kdWN0LXNlbGVjdFwiKS52YWwoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN5c3RlbVF0eUlucHV0ID0gJCh0aGlzKS5maW5kKFwiLnN5c3RlbS1xdWFudGl0eVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBoeXNpY2FsUXR5SW5wdXQgPSAkKHRoaXMpLmZpbmQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2lucHV0W25hbWVePVwicGh5c2ljYWxfcXVhbnRpdHlcIl0nXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTaW1wYW4gbmlsYWkgcGh5c2ljYWwgcXVhbnRpdHkgeWFuZyBzdWRhaCBhZGFcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRQaHlzaWNhbFF0eSA9IHBoeXNpY2FsUXR5SW5wdXQudmFsKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0SWQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5zdG9ja3NbcHJvZHVjdElkXSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1RdHlJbnB1dC52YWwocmVzcG9uc2Uuc3RvY2tzW3Byb2R1Y3RJZF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEtlbWJhbGlrYW4gbmlsYWkgcGh5c2ljYWwgcXVhbnRpdHkgamlrYSBhZGFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFBoeXNpY2FsUXR5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBoeXNpY2FsUXR5SW5wdXQudmFsKGN1cnJlbnRQaHlzaWNhbFF0eSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGN1bGF0ZURpZmZlcmVuY2Uoc3lzdGVtUXR5SW5wdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN0ZW1RdHlJbnB1dC52YWwoXCIwXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGN1bGF0ZURpZmZlcmVuY2Uoc3lzdGVtUXR5SW5wdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICh4aHIpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgZmV0Y2hpbmcgc3RvY2sgZGF0YTpcIiwgeGhyLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgc3RvayBzYWF0IGRlYWxlciBiZXJ1YmFoXG4gICAgJChcIiNkZWFsZXJcIikuY2hhbmdlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZmV0Y2hTdG9ja0RhdGEoKTtcbiAgICB9KTtcblxuICAgIC8vIFVwZGF0ZSBzdG9rIHNhYXQgcHJvZHVrIGJlcnViYWhcbiAgICAkKGRvY3VtZW50KS5vbihcImNoYW5nZVwiLCBcIi5wcm9kdWN0LXNlbGVjdFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJvdyA9ICQodGhpcykuY2xvc2VzdChcInRyXCIpO1xuICAgICAgICBjb25zdCBwcm9kdWN0SWQgPSAkKHRoaXMpLnZhbCgpO1xuICAgICAgICBjb25zdCBzeXN0ZW1RdHlJbnB1dCA9IHJvdy5maW5kKFwiLnN5c3RlbS1xdWFudGl0eVwiKTtcbiAgICAgICAgY29uc3QgcGh5c2ljYWxRdHlJbnB1dCA9IHJvdy5maW5kKCdpbnB1dFtuYW1lXj1cInBoeXNpY2FsX3F1YW50aXR5XCJdJyk7XG5cbiAgICAgICAgLy8gU2ltcGFuIG5pbGFpIHBoeXNpY2FsIHF1YW50aXR5IHlhbmcgc3VkYWggYWRhXG4gICAgICAgIGNvbnN0IGN1cnJlbnRQaHlzaWNhbFF0eSA9IHBoeXNpY2FsUXR5SW5wdXQudmFsKCk7XG5cbiAgICAgICAgaWYgKHByb2R1Y3RJZCkge1xuICAgICAgICAgICAgZmV0Y2hTdG9ja0RhdGEoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN5c3RlbVF0eUlucHV0LnZhbChcIjBcIik7XG4gICAgICAgICAgICAvLyBLZW1iYWxpa2FuIG5pbGFpIHBoeXNpY2FsIHF1YW50aXR5IGppa2EgYWRhXG4gICAgICAgICAgICBpZiAoY3VycmVudFBoeXNpY2FsUXR5KSB7XG4gICAgICAgICAgICAgICAgcGh5c2ljYWxRdHlJbnB1dC52YWwoY3VycmVudFBoeXNpY2FsUXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhbGN1bGF0ZURpZmZlcmVuY2Uoc3lzdGVtUXR5SW5wdXRbMF0pO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBGdW5nc2kgdW50dWsgbWVuYW1iYWggYmFyaXMgcHJvZHVrXG4gICAgJChcIiNidG4tYWRkLXJvd1wiKS5jbGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwcm9kdWN0LXJvdy10ZW1wbGF0ZVwiKTtcbiAgICAgICAgY29uc3QgdGJvZHkgPSAkKFwiI3Byb2R1Y3QtdGFibGUgdGJvZHlcIik7XG4gICAgICAgIGNvbnN0IG5ld1JvdyA9IHRlbXBsYXRlLmNvbnRlbnQuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICBjb25zdCByb3dJbmRleCA9ICQoXCIucHJvZHVjdC1yb3dcIikubGVuZ3RoO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBuYW1lIGF0dHJpYnV0ZXMgd2l0aCBjb3JyZWN0IGluZGV4XG4gICAgICAgICQobmV3Um93KVxuICAgICAgICAgICAgLmZpbmQoJ3NlbGVjdFtuYW1lPVwicHJvZHVjdFtdXCJdJylcbiAgICAgICAgICAgIC5hdHRyKFwibmFtZVwiLCBgcHJvZHVjdFske3Jvd0luZGV4fV1gKTtcbiAgICAgICAgJChuZXdSb3cpXG4gICAgICAgICAgICAuZmluZCgnaW5wdXRbbmFtZT1cInN5c3RlbV9xdWFudGl0eVtdXCJdJylcbiAgICAgICAgICAgIC5hdHRyKFwibmFtZVwiLCBgc3lzdGVtX3F1YW50aXR5WyR7cm93SW5kZXh9XWApO1xuICAgICAgICAkKG5ld1JvdylcbiAgICAgICAgICAgIC5maW5kKCdpbnB1dFtuYW1lPVwicGh5c2ljYWxfcXVhbnRpdHlbXVwiXScpXG4gICAgICAgICAgICAuYXR0cihcIm5hbWVcIiwgYHBoeXNpY2FsX3F1YW50aXR5WyR7cm93SW5kZXh9XWApO1xuICAgICAgICAkKG5ld1JvdylcbiAgICAgICAgICAgIC5maW5kKCdpbnB1dFtuYW1lPVwiaXRlbV9ub3Rlc1tdXCJdJylcbiAgICAgICAgICAgIC5hdHRyKFwibmFtZVwiLCBgaXRlbV9ub3Rlc1ske3Jvd0luZGV4fV1gKTtcblxuICAgICAgICAvLyBBZGQgc3lzdGVtLXF1YW50aXR5IGNsYXNzIGRhbiBwYXN0aWthbiByZWFkb25seVxuICAgICAgICBjb25zdCBzeXN0ZW1RdHlJbnB1dCA9ICQobmV3Um93KS5maW5kKFxuICAgICAgICAgICAgJ2lucHV0W25hbWU9XCJzeXN0ZW1fcXVhbnRpdHlbXVwiXSdcbiAgICAgICAgKTtcbiAgICAgICAgc3lzdGVtUXR5SW5wdXRcbiAgICAgICAgICAgIC5hZGRDbGFzcyhcInN5c3RlbS1xdWFudGl0eVwiKVxuICAgICAgICAgICAgLmF0dHIoXCJyZWFkb25seVwiLCB0cnVlKVxuICAgICAgICAgICAgLnZhbChcIjBcIik7XG5cbiAgICAgICAgLy8gUmVzZXQgc2VtdWEgbmlsYWkgaW5wdXQgZGkgYmFyaXMgYmFydSBrZWN1YWxpIHN5c3RlbSBxdWFudGl0eVxuICAgICAgICAkKG5ld1JvdykuZmluZChcInNlbGVjdFwiKS52YWwoXCJcIik7XG4gICAgICAgICQobmV3Um93KS5maW5kKFwiaW5wdXQ6bm90KC5zeXN0ZW0tcXVhbnRpdHkpXCIpLnZhbChcIlwiKTtcblxuICAgICAgICB0Ym9keS5hcHBlbmQobmV3Um93KTtcbiAgICAgICAgdXBkYXRlUmVtb3ZlQnV0dG9ucygpO1xuICAgIH0pO1xuXG4gICAgLy8gRnVuZ3NpIHVudHVrIG1lbmdoYXB1cyBiYXJpcyBwcm9kdWtcbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1yZW1vdmUtcm93XCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJCh0aGlzKS5jbG9zZXN0KFwidHJcIikucmVtb3ZlKCk7XG4gICAgICAgIHVwZGF0ZVJlbW92ZUJ1dHRvbnMoKTtcbiAgICAgICAgLy8gUmVpbmRleCBzZW11YSBiYXJpcyBzZXRlbGFoIHBlbmdoYXB1c2FuXG4gICAgICAgIHJlaW5kZXhSb3dzKCk7XG4gICAgfSk7XG5cbiAgICAvLyBGdW5nc2kgdW50dWsgdXBkYXRlIHN0YXR1cyB0b21ib2wgaGFwdXNcbiAgICBmdW5jdGlvbiB1cGRhdGVSZW1vdmVCdXR0b25zKCkge1xuICAgICAgICBjb25zdCByb3dzID0gJChcIi5wcm9kdWN0LXJvd1wiKS5sZW5ndGg7XG4gICAgICAgICQoXCIuYnRuLXJlbW92ZS1yb3dcIikucHJvcChcImRpc2FibGVkXCIsIHJvd3MgPD0gMSk7XG4gICAgfVxuXG4gICAgLy8gRnVuZ3NpIHVudHVrIHJlaW5kZXggc2VtdWEgYmFyaXNcbiAgICBmdW5jdGlvbiByZWluZGV4Um93cygpIHtcbiAgICAgICAgJChcIi5wcm9kdWN0LXJvd1wiKS5lYWNoKGZ1bmN0aW9uIChpbmRleCkge1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCdzZWxlY3RbbmFtZV49XCJwcm9kdWN0XCJdJylcbiAgICAgICAgICAgICAgICAuYXR0cihcIm5hbWVcIiwgYHByb2R1Y3RbJHtpbmRleH1dYCk7XG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLmZpbmQoJ2lucHV0W25hbWVePVwic3lzdGVtX3F1YW50aXR5XCJdJylcbiAgICAgICAgICAgICAgICAuYXR0cihcIm5hbWVcIiwgYHN5c3RlbV9xdWFudGl0eVske2luZGV4fV1gKTtcbiAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgnaW5wdXRbbmFtZV49XCJwaHlzaWNhbF9xdWFudGl0eVwiXScpXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJuYW1lXCIsIGBwaHlzaWNhbF9xdWFudGl0eVske2luZGV4fV1gKTtcbiAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgnaW5wdXRbbmFtZV49XCJpdGVtX25vdGVzXCJdJylcbiAgICAgICAgICAgICAgICAuYXR0cihcIm5hbWVcIiwgYGl0ZW1fbm90ZXNbJHtpbmRleH1dYCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSBjYWxjdWxhdGVEaWZmZXJlbmNlIGZ1bmN0aW9uXG4gICAgZnVuY3Rpb24gY2FsY3VsYXRlRGlmZmVyZW5jZShpbnB1dCkge1xuICAgICAgICBjb25zdCByb3cgPSAkKGlucHV0KS5jbG9zZXN0KFwidHJcIik7XG4gICAgICAgIGNvbnN0IHN5c3RlbVF0eSA9IHBhcnNlRmxvYXQocm93LmZpbmQoXCIuc3lzdGVtLXF1YW50aXR5XCIpLnZhbCgpKSB8fCAwO1xuICAgICAgICBjb25zdCBwaHlzaWNhbFF0eSA9XG4gICAgICAgICAgICBwYXJzZUZsb2F0KHJvdy5maW5kKCdpbnB1dFtuYW1lXj1cInBoeXNpY2FsX3F1YW50aXR5XCJdJykudmFsKCkpIHx8IDA7XG4gICAgICAgIGNvbnN0IG5vdGVJbnB1dCA9IHJvdy5maW5kKCdpbnB1dFtuYW1lXj1cIml0ZW1fbm90ZXNcIl0nKTtcblxuICAgICAgICBpZiAoTWF0aC5hYnMoc3lzdGVtUXR5IC0gcGh5c2ljYWxRdHkpID4gMC4wMSkge1xuICAgICAgICAgICAgbm90ZUlucHV0LmFkZENsYXNzKFwiaXMtaW52YWxpZFwiKTtcbiAgICAgICAgICAgIG5vdGVJbnB1dC5hdHRyKFwicmVxdWlyZWRcIiwgdHJ1ZSk7XG4gICAgICAgICAgICBub3RlSW5wdXQuYXR0cihcbiAgICAgICAgICAgICAgICBcInBsYWNlaG9sZGVyXCIsXG4gICAgICAgICAgICAgICAgXCJDYXRhdGFuIHdhamliIGRpaXNpIGthcmVuYSBhZGEgcGVyYmVkYWFuIHN0b2NrXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByb3cuYWRkQ2xhc3MoXCJ0YWJsZS13YXJuaW5nXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbm90ZUlucHV0LnJlbW92ZUNsYXNzKFwiaXMtaW52YWxpZFwiKTtcbiAgICAgICAgICAgIG5vdGVJbnB1dC5yZW1vdmVBdHRyKFwicmVxdWlyZWRcIik7XG4gICAgICAgICAgICBub3RlSW5wdXQuYXR0cihcInBsYWNlaG9sZGVyXCIsIFwiQ2F0YXRhbiBpdGVtXCIpO1xuICAgICAgICAgICAgcm93LnJlbW92ZUNsYXNzKFwidGFibGUtd2FybmluZ1wiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFByZXZlbnQgbWFudWFsIGVkaXRpbmcgb2Ygc3lzdGVtIHF1YW50aXR5XG4gICAgJChkb2N1bWVudCkub24oXCJrZXlkb3duXCIsIFwiLnN5c3RlbS1xdWFudGl0eVwiLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9KTtcblxuICAgICQoZG9jdW1lbnQpLm9uKFwicGFzdGVcIiwgXCIuc3lzdGVtLXF1YW50aXR5XCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuXG4gICAgLy8gVmFsaWRhc2kgZm9ybSBzZWJlbHVtIHN1Ym1pdFxuICAgICQoXCIjb3BuYW1lLWZvcm1cIikuc3VibWl0KGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGNvbnN0IGRlYWxlcklkID0gJChcIiNkZWFsZXJcIikudmFsKCk7XG4gICAgICAgIGlmICghZGVhbGVySWQpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGFsZXJ0KFwiU2lsYWthbiBwaWxpaCBkZWFsZXIgdGVybGViaWggZGFodWx1IVwiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByb2R1Y3RzID0gJCgnc2VsZWN0W25hbWVePVwicHJvZHVjdFwiXScpXG4gICAgICAgICAgICAubWFwKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJCh0aGlzKS52YWwoKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuZ2V0KCk7XG5cbiAgICAgICAgLy8gQ2VrIGR1cGxpa2FzaSBwcm9kdWtcbiAgICAgICAgY29uc3QgdW5pcXVlUHJvZHVjdHMgPSBbLi4ubmV3IFNldChwcm9kdWN0cyldO1xuICAgICAgICBpZiAocHJvZHVjdHMubGVuZ3RoICE9PSB1bmlxdWVQcm9kdWN0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGFsZXJ0KFwiUHJvZHVrIHRpZGFrIGJvbGVoIGR1cGxpa2F0IVwiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENlayBwcm9kdWsga29zb25nXG4gICAgICAgIGlmIChwcm9kdWN0cy5pbmNsdWRlcyhcIlwiKSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgYWxlcnQoXCJTZW11YSBwcm9kdWsgaGFydXMgZGlwaWxpaCFcIik7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDZWsgY2F0YXRhbiB1bnR1ayBwZXJiZWRhYW4gc3RvY2tcbiAgICAgICAgbGV0IGhhc0ludmFsaWROb3RlcyA9IGZhbHNlO1xuICAgICAgICAkKFwiLnByb2R1Y3Qtcm93XCIpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3Qgc3lzdGVtUXR5ID1cbiAgICAgICAgICAgICAgICBwYXJzZUZsb2F0KFxuICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLmZpbmQoJ2lucHV0W25hbWVePVwic3lzdGVtX3F1YW50aXR5XCJdJykudmFsKClcbiAgICAgICAgICAgICAgICApIHx8IDA7XG4gICAgICAgICAgICBjb25zdCBwaHlzaWNhbFF0eSA9XG4gICAgICAgICAgICAgICAgcGFyc2VGbG9hdChcbiAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5maW5kKCdpbnB1dFtuYW1lXj1cInBoeXNpY2FsX3F1YW50aXR5XCJdJykudmFsKClcbiAgICAgICAgICAgICAgICApIHx8IDA7XG4gICAgICAgICAgICBjb25zdCBub3RlID0gJCh0aGlzKS5maW5kKCdpbnB1dFtuYW1lXj1cIml0ZW1fbm90ZXNcIl0nKS52YWwoKTtcblxuICAgICAgICAgICAgaWYgKE1hdGguYWJzKHN5c3RlbVF0eSAtIHBoeXNpY2FsUXR5KSA+IDAuMDEgJiYgIW5vdGUpIHtcbiAgICAgICAgICAgICAgICBoYXNJbnZhbGlkTm90ZXMgPSB0cnVlO1xuICAgICAgICAgICAgICAgICQodGhpcykuYWRkQ2xhc3MoXCJ0YWJsZS1kYW5nZXJcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChoYXNJbnZhbGlkTm90ZXMpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGFsZXJ0KFxuICAgICAgICAgICAgICAgIFwiQ2F0YXRhbiB3YWppYiBkaWlzaSB1bnR1ayBwcm9kdWsgeWFuZyBtZW1pbGlraSBwZXJiZWRhYW4gc3RvY2shXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIEluaXRpYWwgc3RvY2sgZGF0YSBsb2FkIGlmIGRlYWxlciBpcyBzZWxlY3RlZFxuICAgIGlmICgkKFwiI2RlYWxlclwiKS52YWwoKSkge1xuICAgICAgICBmZXRjaFN0b2NrRGF0YSgpO1xuICAgIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQUEsQ0FBQyxDQUFDQyxRQUFELENBQUQsQ0FBWUMsS0FBWixDQUFrQixZQUFZO0VBQzFCO0VBQ0EsU0FBU0MsY0FBVCxHQUEwQjtJQUN0QixJQUFNQyxRQUFRLEdBQUdKLENBQUMsQ0FBQyxTQUFELENBQUQsQ0FBYUssR0FBYixFQUFqQjtJQUNBLElBQUksQ0FBQ0QsUUFBTCxFQUFlO0lBRWYsSUFBTUUsVUFBVSxHQUFHTixDQUFDLENBQUMsaUJBQUQsQ0FBRCxDQUNkTyxHQURjLENBQ1YsWUFBWTtNQUNiLE9BQU9QLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUUssR0FBUixFQUFQO0lBQ0gsQ0FIYyxFQUlkRyxHQUpjLEdBS2RDLE1BTGMsQ0FLUCxVQUFDQyxFQUFEO01BQUEsT0FBUUEsRUFBRSxLQUFLLEVBQWY7SUFBQSxDQUxPLENBQW5CO0lBT0EsSUFBSUosVUFBVSxDQUFDSyxNQUFYLEtBQXNCLENBQTFCLEVBQTZCO0lBRTdCWCxDQUFDLENBQUNZLElBQUYsQ0FBTztNQUNIQyxHQUFHLEVBQUUsbUNBREY7TUFFSEMsTUFBTSxFQUFFLE1BRkw7TUFHSEMsSUFBSSxFQUFFO1FBQ0ZDLE1BQU0sRUFBRWhCLENBQUMsQ0FBQyx5QkFBRCxDQUFELENBQTZCaUIsSUFBN0IsQ0FBa0MsU0FBbEMsQ0FETjtRQUVGQyxTQUFTLEVBQUVkLFFBRlQ7UUFHRmUsV0FBVyxFQUFFYjtNQUhYLENBSEg7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LENBQUQsQ0FBa0J1QixJQUFsQixDQUF1QixZQUFZO01BQy9CLElBQU1pQyxTQUFTLEdBQ1hDLFVBQVUsQ0FDTnpELENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUXlCLElBQVIsQ0FBYSxnQ0FBYixFQUErQ3BCLEdBQS9DLEVBRE0sQ0FBVixJQUVLLENBSFQ7TUFJQSxJQUFNcUQsV0FBVyxHQUNiRCxVQUFVLENBQ056RCxDQUFDLENBQUMsSUFBRCxDQUFELENBQVF5QixJQUFSLENBQWEsa0NBQWIsRUFBaURwQixHQUFqRCxFQURNLENBQVYsSUFFSyxDQUhUO01BSUEsSUFBTW9FLElBQUksR0FBR3pFLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUXlCLElBQVIsQ0FBYSwyQkFBYixFQUEwQ3BCLEdBQTFDLEVBQWI7O01BRUEsSUFBSXVELElBQUksQ0FBQ0MsR0FBTCxDQUFTTCxTQUFTLEdBQUdFLFdBQXJCLElBQW9DLElBQXBDLElBQTRDLENBQUNlLElBQWpELEVBQXVEO1FBQ25ERCxlQUFlLEdBQUcsSUFBbEI7UUFDQXhFLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUStDLFFBQVIsQ0FBaUIsY0FBakI7TUFDSDtJQUNKLENBZkQ7O0lBaUJBLElBQUl5QixlQUFKLEVBQXFCO01BQ2pCUixDQUFDLENBQUNDLGNBQUY7TUFDQUUsS0FBSyxDQUNELGlFQURDLENBQUw7TUFHQSxPQUFPLEtBQVA7SUFDSDtFQUNKLENBdkRELEVBL0wwQixDQXdQMUI7O0VBQ0EsSUFBSW5FLENBQUMsQ0FBQyxTQUFELENBQUQsQ0FBYUssR0FBYixFQUFKLEVBQXdCO0lBQ3BCRixjQUFjO0VBQ2pCO0FBQ0osQ0E1UEQiLCJmaWxlIjoiLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvb3BuYW1lcy9jcmVhdGUuanMiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/opnames/create.js\n");
/***/ })
diff --git a/public/js/warehouse_management/products/index.js b/public/js/warehouse_management/products/index.js
index 636b000..db46aae 100644
--- a/public/js/warehouse_management/products/index.js
+++ b/public/js/warehouse_management/products/index.js
@@ -15,7 +15,7 @@
\*************************************************************/
/***/ (() => {
-eval("$.ajaxSetup({\n headers: {\n \"X-CSRF-TOKEN\": $('meta[name=\"csrf-token\"]').attr(\"content\")\n }\n});\nvar tableContainer = $(\"#products-table\");\nvar url = tableContainer.data(\"url\");\nvar table = $(\"#products-table\").DataTable({\n processing: true,\n serverSide: true,\n ajax: url,\n columns: [{\n data: \"code\",\n name: \"code\"\n }, {\n data: \"name\",\n name: \"name\"\n }, {\n data: \"category_name\",\n name: \"category.name\"\n }, {\n data: \"unit\",\n name: \"unit\"\n }, {\n data: \"total_stock\",\n name: \"total_stock\",\n orderable: false,\n searchable: false\n }, {\n data: \"action\",\n name: \"action\",\n orderable: false,\n searchable: false\n }]\n});\n$(document).on(\"click\", \".btn-destroy-product\", function () {\n var _this = this;\n\n Swal.fire({\n title: \"Hapus produk?\",\n text: \"Anda tidak akan bisa mengembalikannya!\",\n showCancelButton: true,\n confirmButtonColor: \"#d33\",\n cancelButtonColor: \"#dedede\",\n confirmButtonText: \"Hapus\"\n }).then(function (result) {\n if (result.value) {\n var _url = $(_this).data(\"action\");\n\n $.ajax({\n url: _url,\n method: \"POST\",\n data: {\n _method: \"DELETE\",\n _token: $('meta[name=\"csrf-token\"]').attr(\"content\")\n },\n success: function success() {\n alert(\"Produk berhasil dihapus.\");\n $(\"#products-table\").DataTable().ajax.reload();\n },\n error: function error(xhr) {\n alert(\"Gagal menghapus produk.\");\n console.error(xhr.responseText);\n }\n });\n }\n });\n});\n$(document).on(\"click\", \".btn-toggle-active\", function () {\n var button = $(this);\n var url = button.data(\"url\");\n Swal.fire({\n title: \"Status produk?\",\n text: \"Anda yakin ingin mengganti status produk!\",\n showCancelButton: true,\n confirmButtonColor: \"#d33\",\n cancelButtonColor: \"#dedede\",\n confirmButtonText: \"Ya\"\n }).then(function (result) {\n if (result.value) {\n $.ajax({\n url: url,\n method: \"POST\",\n data: {\n _token: $('meta[name=\"csrf-token\"]').attr(\"content\")\n },\n success: function success(response) {\n if (response.success) {\n $(\"#products-table\").DataTable().ajax.reload(null, false);\n alert(response.message);\n }\n },\n error: function error() {\n alert(\"Gagal mengubah status produk.\");\n }\n });\n }\n });\n});\n$(document).on(\"click\", \".btn-product-stock-dealers\", function () {\n var productId = $(this).data(\"id\");\n var productName = $(this).data(\"name\");\n var ajaxUrl = $(this).data(\"url\"); // Set product name in modal title\n\n $(\"#product-name-title\").text(productName); // Initialize or reload DataTable inside modal\n\n $(\"#dealer-stock-table\").DataTable({\n destroy: true,\n // reinit if exists\n processing: true,\n serverSide: true,\n ajax: {\n url: ajaxUrl,\n data: {\n product_id: productId\n }\n },\n columns: [{\n data: \"dealer_name\",\n name: \"dealer_name\"\n }, {\n data: \"system_stock\",\n name: \"system_stock\"\n }, {\n data: \"physical_stock\",\n name: \"physical_stock\"\n }, {\n data: \"difference\",\n name: \"difference\"\n }, {\n data: \"opname_date\",\n name: \"opname_date\"\n }],\n initComplete: function initComplete() {\n $(\"#dealerStockModal\").modal(\"show\");\n }\n });\n});\n$(document).on(\"click\", \"#dealerStockModal .close\", function () {\n $(\"#dealerStockModal\").modal(\"hide\");\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyIkIiwiYWpheFNldHVwIiwiaGVhZGVycyIsImF0dHIiLCJ0YWJsZUNvbnRhaW5lciIsInVybCIsImRhdGEiLCJ0YWJsZSIsIkRhdGFUYWJsZSIsInByb2Nlc3NpbmciLCJzZXJ2ZXJTaWRlIiwiYWpheCIsImNvbHVtbnMiLCJuYW1lIiwib3JkZXJhYmxlIiwic2VhcmNoYWJsZSIsImRvY3VtZW50Iiwib24iLCJTd2FsIiwiZmlyZSIsInRpdGxlIiwidGV4dCIsInNob3dDYW5jZWxCdXR0b24iLCJjb25maXJtQnV0dG9uQ29sb3IiLCJjYW5jZWxCdXR0b25Db2xvciIsImNvbmZpcm1CdXR0b25UZXh0IiwidGhlbiIsInJlc3VsdCIsInZhbHVlIiwibWV0aG9kIiwiX21ldGhvZCIsIl90b2tlbiIsInN1Y2Nlc3MiLCJhbGVydCIsInJlbG9hZCIsImVycm9yIiwieGhyIiwiY29uc29sZSIsInJlc3BvbnNlVGV4dCIsImJ1dHRvbiIsInJlc3BvbnNlIiwibWVzc2FnZSIsInByb2R1Y3RJZCIsInByb2R1Y3ROYW1lIiwiYWpheFVybCIsImRlc3Ryb3kiLCJwcm9kdWN0X2lkIiwiaW5pdENvbXBsZXRlIiwibW9kYWwiXSwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL3dhcmVob3VzZV9tYW5hZ2VtZW50L3Byb2R1Y3RzL2luZGV4LmpzP2ZjZDYiXSwic291cmNlc0NvbnRlbnQiOlsiJC5hamF4U2V0dXAoe1xuICAgIGhlYWRlcnM6IHtcbiAgICAgICAgXCJYLUNTUkYtVE9LRU5cIjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgIH0sXG59KTtcbmxldCB0YWJsZUNvbnRhaW5lciA9ICQoXCIjcHJvZHVjdHMtdGFibGVcIik7XG5sZXQgdXJsID0gdGFibGVDb250YWluZXIuZGF0YShcInVybFwiKTtcbmxldCB0YWJsZSA9ICQoXCIjcHJvZHVjdHMtdGFibGVcIikuRGF0YVRhYmxlKHtcbiAgICBwcm9jZXNzaW5nOiB0cnVlLFxuICAgIHNlcnZlclNpZGU6IHRydWUsXG4gICAgYWpheDogdXJsLFxuICAgIGNvbHVtbnM6IFtcbiAgICAgICAgeyBkYXRhOiBcImNvZGVcIiwgbmFtZTogXCJjb2RlXCIgfSxcbiAgICAgICAgeyBkYXRhOiBcIm5hbWVcIiwgbmFtZTogXCJuYW1lXCIgfSxcbiAgICAgICAgeyBkYXRhOiBcImNhdGVnb3J5X25hbWVcIiwgbmFtZTogXCJjYXRlZ29yeS5uYW1lXCIgfSxcbiAgICAgICAgeyBkYXRhOiBcInVuaXRcIiwgbmFtZTogXCJ1bml0XCIgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgZGF0YTogXCJ0b3RhbF9zdG9ja1wiLFxuICAgICAgICAgICAgbmFtZTogXCJ0b3RhbF9zdG9ja1wiLFxuICAgICAgICAgICAgb3JkZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICB7IGRhdGE6IFwiYWN0aW9uXCIsIG5hbWU6IFwiYWN0aW9uXCIsIG9yZGVyYWJsZTogZmFsc2UsIHNlYXJjaGFibGU6IGZhbHNlIH0sXG4gICAgXSxcbn0pO1xuXG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1kZXN0cm95LXByb2R1Y3RcIiwgZnVuY3Rpb24gKCkge1xuICAgIFN3YWwuZmlyZSh7XG4gICAgICAgIHRpdGxlOiBcIkhhcHVzIHByb2R1az9cIixcbiAgICAgICAgdGV4dDogXCJBbmRhIHRpZGFrIGFrYW4gYmlzYSBtZW5nZW1iYWxpa2FubnlhIVwiLFxuICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiB0cnVlLFxuICAgICAgICBjb25maXJtQnV0dG9uQ29sb3I6IFwiI2QzM1wiLFxuICAgICAgICBjYW5jZWxCdXR0b25Db2xvcjogXCIjZGVkZWRlXCIsXG4gICAgICAgIGNvbmZpcm1CdXR0b25UZXh0OiBcIkhhcHVzXCIsXG4gICAgfSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQudmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9ICQodGhpcykuZGF0YShcImFjdGlvblwiKTtcbiAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIF9tZXRob2Q6IFwiREVMRVRFXCIsXG4gICAgICAgICAgICAgICAgICAgIF90b2tlbjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChcIlByb2R1ayBiZXJoYXNpbCBkaWhhcHVzLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgJChcIiNwcm9kdWN0cy10YWJsZVwiKS5EYXRhVGFibGUoKS5hamF4LnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICh4aHIpIHtcbiAgICAgICAgICAgICAgICAgICAgYWxlcnQoXCJHYWdhbCBtZW5naGFwdXMgcHJvZHVrLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcih4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn0pO1xuJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi5idG4tdG9nZ2xlLWFjdGl2ZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGJ1dHRvbiA9ICQodGhpcyk7XG4gICAgbGV0IHVybCA9IGJ1dHRvbi5kYXRhKFwidXJsXCIpO1xuXG4gICAgU3dhbC5maXJlKHtcbiAgICAgICAgdGl0bGU6IFwiU3RhdHVzIHByb2R1az9cIixcbiAgICAgICAgdGV4dDogXCJBbmRhIHlha2luIGluZ2luIG1lbmdnYW50aSBzdGF0dXMgcHJvZHVrIVwiLFxuICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiB0cnVlLFxuICAgICAgICBjb25maXJtQnV0dG9uQ29sb3I6IFwiI2QzM1wiLFxuICAgICAgICBjYW5jZWxCdXR0b25Db2xvcjogXCIjZGVkZWRlXCIsXG4gICAgICAgIGNvbmZpcm1CdXR0b25UZXh0OiBcIllhXCIsXG4gICAgfSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQudmFsdWUpIHtcbiAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIF90b2tlbjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKFwiI3Byb2R1Y3RzLXRhYmxlXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLkRhdGFUYWJsZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFqYXgucmVsb2FkKG51bGwsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChcIkdhZ2FsIG1lbmd1YmFoIHN0YXR1cyBwcm9kdWsuXCIpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xufSk7XG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1wcm9kdWN0LXN0b2NrLWRlYWxlcnNcIiwgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHByb2R1Y3RJZCA9ICQodGhpcykuZGF0YShcImlkXCIpO1xuICAgIGNvbnN0IHByb2R1Y3ROYW1lID0gJCh0aGlzKS5kYXRhKFwibmFtZVwiKTtcbiAgICBjb25zdCBhamF4VXJsID0gJCh0aGlzKS5kYXRhKFwidXJsXCIpO1xuXG4gICAgLy8gU2V0IHByb2R1Y3QgbmFtZSBpbiBtb2RhbCB0aXRsZVxuICAgICQoXCIjcHJvZHVjdC1uYW1lLXRpdGxlXCIpLnRleHQocHJvZHVjdE5hbWUpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBvciByZWxvYWQgRGF0YVRhYmxlIGluc2lkZSBtb2RhbFxuICAgICQoXCIjZGVhbGVyLXN0b2NrLXRhYmxlXCIpLkRhdGFUYWJsZSh7XG4gICAgICAgIGRlc3Ryb3k6IHRydWUsIC8vIHJlaW5pdCBpZiBleGlzdHNcbiAgICAgICAgcHJvY2Vzc2luZzogdHJ1ZSxcbiAgICAgICAgc2VydmVyU2lkZTogdHJ1ZSxcbiAgICAgICAgYWpheDoge1xuICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIHByb2R1Y3RfaWQ6IHByb2R1Y3RJZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGNvbHVtbnM6IFtcbiAgICAgICAgICAgIHsgZGF0YTogXCJkZWFsZXJfbmFtZVwiLCBuYW1lOiBcImRlYWxlcl9uYW1lXCIgfSxcbiAgICAgICAgICAgIHsgZGF0YTogXCJzeXN0ZW1fc3RvY2tcIiwgbmFtZTogXCJzeXN0ZW1fc3RvY2tcIiB9LFxuICAgICAgICAgICAgeyBkYXRhOiBcInBoeXNpY2FsX3N0b2NrXCIsIG5hbWU6IFwicGh5c2ljYWxfc3RvY2tcIiB9LFxuICAgICAgICAgICAgeyBkYXRhOiBcImRpZmZlcmVuY2VcIiwgbmFtZTogXCJkaWZmZXJlbmNlXCIgfSxcbiAgICAgICAgICAgIHsgZGF0YTogXCJvcG5hbWVfZGF0ZVwiLCBuYW1lOiBcIm9wbmFtZV9kYXRlXCIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaW5pdENvbXBsZXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkKFwiI2RlYWxlclN0b2NrTW9kYWxcIikubW9kYWwoXCJzaG93XCIpO1xuICAgICAgICB9LFxuICAgIH0pO1xufSk7XG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiI2RlYWxlclN0b2NrTW9kYWwgLmNsb3NlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAkKFwiI2RlYWxlclN0b2NrTW9kYWxcIikubW9kYWwoXCJoaWRlXCIpO1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBQSxDQUFDLENBQUNDLFNBQUYsQ0FBWTtFQUNSQyxPQUFPLEVBQUU7SUFDTCxnQkFBZ0JGLENBQUMsQ0FBQyx5QkFBRCxDQUFELENBQTZCRyxJQUE3QixDQUFrQyxTQUFsQztFQURYO0FBREQsQ0FBWjtBQUtBLElBQUlDLGNBQWMsR0FBR0osQ0FBQyxDQUFDLGlCQUFELENBQXRCO0FBQ0EsSUFBSUssR0FBRyxHQUFHRCxjQUFjLENBQUNFLElBQWYsQ0FBb0IsS0FBcEIsQ0FBVjtBQUNBLElBQUlDLEtBQUssR0FBR1AsQ0FBQyxDQUFDLGlCQUFELENBQUQsQ0FBcUJRLFNBQXJCLENBQStCO0VBQ3ZDQyxVQUFVLEVBQUUsSUFEMkI7RUFFdkNDLFVBQVUsRUFBRSxJQUYyQjtFQUd2Q0MsSUFBSSxFQUFFTixHQUhpQztFQUl2Q08sT0FBTyxFQUFFLENBQ0w7SUFBRU4sSUFBSSxFQUFFLE1BQVI7SUFBZ0JPLElBQUksRUFBRTtFQUF0QixDQURLLEVBRUw7SUFBRVAsSUFBSSxFQUFFLE1BQVI7SUFBZ0JPLElBQUksRUFBRTtFQUF0QixDQUZLLEVBR0w7SUFBRVAs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QUksRUFBRSxjQUFSO01BQXdCTyxJQUFJLEVBQUU7SUFBOUIsQ0FGSyxFQUdMO01BQUVQLElBQUksRUFBRSxnQkFBUjtNQUEwQk8sSUFBSSxFQUFFO0lBQWhDLENBSEssRUFJTDtNQUFFUCxJQUFJLEVBQUUsWUFBUjtNQUFzQk8sSUFBSSxFQUFFO0lBQTVCLENBSkssRUFLTDtNQUFFUCxJQUFJLEVBQUUsYUFBUjtNQUF1Qk8sSUFBSSxFQUFFO0lBQTdCLENBTEssQ0FWc0I7SUFpQi9Ca0MsWUFBWSxFQUFFLHdCQUFZO01BQ3RCL0MsQ0FBQyxDQUFDLG1CQUFELENBQUQsQ0FBdUJnRCxLQUF2QixDQUE2QixNQUE3QjtJQUNIO0VBbkI4QixDQUFuQztBQXFCSCxDQTlCRDtBQStCQWhELENBQUMsQ0FBQ2dCLFFBQUQsQ0FBRCxDQUFZQyxFQUFaLENBQWUsT0FBZixFQUF3QiwwQkFBeEIsRUFBb0QsWUFBWTtFQUM1RGpCLENBQUMsQ0FBQyxtQkFBRCxDQUFELENBQXVCZ0QsS0FBdkIsQ0FBNkIsTUFBN0I7QUFDSCxDQUZEIiwiZmlsZSI6Ii4vcmVzb3VyY2VzL2pzL3dhcmVob3VzZV9tYW5hZ2VtZW50L3Byb2R1Y3RzL2luZGV4LmpzIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/products/index.js\n");
+eval("$.ajaxSetup({\n headers: {\n \"X-CSRF-TOKEN\": $('meta[name=\"csrf-token\"]').attr(\"content\")\n }\n});\nvar tableContainer = $(\"#products-table\");\nvar url = tableContainer.data(\"url\");\nvar table = $(\"#products-table\").DataTable({\n processing: true,\n serverSide: true,\n ajax: url,\n columns: [{\n data: \"code\",\n name: \"code\"\n }, {\n data: \"name\",\n name: \"name\"\n }, {\n data: \"category_name\",\n name: \"category.name\"\n }, {\n data: \"unit\",\n name: \"unit\"\n }, {\n data: \"total_stock\",\n name: \"total_stock\",\n orderable: false,\n searchable: false\n }, {\n data: \"action\",\n name: \"action\",\n orderable: false,\n searchable: false\n }]\n});\n$(document).on(\"click\", \".btn-destroy-product\", function () {\n var _this = this;\n\n Swal.fire({\n title: \"Hapus produk?\",\n text: \"Anda tidak akan bisa mengembalikannya!\",\n showCancelButton: true,\n confirmButtonColor: \"#d33\",\n cancelButtonColor: \"#dedede\",\n confirmButtonText: \"Hapus\"\n }).then(function (result) {\n if (result.value) {\n var _url = $(_this).data(\"action\");\n\n $.ajax({\n url: _url,\n method: \"POST\",\n data: {\n _method: \"DELETE\",\n _token: $('meta[name=\"csrf-token\"]').attr(\"content\")\n },\n success: function success() {\n alert(\"Produk berhasil dihapus.\");\n $(\"#products-table\").DataTable().ajax.reload();\n },\n error: function error(xhr) {\n alert(\"Gagal menghapus produk.\");\n console.error(xhr.responseText);\n }\n });\n }\n });\n});\n$(document).on(\"click\", \".btn-toggle-active\", function () {\n var button = $(this);\n var url = button.data(\"url\");\n Swal.fire({\n title: \"Status produk?\",\n text: \"Anda yakin ingin mengganti status produk!\",\n showCancelButton: true,\n confirmButtonColor: \"#d33\",\n cancelButtonColor: \"#dedede\",\n confirmButtonText: \"Ya\"\n }).then(function (result) {\n if (result.value) {\n $.ajax({\n url: url,\n method: \"POST\",\n data: {\n _token: $('meta[name=\"csrf-token\"]').attr(\"content\")\n },\n success: function success(response) {\n if (response.success) {\n $(\"#products-table\").DataTable().ajax.reload(null, false);\n alert(response.message);\n }\n },\n error: function error() {\n alert(\"Gagal mengubah status produk.\");\n }\n });\n }\n });\n});\n$(document).on(\"click\", \".btn-product-stock-dealers\", function () {\n var productId = $(this).data(\"id\");\n var productName = $(this).data(\"name\");\n var ajaxUrl = $(this).data(\"url\"); // Set product name in modal title\n\n $(\"#product-name-title\").text(productName); // Initialize or reload DataTable inside modal\n\n $(\"#dealer-stock-table\").DataTable({\n destroy: true,\n // reinit if exists\n processing: true,\n serverSide: true,\n ajax: {\n url: ajaxUrl,\n data: {\n product_id: productId\n }\n },\n columns: [{\n data: \"dealer_name\",\n name: \"dealer_name\"\n }, {\n data: \"quantity\",\n name: \"quantity\"\n }],\n initComplete: function initComplete() {\n $(\"#dealerStockModal\").modal(\"show\");\n }\n });\n});\n$(document).on(\"click\", \"#dealerStockModal .close\", function () {\n $(\"#dealerStockModal\").modal(\"hide\");\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyIkIiwiYWpheFNldHVwIiwiaGVhZGVycyIsImF0dHIiLCJ0YWJsZUNvbnRhaW5lciIsInVybCIsImRhdGEiLCJ0YWJsZSIsIkRhdGFUYWJsZSIsInByb2Nlc3NpbmciLCJzZXJ2ZXJTaWRlIiwiYWpheCIsImNvbHVtbnMiLCJuYW1lIiwib3JkZXJhYmxlIiwic2VhcmNoYWJsZSIsImRvY3VtZW50Iiwib24iLCJTd2FsIiwiZmlyZSIsInRpdGxlIiwidGV4dCIsInNob3dDYW5jZWxCdXR0b24iLCJjb25maXJtQnV0dG9uQ29sb3IiLCJjYW5jZWxCdXR0b25Db2xvciIsImNvbmZpcm1CdXR0b25UZXh0IiwidGhlbiIsInJlc3VsdCIsInZhbHVlIiwibWV0aG9kIiwiX21ldGhvZCIsIl90b2tlbiIsInN1Y2Nlc3MiLCJhbGVydCIsInJlbG9hZCIsImVycm9yIiwieGhyIiwiY29uc29sZSIsInJlc3BvbnNlVGV4dCIsImJ1dHRvbiIsInJlc3BvbnNlIiwibWVzc2FnZSIsInByb2R1Y3RJZCIsInByb2R1Y3ROYW1lIiwiYWpheFVybCIsImRlc3Ryb3kiLCJwcm9kdWN0X2lkIiwiaW5pdENvbXBsZXRlIiwibW9kYWwiXSwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL3dhcmVob3VzZV9tYW5hZ2VtZW50L3Byb2R1Y3RzL2luZGV4LmpzP2ZjZDYiXSwic291cmNlc0NvbnRlbnQiOlsiJC5hamF4U2V0dXAoe1xuICAgIGhlYWRlcnM6IHtcbiAgICAgICAgXCJYLUNTUkYtVE9LRU5cIjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgIH0sXG59KTtcbmxldCB0YWJsZUNvbnRhaW5lciA9ICQoXCIjcHJvZHVjdHMtdGFibGVcIik7XG5sZXQgdXJsID0gdGFibGVDb250YWluZXIuZGF0YShcInVybFwiKTtcbmxldCB0YWJsZSA9ICQoXCIjcHJvZHVjdHMtdGFibGVcIikuRGF0YVRhYmxlKHtcbiAgICBwcm9jZXNzaW5nOiB0cnVlLFxuICAgIHNlcnZlclNpZGU6IHRydWUsXG4gICAgYWpheDogdXJsLFxuICAgIGNvbHVtbnM6IFtcbiAgICAgICAgeyBkYXRhOiBcImNvZGVcIiwgbmFtZTogXCJjb2RlXCIgfSxcbiAgICAgICAgeyBkYXRhOiBcIm5hbWVcIiwgbmFtZTogXCJuYW1lXCIgfSxcbiAgICAgICAgeyBkYXRhOiBcImNhdGVnb3J5X25hbWVcIiwgbmFtZTogXCJjYXRlZ29yeS5uYW1lXCIgfSxcbiAgICAgICAgeyBkYXRhOiBcInVuaXRcIiwgbmFtZTogXCJ1bml0XCIgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgZGF0YTogXCJ0b3RhbF9zdG9ja1wiLFxuICAgICAgICAgICAgbmFtZTogXCJ0b3RhbF9zdG9ja1wiLFxuICAgICAgICAgICAgb3JkZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICB7IGRhdGE6IFwiYWN0aW9uXCIsIG5hbWU6IFwiYWN0aW9uXCIsIG9yZGVyYWJsZTogZmFsc2UsIHNlYXJjaGFibGU6IGZhbHNlIH0sXG4gICAgXSxcbn0pO1xuXG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1kZXN0cm95LXByb2R1Y3RcIiwgZnVuY3Rpb24gKCkge1xuICAgIFN3YWwuZmlyZSh7XG4gICAgICAgIHRpdGxlOiBcIkhhcHVzIHByb2R1az9cIixcbiAgICAgICAgdGV4dDogXCJBbmRhIHRpZGFrIGFrYW4gYmlzYSBtZW5nZW1iYWxpa2FubnlhIVwiLFxuICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiB0cnVlLFxuICAgICAgICBjb25maXJtQnV0dG9uQ29sb3I6IFwiI2QzM1wiLFxuICAgICAgICBjYW5jZWxCdXR0b25Db2xvcjogXCIjZGVkZWRlXCIsXG4gICAgICAgIGNvbmZpcm1CdXR0b25UZXh0OiBcIkhhcHVzXCIsXG4gICAgfSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQudmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9ICQodGhpcykuZGF0YShcImFjdGlvblwiKTtcbiAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIF9tZXRob2Q6IFwiREVMRVRFXCIsXG4gICAgICAgICAgICAgICAgICAgIF90b2tlbjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChcIlByb2R1ayBiZXJoYXNpbCBkaWhhcHVzLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgJChcIiNwcm9kdWN0cy10YWJsZVwiKS5EYXRhVGFibGUoKS5hamF4LnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICh4aHIpIHtcbiAgICAgICAgICAgICAgICAgICAgYWxlcnQoXCJHYWdhbCBtZW5naGFwdXMgcHJvZHVrLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcih4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn0pO1xuJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi5idG4tdG9nZ2xlLWFjdGl2ZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGJ1dHRvbiA9ICQodGhpcyk7XG4gICAgbGV0IHVybCA9IGJ1dHRvbi5kYXRhKFwidXJsXCIpO1xuXG4gICAgU3dhbC5maXJlKHtcbiAgICAgICAgdGl0bGU6IFwiU3RhdHVzIHByb2R1az9cIixcbiAgICAgICAgdGV4dDogXCJBbmRhIHlha2luIGluZ2luIG1lbmdnYW50aSBzdGF0dXMgcHJvZHVrIVwiLFxuICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiB0cnVlLFxuICAgICAgICBjb25maXJtQnV0dG9uQ29sb3I6IFwiI2QzM1wiLFxuICAgICAgICBjYW5jZWxCdXR0b25Db2xvcjogXCIjZGVkZWRlXCIsXG4gICAgICAgIGNvbmZpcm1CdXR0b25UZXh0OiBcIllhXCIsXG4gICAgfSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQudmFsdWUpIHtcbiAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIF90b2tlbjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKFwiI3Byb2R1Y3RzLXRhYmxlXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLkRhdGFUYWJsZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFqYXgucmVsb2FkKG51bGwsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChcIkdhZ2FsIG1lbmd1YmFoIHN0YXR1cyBwcm9kdWsuXCIpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xufSk7XG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1wcm9kdWN0LXN0b2NrLWRlYWxlcnNcIiwgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHByb2R1Y3RJZCA9ICQodGhpcykuZGF0YShcImlkXCIpO1xuICAgIGNvbnN0IHByb2R1Y3ROYW1lID0gJCh0aGlzKS5kYXRhKFwibmFtZVwiKTtcbiAgICBjb25zdCBhamF4VXJsID0gJCh0aGlzKS5kYXRhKFwidXJsXCIpO1xuXG4gICAgLy8gU2V0IHByb2R1Y3QgbmFtZSBpbiBtb2RhbCB0aXRsZVxuICAgICQoXCIjcHJvZHVjdC1uYW1lLXRpdGxlXCIpLnRleHQocHJvZHVjdE5hbWUpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBvciByZWxvYWQgRGF0YVRhYmxlIGluc2lkZSBtb2RhbFxuICAgICQoXCIjZGVhbGVyLXN0b2NrLXRhYmxlXCIpLkRhdGFUYWJsZSh7XG4gICAgICAgIGRlc3Ryb3k6IHRydWUsIC8vIHJlaW5pdCBpZiBleGlzdHNcbiAgICAgICAgcHJvY2Vzc2luZzogdHJ1ZSxcbiAgICAgICAgc2VydmVyU2lkZTogdHJ1ZSxcbiAgICAgICAgYWpheDoge1xuICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIHByb2R1Y3RfaWQ6IHByb2R1Y3RJZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGNvbHVtbnM6IFtcbiAgICAgICAgICAgIHsgZGF0YTogXCJkZWFsZXJfbmFtZVwiLCBuYW1lOiBcImRlYWxlcl9uYW1lXCIgfSxcbiAgICAgICAgICAgIHsgZGF0YTogXCJxdWFudGl0eVwiLCBuYW1lOiBcInF1YW50aXR5XCIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaW5pdENvbXBsZXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkKFwiI2RlYWxlclN0b2NrTW9kYWxcIikubW9kYWwoXCJzaG93XCIpO1xuICAgICAgICB9LFxuICAgIH0pO1xufSk7XG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiI2RlYWxlclN0b2NrTW9kYWwgLmNsb3NlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAkKFwiI2RlYWxlclN0b2NrTW9kYWxcIikubW9kYWwoXCJoaWRlXCIpO1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBQSxDQUFDLENBQUNDLFNBQUYsQ0FBWTtFQUNSQyxPQUFPLEVBQUU7SUFDTCxnQkFBZ0JGLENBQUMsQ0FBQyx5QkFBRCxDQUFELENBQTZCRyxJQUE3QixDQUFrQyxTQUFsQztFQURYO0FBREQsQ0FBWjtBQUtBLElBQUlDLGNBQWMsR0FBR0osQ0FBQyxDQUFDLGlCQUFELENBQXRCO0FBQ0EsSUFBSUssR0FBRyxHQUFHRCxjQUFjLENBQUNFLElBQWYsQ0FBb0IsS0FBcEIsQ0FBVjtBQUNBLElBQUlDLEtBQUssR0FBR1AsQ0FBQyxDQUFDLGlCQUFELENBQUQsQ0FBcUJRLFNBQXJCLENBQStCO0VBQ3ZDQyxVQUFVLEVBQUUsSUFEMkI7RUFFdkNDLFVBQVUsRUFBRSxJQUYyQjtFQUd2Q0MsSUFBSSxFQUFFTixHQUhpQztFQUl2Q08sT0FBTyxFQUFFLENBQ0w7SUFBRU4sSUFBSSxFQUFFLE1BQVI7SUFBZ0JPLElBQUksRUFBRTtFQUF0QixDQURLLEVBRUw7SUFBRVAsSUFBSSxFQUFFLE1BQVI7SUFBZ0JPLElBQUksRUFBRTtFQUF0QixDQUZLLEVBR0w7SUFBRVAsSUFBSSxFQUFFLGVBQVI7SUFBeUJPLElBQUksRUFBRTtFQUEvQixDQUhLLEVBSUw7SUFBRVAsSUFBSSxFQUFFLE1BQVI7SUFBZ0JPLElBQUksRUFBRTtFQUF0QixDQUpLLEVBS0w7SUFDSVAsSUFBSSxFQUFFLGFBRFY7SUFFSU8sSUFBSSxFQUFFLGFBRlY7SUFHSUMsU0FBUyxFQUFFLEtBSGY7SUFJSUMsVUFBVSxFQUFFO0VBSmhCLENBTEssRUFXTDtJQUFF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O0lBa0JIO0VBQ0osQ0E1QkQ7QUE2QkgsQ0FqQ0Q7QUFrQ0FqQyxDQUFDLENBQUNnQixRQUFELENBQUQsQ0FBWUMsRUFBWixDQUFlLE9BQWYsRUFBd0IsNEJBQXhCLEVBQXNELFlBQVk7RUFDOUQsSUFBTXlCLFNBQVMsR0FBRzFDLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUU0sSUFBUixDQUFhLElBQWIsQ0FBbEI7RUFDQSxJQUFNcUMsV0FBVyxHQUFHM0MsQ0FBQyxDQUFDLElBQUQsQ0FBRCxDQUFRTSxJQUFSLENBQWEsTUFBYixDQUFwQjtFQUNBLElBQU1zQyxPQUFPLEdBQUc1QyxDQUFDLENBQUMsSUFBRCxDQUFELENBQVFNLElBQVIsQ0FBYSxLQUFiLENBQWhCLENBSDhELENBSzlEOztFQUNBTixDQUFDLENBQUMscUJBQUQsQ0FBRCxDQUF5QnFCLElBQXpCLENBQThCc0IsV0FBOUIsRUFOOEQsQ0FROUQ7O0VBQ0EzQyxDQUFDLENBQUMscUJBQUQsQ0FBRCxDQUF5QlEsU0FBekIsQ0FBbUM7SUFDL0JxQyxPQUFPLEVBQUUsSUFEc0I7SUFDaEI7SUFDZnBDLFVBQVUsRUFBRSxJQUZtQjtJQUcvQkMsVUFBVSxFQUFFLElBSG1CO0lBSS9CQyxJQUFJLEVBQUU7TUFDRk4sR0FBRyxFQUFFdUMsT0FESDtNQUVGdEMsSUFBSSxFQUFFO1FBQ0Z3QyxVQUFVLEVBQUVKO01BRFY7SUFGSixDQUp5QjtJQVUvQjlCLE9BQU8sRUFBRSxDQUNMO01BQUVOLElBQUksRUFBRSxhQUFSO01BQXVCTyxJQUFJLEVBQUU7SUFBN0IsQ0FESyxFQUVMO01BQUVQLElBQUksRUFBRSxVQUFSO01BQW9CTyxJQUFJLEVBQUU7SUFBMUIsQ0FGSyxDQVZzQjtJQWMvQmtDLFlBQVksRUFBRSx3QkFBWTtNQUN0Qi9DLENBQUMsQ0FBQyxtQkFBRCxDQUFELENBQXVCZ0QsS0FBdkIsQ0FBNkIsTUFBN0I7SUFDSDtFQWhCOEIsQ0FBbkM7QUFrQkgsQ0EzQkQ7QUE0QkFoRCxDQUFDLENBQUNnQixRQUFELENBQUQsQ0FBWUMsRUFBWixDQUFlLE9BQWYsRUFBd0IsMEJBQXhCLEVBQW9ELFlBQVk7RUFDNURqQixDQUFDLENBQUMsbUJBQUQsQ0FBRCxDQUF1QmdELEtBQXZCLENBQTZCLE1BQTdCO0FBQ0gsQ0FGRCIsImZpbGUiOiIuL3Jlc291cmNlcy9qcy93YXJlaG91c2VfbWFuYWdlbWVudC9wcm9kdWN0cy9pbmRleC5qcyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/products/index.js\n");
/***/ })
diff --git a/public/js/warehouse_management/stock_mutations/index.js b/public/js/warehouse_management/stock_mutations/index.js
deleted file mode 100644
index 16224fa..0000000
--- a/public/js/warehouse_management/stock_mutations/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * ATTENTION: An "eval-source-map" devtool has been used.
- * This devtool is neither made for production nor for readable output files.
- * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
- * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
- * or disable the default devtool with "devtool: false".
- * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
- */
-/******/ (() => { // webpackBootstrap
-/******/ var __webpack_modules__ = ({
-
-/***/ "./resources/js/warehouse_management/stock_mutations/index.js":
-/*!********************************************************************!*\
- !*** ./resources/js/warehouse_management/stock_mutations/index.js ***!
- \********************************************************************/
-/***/ (() => {
-
-eval("$.ajaxSetup({\n headers: {\n \"X-CSRF-TOKEN\": $('meta[name=\"csrf-token\"]').attr(\"content\")\n }\n});\nvar tableContainer = $(\"#stock-mutations-table\");\nvar url = tableContainer.data(\"url\");\nvar table = $(\"#stock-mutations-table\").DataTable({\n processing: true,\n serverSide: true,\n ajax: url,\n columns: [{\n data: \"product_name\",\n name: \"product_name\"\n }, {\n data: \"dealer_name\",\n name: \"dealer_name\"\n }, {\n data: \"user_name\",\n name: \"user_name\"\n }, {\n data: \"mutation_type_label\",\n name: \"mutation_type_label\"\n }, {\n data: \"quantity\",\n name: \"quantity\"\n }, {\n data: \"created_at\",\n name: \"created_at\"\n }]\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyIkIiwiYWpheFNldHVwIiwiaGVhZGVycyIsImF0dHIiLCJ0YWJsZUNvbnRhaW5lciIsInVybCIsImRhdGEiLCJ0YWJsZSIsIkRhdGFUYWJsZSIsInByb2Nlc3NpbmciLCJzZXJ2ZXJTaWRlIiwiYWpheCIsImNvbHVtbnMiLCJuYW1lIl0sInNvdXJjZXMiOlsid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy93YXJlaG91c2VfbWFuYWdlbWVudC9zdG9ja19tdXRhdGlvbnMvaW5kZXguanM/OGNlZiJdLCJzb3VyY2VzQ29udGVudCI6WyIkLmFqYXhTZXR1cCh7XG4gICAgaGVhZGVyczoge1xuICAgICAgICBcIlgtQ1NSRi1UT0tFTlwiOiAkKCdtZXRhW25hbWU9XCJjc3JmLXRva2VuXCJdJykuYXR0cihcImNvbnRlbnRcIiksXG4gICAgfSxcbn0pO1xubGV0IHRhYmxlQ29udGFpbmVyID0gJChcIiNzdG9jay1tdXRhdGlvbnMtdGFibGVcIik7XG5sZXQgdXJsID0gdGFibGVDb250YWluZXIuZGF0YShcInVybFwiKTtcbmxldCB0YWJsZSA9ICQoXCIjc3RvY2stbXV0YXRpb25zLXRhYmxlXCIpLkRhdGFUYWJsZSh7XG4gICAgcHJvY2Vzc2luZzogdHJ1ZSxcbiAgICBzZXJ2ZXJTaWRlOiB0cnVlLFxuICAgIGFqYXg6IHVybCxcbiAgICBjb2x1bW5zOiBbXG4gICAgICAgIHsgZGF0YTogXCJwcm9kdWN0X25hbWVcIiwgbmFtZTogXCJwcm9kdWN0X25hbWVcIiB9LFxuICAgICAgICB7IGRhdGE6IFwiZGVhbGVyX25hbWVcIiwgbmFtZTogXCJkZWFsZXJfbmFtZVwiIH0sXG4gICAgICAgIHsgZGF0YTogXCJ1c2VyX25hbWVcIiwgbmFtZTogXCJ1c2VyX25hbWVcIiB9LFxuICAgICAgICB7IGRhdGE6IFwibXV0YXRpb25fdHlwZV9sYWJlbFwiLCBuYW1lOiBcIm11dGF0aW9uX3R5cGVfbGFiZWxcIiB9LFxuICAgICAgICB7IGRhdGE6IFwicXVhbnRpdHlcIiwgbmFtZTogXCJxdWFudGl0eVwiIH0sXG4gICAgICAgIHsgZGF0YTogXCJjcmVhdGVkX2F0XCIsIG5hbWU6IFwiY3JlYXRlZF9hdFwiIH0sXG4gICAgXSxcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQUEsQ0FBQyxDQUFDQyxTQUFGLENBQVk7RUFDUkMsT0FBTyxFQUFFO0lBQ0wsZ0JBQWdCRixDQUFDLENBQUMseUJBQUQsQ0FBRCxDQUE2QkcsSUFBN0IsQ0FBa0MsU0FBbEM7RUFEWDtBQURELENBQVo7QUFLQSxJQUFJQyxjQUFjLEdBQUdKLENBQUMsQ0FBQyx3QkFBRCxDQUF0QjtBQUNBLElBQUlLLEdBQUcsR0FBR0QsY0FBYyxDQUFDRSxJQUFmLENBQW9CLEtBQXBCLENBQVY7QUFDQSxJQUFJQyxLQUFLLEdBQUdQLENBQUMsQ0FBQyx3QkFBRCxDQUFELENBQTRCUSxTQUE1QixDQUFzQztFQUM5Q0MsVUFBVSxFQUFFLElBRGtDO0VBRTlDQyxVQUFVLEVBQUUsSUFGa0M7RUFHOUNDLElBQUksRUFBRU4sR0FId0M7RUFJOUNPLE9BQU8sRUFBRSxDQUNMO0lBQUVOLElBQUksRUFBRSxjQUFSO0lBQXdCTyxJQUFJLEVBQUU7RUFBOUIsQ0FESyxFQUVMO0lBQUVQLElBQUksRUFBRSxhQUFSO0lBQXVCTyxJQUFJLEVBQUU7RUFBN0IsQ0FGSyxFQUdMO0lBQUVQLElBQUksRUFBRSxXQUFSO0lBQXFCTyxJQUFJLEVBQUU7RUFBM0IsQ0FISyxFQUlMO0lBQUVQLElBQUksRUFBRSxxQkFBUjtJQUErQk8sSUFBSSxFQUFFO0VBQXJDLENBSkssRUFLTDtJQUFFUCxJQUFJLEVBQUUsVUFBUjtJQUFvQk8sSUFBSSxFQUFFO0VBQTFCLENBTEssRUFNTDtJQUFFUCxJQUFJLEVBQUUsWUFBUjtJQUFzQk8sSUFBSSxFQUFFO0VBQTVCLENBTks7QUFKcUMsQ0FBdEMsQ0FBWiIsImZpbGUiOiIuL3Jlc291cmNlcy9qcy93YXJlaG91c2VfbWFuYWdlbWVudC9zdG9ja19tdXRhdGlvbnMvaW5kZXguanMiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/stock_mutations/index.js\n");
-
-/***/ })
-
-/******/ });
-/************************************************************************/
-/******/
-/******/ // startup
-/******/ // Load entry module and return exports
-/******/ // This entry module can't be inlined because the eval-source-map devtool is used.
-/******/ var __webpack_exports__ = {};
-/******/ __webpack_modules__["./resources/js/warehouse_management/stock_mutations/index.js"]();
-/******/
-/******/ })()
-;
\ No newline at end of file
diff --git a/public/js/warehouse_management/stock_opnames/create.js b/public/js/warehouse_management/stock_opnames/create.js
deleted file mode 100644
index 2350914..0000000
--- a/public/js/warehouse_management/stock_opnames/create.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * ATTENTION: An "eval-source-map" devtool has been used.
- * This devtool is neither made for production nor for readable output files.
- * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
- * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
- * or disable the default devtool with "devtool: false".
- * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
- */
-/******/ (() => { // webpackBootstrap
-/******/ var __webpack_modules__ = ({
-
-/***/ "./resources/js/warehouse_management/stock_opnames/create.js":
-/*!*******************************************************************!*\
- !*** ./resources/js/warehouse_management/stock_opnames/create.js ***!
- \*******************************************************************/
-/***/ (() => {
-
-eval("//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sInNvdXJjZXMiOlsid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy93YXJlaG91c2VfbWFuYWdlbWVudC9zdG9ja19vcG5hbWVzL2NyZWF0ZS5qcz9kYzA1Il0sInNvdXJjZXNDb250ZW50IjpbIiJdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiIuL3Jlc291cmNlcy9qcy93YXJlaG91c2VfbWFuYWdlbWVudC9zdG9ja19vcG5hbWVzL2NyZWF0ZS5qcyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/stock_opnames/create.js\n");
-
-/***/ })
-
-/******/ });
-/************************************************************************/
-/******/
-/******/ // startup
-/******/ // Load entry module and return exports
-/******/ // This entry module can't be inlined because the eval-source-map devtool is used.
-/******/ var __webpack_exports__ = {};
-/******/ __webpack_modules__["./resources/js/warehouse_management/stock_opnames/create.js"]();
-/******/
-/******/ })()
-;
\ No newline at end of file
diff --git a/public/js/warehouse_management/stock_opnames/index.js b/public/js/warehouse_management/stock_opnames/index.js
deleted file mode 100644
index 746fac8..0000000
--- a/public/js/warehouse_management/stock_opnames/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * ATTENTION: An "eval-source-map" devtool has been used.
- * This devtool is neither made for production nor for readable output files.
- * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
- * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
- * or disable the default devtool with "devtool: false".
- * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
- */
-/******/ (() => { // webpackBootstrap
-/******/ var __webpack_modules__ = ({
-
-/***/ "./resources/js/warehouse_management/stock_opnames/index.js":
-/*!******************************************************************!*\
- !*** ./resources/js/warehouse_management/stock_opnames/index.js ***!
- \******************************************************************/
-/***/ (() => {
-
-eval("$.ajaxSetup({\n headers: {\n \"X-CSRF-TOKEN\": $('meta[name=\"csrf-token\"]').attr(\"content\")\n }\n});\nvar tableContainer = $(\"#stock-opnames-table\");\nvar url = tableContainer.data(\"url\");\nvar table = $(\"#stock-opnames-table\").DataTable({\n processing: true,\n serverSide: true,\n ajax: url,\n columns: [{\n data: \"product_name\",\n name: \"product_name\"\n }, {\n data: \"dealer_name\",\n name: \"dealer_name\"\n }, {\n data: \"user_name\",\n name: \"user_name\"\n }, {\n data: \"system_quantity\",\n name: \"system_quantity\"\n }, {\n data: \"physical_quantity\",\n name: \"physical_quantity\"\n }, {\n data: \"difference\",\n name: \"difference\"\n }, {\n data: \"opname_date\",\n name: \"opname_date\"\n }]\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyIkIiwiYWpheFNldHVwIiwiaGVhZGVycyIsImF0dHIiLCJ0YWJsZUNvbnRhaW5lciIsInVybCIsImRhdGEiLCJ0YWJsZSIsIkRhdGFUYWJsZSIsInByb2Nlc3NpbmciLCJzZXJ2ZXJTaWRlIiwiYWpheCIsImNvbHVtbnMiLCJuYW1lIl0sInNvdXJjZXMiOlsid2VicGFjazovLy8uL3Jlc291cmNlcy9qcy93YXJlaG91c2VfbWFuYWdlbWVudC9zdG9ja19vcG5hbWVzL2luZGV4LmpzPzI3YTQiXSwic291cmNlc0NvbnRlbnQiOlsiJC5hamF4U2V0dXAoe1xuICAgIGhlYWRlcnM6IHtcbiAgICAgICAgXCJYLUNTUkYtVE9LRU5cIjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgIH0sXG59KTtcbmxldCB0YWJsZUNvbnRhaW5lciA9ICQoXCIjc3RvY2stb3BuYW1lcy10YWJsZVwiKTtcbmxldCB1cmwgPSB0YWJsZUNvbnRhaW5lci5kYXRhKFwidXJsXCIpO1xubGV0IHRhYmxlID0gJChcIiNzdG9jay1vcG5hbWVzLXRhYmxlXCIpLkRhdGFUYWJsZSh7XG4gICAgcHJvY2Vzc2luZzogdHJ1ZSxcbiAgICBzZXJ2ZXJTaWRlOiB0cnVlLFxuICAgIGFqYXg6IHVybCxcbiAgICBjb2x1bW5zOiBbXG4gICAgICAgIHsgZGF0YTogXCJwcm9kdWN0X25hbWVcIiwgbmFtZTogXCJwcm9kdWN0X25hbWVcIiB9LFxuICAgICAgICB7IGRhdGE6IFwiZGVhbGVyX25hbWVcIiwgbmFtZTogXCJkZWFsZXJfbmFtZVwiIH0sXG4gICAgICAgIHsgZGF0YTogXCJ1c2VyX25hbWVcIiwgbmFtZTogXCJ1c2VyX25hbWVcIiB9LFxuICAgICAgICB7IGRhdGE6IFwic3lzdGVtX3F1YW50aXR5XCIsIG5hbWU6IFwic3lzdGVtX3F1YW50aXR5XCIgfSxcbiAgICAgICAgeyBkYXRhOiBcInBoeXNpY2FsX3F1YW50aXR5XCIsIG5hbWU6IFwicGh5c2ljYWxfcXVhbnRpdHlcIiB9LFxuICAgICAgICB7IGRhdGE6IFwiZGlmZmVyZW5jZVwiLCBuYW1lOiBcImRpZmZlcmVuY2VcIiB9LFxuICAgICAgICB7IGRhdGE6IFwib3BuYW1lX2RhdGVcIiwgbmFtZTogXCJvcG5hbWVfZGF0ZVwiIH0sXG4gICAgXSxcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQUEsQ0FBQyxDQUFDQyxTQUFGLENBQVk7RUFDUkMsT0FBTyxFQUFFO0lBQ0wsZ0JBQWdCRixDQUFDLENBQUMseUJBQUQsQ0FBRCxDQUE2QkcsSUFBN0IsQ0FBa0MsU0FBbEM7RUFEWDtBQURELENBQVo7QUFLQSxJQUFJQyxjQUFjLEdBQUdKLENBQUMsQ0FBQyxzQkFBRCxDQUF0QjtBQUNBLElBQUlLLEdBQUcsR0FBR0QsY0FBYyxDQUFDRSxJQUFmLENBQW9CLEtBQXBCLENBQVY7QUFDQSxJQUFJQyxLQUFLLEdBQUdQLENBQUMsQ0FBQyxzQkFBRCxDQUFELENBQTBCUSxTQUExQixDQUFvQztFQUM1Q0MsVUFBVSxFQUFFLElBRGdDO0VBRTVDQyxVQUFVLEVBQUUsSUFGZ0M7RUFHNUNDLElBQUksRUFBRU4sR0FIc0M7RUFJNUNPLE9BQU8sRUFBRSxDQUNMO0lBQUVOLElBQUksRUFBRSxjQUFSO0lBQXdCTyxJQUFJLEVBQUU7RUFBOUIsQ0FESyxFQUVMO0lBQUVQLElBQUksRUFBRSxhQUFSO0lBQXVCTyxJQUFJLEVBQUU7RUFBN0IsQ0FGSyxFQUdMO0lBQUVQLElBQUksRUFBRSxXQUFSO0lBQXFCTyxJQUFJLEVBQUU7RUFBM0IsQ0FISyxFQUlMO0lBQUVQLElBQUksRUFBRSxpQkFBUjtJQUEyQk8sSUFBSSxFQUFFO0VBQWpDLENBSkssRUFLTDtJQUFFUCxJQUFJLEVBQUUsbUJBQVI7SUFBNkJPLElBQUksRUFBRTtFQUFuQyxDQUxLLEVBTUw7SUFBRVAsSUFBSSxFQUFFLFlBQVI7SUFBc0JPLElBQUksRUFBRTtFQUE1QixDQU5LLEVBT0w7SUFBRVAsSUFBSSxFQUFFLGFBQVI7SUFBdUJPLElBQUksRUFBRTtFQUE3QixDQVBLO0FBSm1DLENBQXBDLENBQVoiLCJmaWxlIjoiLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvc3RvY2tfb3BuYW1lcy9pbmRleC5qcyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/stock_opnames/index.js\n");
-
-/***/ })
-
-/******/ });
-/************************************************************************/
-/******/
-/******/ // startup
-/******/ // Load entry module and return exports
-/******/ // This entry module can't be inlined because the eval-source-map devtool is used.
-/******/ var __webpack_exports__ = {};
-/******/ __webpack_modules__["./resources/js/warehouse_management/stock_opnames/index.js"]();
-/******/
-/******/ })()
-;
\ No newline at end of file
diff --git a/public/mix-manifest.json b/public/mix-manifest.json
index 193ccdd..7f75923 100644
--- a/public/mix-manifest.json
+++ b/public/mix-manifest.json
@@ -2,8 +2,6 @@
"/js/app.js": "/js/app.js",
"/js/warehouse_management/product_categories/index.js": "/js/warehouse_management/product_categories/index.js",
"/js/warehouse_management/products/index.js": "/js/warehouse_management/products/index.js",
- "/js/warehouse_management/products/create.js": "/js/warehouse_management/products/create.js",
- "/js/warehouse_management/products/edit.js": "/js/warehouse_management/products/edit.js",
"/js/warehouse_management/opnames/index.js": "/js/warehouse_management/opnames/index.js",
"/js/warehouse_management/opnames/create.js": "/js/warehouse_management/opnames/create.js",
"/js/warehouse_management/opnames/detail.js": "/js/warehouse_management/opnames/detail.js",
diff --git a/resources/js/warehouse_management/opnames/create.js b/resources/js/warehouse_management/opnames/create.js
index d186f6d..ee966f9 100644
--- a/resources/js/warehouse_management/opnames/create.js
+++ b/resources/js/warehouse_management/opnames/create.js
@@ -1,60 +1,253 @@
-const productUrl = $("#product-container").data("url");
-
-function createProductSelectOptions(callback) {
- $.ajax({
- url: productUrl,
- method: "GET",
- success: function (data) {
- let options = '
Pilih Produk ';
- data.forEach((product) => {
- options += `
${product.name} `;
- });
- callback(options);
- },
- error: function () {
- alert("Gagal memuat produk.");
- },
- });
-}
-
$(document).ready(function () {
- // Initial load only for the first row
- createProductSelectOptions((options) => {
- $(".product-select").first().html(options);
- });
+ // Fungsi untuk mengambil data stok
+ function fetchStockData() {
+ const dealerId = $("#dealer").val();
+ if (!dealerId) return;
- // When adding a new row
- $(document).on("click", ".btn-add-row", function () {
- const row = `
-
- `;
+ const productIds = $(".product-select")
+ .map(function () {
+ return $(this).val();
+ })
+ .get()
+ .filter((id) => id !== "");
- const $newRow = $(row);
- $("#product-container").append($newRow);
+ if (productIds.length === 0) return;
- // Load options only for the new select
- createProductSelectOptions((options) => {
- $newRow.find(".product-select").html(options);
+ $.ajax({
+ url: "/warehouse/opnames/get-stock-data",
+ method: "POST",
+ data: {
+ _token: $('meta[name="csrf-token"]').attr("content"),
+ dealer_id: dealerId,
+ product_ids: productIds,
+ },
+ success: function (response) {
+ if (response.stocks) {
+ $(".product-row").each(function () {
+ const productId = $(this).find(".product-select").val();
+ const systemQtyInput = $(this).find(".system-quantity");
+ const physicalQtyInput = $(this).find(
+ 'input[name^="physical_quantity"]'
+ );
+
+ // Simpan nilai physical quantity yang sudah ada
+ const currentPhysicalQty = physicalQtyInput.val();
+
+ if (
+ productId &&
+ response.stocks[productId] !== undefined
+ ) {
+ systemQtyInput.val(response.stocks[productId]);
+ // Kembalikan nilai physical quantity jika ada
+ if (currentPhysicalQty) {
+ physicalQtyInput.val(currentPhysicalQty);
+ }
+ calculateDifference(systemQtyInput[0]);
+ } else {
+ systemQtyInput.val("0");
+ calculateDifference(systemQtyInput[0]);
+ }
+ });
+ }
+ },
+ error: function (xhr) {
+ console.error("Error fetching stock data:", xhr.responseText);
+ },
});
+ }
+
+ // Update stok saat dealer berubah
+ $("#dealer").change(function () {
+ fetchStockData();
});
- // Remove row
- $(document).on("click", ".btn-remove-row", function () {
- $(this).closest(".product-row").remove();
+ // Update stok saat produk berubah
+ $(document).on("change", ".product-select", function () {
+ const row = $(this).closest("tr");
+ const productId = $(this).val();
+ const systemQtyInput = row.find(".system-quantity");
+ const physicalQtyInput = row.find('input[name^="physical_quantity"]');
+
+ // Simpan nilai physical quantity yang sudah ada
+ const currentPhysicalQty = physicalQtyInput.val();
+
+ if (productId) {
+ fetchStockData();
+ } else {
+ systemQtyInput.val("0");
+ // Kembalikan nilai physical quantity jika ada
+ if (currentPhysicalQty) {
+ physicalQtyInput.val(currentPhysicalQty);
+ }
+ calculateDifference(systemQtyInput[0]);
+ }
});
+
+ // Fungsi untuk menambah baris produk
+ $("#btn-add-row").click(function () {
+ const template = document.getElementById("product-row-template");
+ const tbody = $("#product-table tbody");
+ const newRow = template.content.cloneNode(true);
+ const rowIndex = $(".product-row").length;
+
+ // Update name attributes with correct index
+ $(newRow)
+ .find('select[name="product[]"]')
+ .attr("name", `product[${rowIndex}]`);
+ $(newRow)
+ .find('input[name="system_quantity[]"]')
+ .attr("name", `system_quantity[${rowIndex}]`);
+ $(newRow)
+ .find('input[name="physical_quantity[]"]')
+ .attr("name", `physical_quantity[${rowIndex}]`);
+ $(newRow)
+ .find('input[name="item_notes[]"]')
+ .attr("name", `item_notes[${rowIndex}]`);
+
+ // Add system-quantity class dan pastikan readonly
+ const systemQtyInput = $(newRow).find(
+ 'input[name="system_quantity[]"]'
+ );
+ systemQtyInput
+ .addClass("system-quantity")
+ .attr("readonly", true)
+ .val("0");
+
+ // Reset semua nilai input di baris baru kecuali system quantity
+ $(newRow).find("select").val("");
+ $(newRow).find("input:not(.system-quantity)").val("");
+
+ tbody.append(newRow);
+ updateRemoveButtons();
+ });
+
+ // Fungsi untuk menghapus baris produk
+ $(document).on("click", ".btn-remove-row", function () {
+ $(this).closest("tr").remove();
+ updateRemoveButtons();
+ // Reindex semua baris setelah penghapusan
+ reindexRows();
+ });
+
+ // Fungsi untuk update status tombol hapus
+ function updateRemoveButtons() {
+ const rows = $(".product-row").length;
+ $(".btn-remove-row").prop("disabled", rows <= 1);
+ }
+
+ // Fungsi untuk reindex semua baris
+ function reindexRows() {
+ $(".product-row").each(function (index) {
+ $(this)
+ .find('select[name^="product"]')
+ .attr("name", `product[${index}]`);
+ $(this)
+ .find('input[name^="system_quantity"]')
+ .attr("name", `system_quantity[${index}]`);
+ $(this)
+ .find('input[name^="physical_quantity"]')
+ .attr("name", `physical_quantity[${index}]`);
+ $(this)
+ .find('input[name^="item_notes"]')
+ .attr("name", `item_notes[${index}]`);
+ });
+ }
+
+ // Update calculateDifference function
+ function calculateDifference(input) {
+ const row = $(input).closest("tr");
+ const systemQty = parseFloat(row.find(".system-quantity").val()) || 0;
+ const physicalQty =
+ parseFloat(row.find('input[name^="physical_quantity"]').val()) || 0;
+ const noteInput = row.find('input[name^="item_notes"]');
+
+ if (Math.abs(systemQty - physicalQty) > 0.01) {
+ noteInput.addClass("is-invalid");
+ noteInput.attr("required", true);
+ noteInput.attr(
+ "placeholder",
+ "Catatan wajib diisi karena ada perbedaan stock"
+ );
+ row.addClass("table-warning");
+ } else {
+ noteInput.removeClass("is-invalid");
+ noteInput.removeAttr("required");
+ noteInput.attr("placeholder", "Catatan item");
+ row.removeClass("table-warning");
+ }
+ }
+
+ // Prevent manual editing of system quantity
+ $(document).on("keydown", ".system-quantity", function (e) {
+ e.preventDefault();
+ return false;
+ });
+
+ $(document).on("paste", ".system-quantity", function (e) {
+ e.preventDefault();
+ return false;
+ });
+
+ // Validasi form sebelum submit
+ $("#opname-form").submit(function (e) {
+ const dealerId = $("#dealer").val();
+ if (!dealerId) {
+ e.preventDefault();
+ alert("Silakan pilih dealer terlebih dahulu!");
+ return false;
+ }
+
+ const products = $('select[name^="product"]')
+ .map(function () {
+ return $(this).val();
+ })
+ .get();
+
+ // Cek duplikasi produk
+ const uniqueProducts = [...new Set(products)];
+ if (products.length !== uniqueProducts.length) {
+ e.preventDefault();
+ alert("Produk tidak boleh duplikat!");
+ return false;
+ }
+
+ // Cek produk kosong
+ if (products.includes("")) {
+ e.preventDefault();
+ alert("Semua produk harus dipilih!");
+ return false;
+ }
+
+ // Cek catatan untuk perbedaan stock
+ let hasInvalidNotes = false;
+ $(".product-row").each(function () {
+ const systemQty =
+ parseFloat(
+ $(this).find('input[name^="system_quantity"]').val()
+ ) || 0;
+ const physicalQty =
+ parseFloat(
+ $(this).find('input[name^="physical_quantity"]').val()
+ ) || 0;
+ const note = $(this).find('input[name^="item_notes"]').val();
+
+ if (Math.abs(systemQty - physicalQty) > 0.01 && !note) {
+ hasInvalidNotes = true;
+ $(this).addClass("table-danger");
+ }
+ });
+
+ if (hasInvalidNotes) {
+ e.preventDefault();
+ alert(
+ "Catatan wajib diisi untuk produk yang memiliki perbedaan stock!"
+ );
+ return false;
+ }
+ });
+
+ // Initial stock data load if dealer is selected
+ if ($("#dealer").val()) {
+ fetchStockData();
+ }
});
diff --git a/resources/js/warehouse_management/products/create.js b/resources/js/warehouse_management/products/create.js
deleted file mode 100644
index b6ad13e..0000000
--- a/resources/js/warehouse_management/products/create.js
+++ /dev/null
@@ -1 +0,0 @@
-document.addEventListener("DOMContentLoaded", function () {});
diff --git a/resources/js/warehouse_management/products/edit.js b/resources/js/warehouse_management/products/edit.js
deleted file mode 100644
index b6ad13e..0000000
--- a/resources/js/warehouse_management/products/edit.js
+++ /dev/null
@@ -1 +0,0 @@
-document.addEventListener("DOMContentLoaded", function () {});
diff --git a/resources/js/warehouse_management/products/index.js b/resources/js/warehouse_management/products/index.js
index b61f5ba..cc287fb 100644
--- a/resources/js/warehouse_management/products/index.js
+++ b/resources/js/warehouse_management/products/index.js
@@ -109,10 +109,7 @@ $(document).on("click", ".btn-product-stock-dealers", function () {
},
columns: [
{ data: "dealer_name", name: "dealer_name" },
- { data: "system_stock", name: "system_stock" },
- { data: "physical_stock", name: "physical_stock" },
- { data: "difference", name: "difference" },
- { data: "opname_date", name: "opname_date" },
+ { data: "quantity", name: "quantity" },
],
initComplete: function () {
$("#dealerStockModal").modal("show");
diff --git a/resources/views/warehouse_management/opnames/create.blade.php b/resources/views/warehouse_management/opnames/create.blade.php
index c73c335..27ea0f4 100644
--- a/resources/views/warehouse_management/opnames/create.blade.php
+++ b/resources/views/warehouse_management/opnames/create.blade.php
@@ -2,58 +2,205 @@
@section('content')
-
-
-
-
-
-
Tambah Opnames
-
-
-
-
+
+
+
+
+
+
+ Pilih Produk
+ @foreach($products as $product)
+ {{ $product->name }}
+ @endforeach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@endsection
@section('javascripts')
-
+
@endsection
diff --git a/resources/views/warehouse_management/opnames/detail.blade.php b/resources/views/warehouse_management/opnames/detail.blade.php
index feca156..3447504 100644
--- a/resources/views/warehouse_management/opnames/detail.blade.php
+++ b/resources/views/warehouse_management/opnames/detail.blade.php
@@ -2,16 +2,21 @@
@section('content')
-
-
-
-
-
-
- Detail Opname
-
-
-
+
+
+
+
+
+
+ Opname {{ $opname->dealer->name }} Tanggal {{ Carbon\Carbon::parse($opname->opname_date)->format('d M Y') }}
+
+
+
+
@@ -35,5 +40,5 @@
@endsection
@section('javascripts')
-
+
@endsection
\ No newline at end of file
diff --git a/resources/views/warehouse_management/opnames/index.blade.php b/resources/views/warehouse_management/opnames/index.blade.php
index 79352d7..82355e0 100644
--- a/resources/views/warehouse_management/opnames/index.blade.php
+++ b/resources/views/warehouse_management/opnames/index.blade.php
@@ -30,7 +30,7 @@
Dealer
Pengguna
- Tanggal Opname
+ Tanggal
Aksi
@@ -42,5 +42,5 @@
@endsection
@section('javascripts')
-
+
@endsection
\ No newline at end of file
diff --git a/resources/views/warehouse_management/product_categories/index.blade.php b/resources/views/warehouse_management/product_categories/index.blade.php
index 1f1a8d1..4b5afe4 100644
--- a/resources/views/warehouse_management/product_categories/index.blade.php
+++ b/resources/views/warehouse_management/product_categories/index.blade.php
@@ -75,5 +75,5 @@
@endsection
@section('javascripts')
-
+
@endsection
\ No newline at end of file
diff --git a/resources/views/warehouse_management/products/create.blade.php b/resources/views/warehouse_management/products/create.blade.php
index a286f9c..d4eef7e 100644
--- a/resources/views/warehouse_management/products/create.blade.php
+++ b/resources/views/warehouse_management/products/create.blade.php
@@ -69,7 +69,3 @@
@endsection
-
-@section('javascripts')
-
-@endsection
\ No newline at end of file
diff --git a/resources/views/warehouse_management/products/edit.blade.php b/resources/views/warehouse_management/products/edit.blade.php
index 5f432e5..5bf64ab 100644
--- a/resources/views/warehouse_management/products/edit.blade.php
+++ b/resources/views/warehouse_management/products/edit.blade.php
@@ -71,8 +71,4 @@
-@endsection
-
-@section('javascripts')
-
@endsection
\ No newline at end of file
diff --git a/resources/views/warehouse_management/products/index.blade.php b/resources/views/warehouse_management/products/index.blade.php
index 8b7592d..03e5154 100644
--- a/resources/views/warehouse_management/products/index.blade.php
+++ b/resources/views/warehouse_management/products/index.blade.php
@@ -57,13 +57,9 @@
Dealer
- System Stock
- Physical Stock
- Difference
- Opname Date
+ Stok
-
@@ -72,5 +68,5 @@
@endsection
@section('javascripts')
-
+
@endsection
\ No newline at end of file
diff --git a/resources/views/warehouse_management/stocks/_action.blade.php b/resources/views/warehouse_management/stocks/_action.blade.php
new file mode 100644
index 0000000..53d1e84
--- /dev/null
+++ b/resources/views/warehouse_management/stocks/_action.blade.php
@@ -0,0 +1,19 @@
+