From 51079aa567e1f7fdf916bd4810305056d19b431f Mon Sep 17 00:00:00 2001 From: arifal Date: Tue, 10 Jun 2025 18:38:06 +0700 Subject: [PATCH] create stock and stock logs --- app/Console/Commands/ClearOpnameData.php | 93 ++++++ app/Console/Kernel.php | 4 + app/Enums/StockChangeType.php | 21 ++ .../WarehouseManagement/OpnamesController.php | 222 ++++++++++--- .../ProductsController.php | 22 +- .../WarehouseManagement/StocksController.php | 117 +++++++ app/Models/Opname.php | 99 +++++- app/Models/Product.php | 10 + app/Models/Stock.php | 56 ++++ app/Models/StockLog.php | 70 +++++ ckb.sql | 95 +++++- .../2025_06_10_135321_create_stocks_table.php | 34 ++ ...5_06_10_135341_create_stock_logs_table.php | 44 +++ ..._add_approval_columns_to_opnames_table.php | 36 +++ ...k_columns_to_decimal_in_opname_details.php | 41 +++ .../js/warehouse_management/opnames/create.js | 2 +- .../js/warehouse_management/products/index.js | 2 +- .../stock_mutations/index.js | 32 -- .../stock_opnames/create.js | 32 -- .../stock_opnames/index.js | 32 -- public/mix-manifest.json | 2 - .../js/warehouse_management/opnames/create.js | 295 +++++++++++++++--- .../warehouse_management/products/create.js | 1 - .../js/warehouse_management/products/edit.js | 1 - .../js/warehouse_management/products/index.js | 5 +- .../opnames/create.blade.php | 243 ++++++++++++--- .../opnames/detail.blade.php | 27 +- .../opnames/index.blade.php | 4 +- .../product_categories/index.blade.php | 2 +- .../products/create.blade.php | 4 - .../products/edit.blade.php | 4 - .../products/index.blade.php | 8 +- .../stocks/_action.blade.php | 19 ++ .../stocks/index.blade.php | 234 ++++++++++++++ routes/web.php | 11 +- webpack.mix.js | 8 - 36 files changed, 1621 insertions(+), 311 deletions(-) create mode 100644 app/Console/Commands/ClearOpnameData.php create mode 100644 app/Enums/StockChangeType.php create mode 100644 app/Http/Controllers/WarehouseManagement/StocksController.php create mode 100644 app/Models/Stock.php create mode 100644 app/Models/StockLog.php create mode 100644 database/migrations/2025_06_10_135321_create_stocks_table.php create mode 100644 database/migrations/2025_06_10_135341_create_stock_logs_table.php create mode 100644 database/migrations/2025_06_10_135417_add_approval_columns_to_opnames_table.php create mode 100644 database/migrations/2025_06_10_140540_change_stock_columns_to_decimal_in_opname_details.php delete mode 100644 public/js/warehouse_management/stock_mutations/index.js delete mode 100644 public/js/warehouse_management/stock_opnames/create.js delete mode 100644 public/js/warehouse_management/stock_opnames/index.js delete mode 100644 resources/js/warehouse_management/products/create.js delete mode 100644 resources/js/warehouse_management/products/edit.js create mode 100644 resources/views/warehouse_management/stocks/_action.blade.php create mode 100644 resources/views/warehouse_management/stocks/index.blade.php 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 = '';\n data.forEach(function (product) {\n options += \"\");\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 \\n
\\n
\\n \\n
\\n
\\n \\n
\\n
\\n \\n
\\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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyIkIiwiYWpheFNldHVwIiwiaGVhZGVycyIsImF0dHIiLCJ0YWJsZUNvbnRhaW5lciIsInVybCIsImRhdGEiLCJ0YWJsZSIsIkRhdGFUYWJsZSIsInByb2Nlc3NpbmciLCJzZXJ2ZXJTaWRlIiwiYWpheCIsImNvbHVtbnMiLCJuYW1lIiwib3JkZXJhYmxlIiwic2VhcmNoYWJsZSIsImRvY3VtZW50Iiwib24iLCJTd2FsIiwiZmlyZSIsInRpdGxlIiwidGV4dCIsInNob3dDYW5jZWxCdXR0b24iLCJjb25maXJtQnV0dG9uQ29sb3IiLCJjYW5jZWxCdXR0b25Db2xvciIsImNvbmZpcm1CdXR0b25UZXh0IiwidGhlbiIsInJlc3VsdCIsInZhbHVlIiwibWV0aG9kIiwiX21ldGhvZCIsIl90b2tlbiIsInN1Y2Nlc3MiLCJhbGVydCIsInJlbG9hZCIsImVycm9yIiwieGhyIiwiY29uc29sZSIsInJlc3BvbnNlVGV4dCIsImJ1dHRvbiIsInJlc3BvbnNlIiwibWVzc2FnZSIsInByb2R1Y3RJZCIsInByb2R1Y3ROYW1lIiwiYWpheFVybCIsImRlc3Ryb3kiLCJwcm9kdWN0X2lkIiwiaW5pdENvbXBsZXRlIiwibW9kYWwiXSwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL3dhcmVob3VzZV9tYW5hZ2VtZW50L3Byb2R1Y3RzL2luZGV4LmpzP2ZjZDYiXSwic291cmNlc0NvbnRlbnQiOlsiJC5hamF4U2V0dXAoe1xuICAgIGhlYWRlcnM6IHtcbiAgICAgICAgXCJYLUNTUkYtVE9LRU5cIjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgIH0sXG59KTtcbmxldCB0YWJsZUNvbnRhaW5lciA9ICQoXCIjcHJvZHVjdHMtdGFibGVcIik7XG5sZXQgdXJsID0gdGFibGVDb250YWluZXIuZGF0YShcInVybFwiKTtcbmxldCB0YWJsZSA9ICQoXCIjcHJvZHVjdHMtdGFibGVcIikuRGF0YVRhYmxlKHtcbiAgICBwcm9jZXNzaW5nOiB0cnVlLFxuICAgIHNlcnZlclNpZGU6IHRydWUsXG4gICAgYWpheDogdXJsLFxuICAgIGNvbHVtbnM6IFtcbiAgICAgICAgeyBkYXRhOiBcImNvZGVcIiwgbmFtZTogXCJjb2RlXCIgfSxcbiAgICAgICAgeyBkYXRhOiBcIm5hbWVcIiwgbmFtZTogXCJuYW1lXCIgfSxcbiAgICAgICAgeyBkYXRhOiBcImNhdGVnb3J5X25hbWVcIiwgbmFtZTogXCJjYXRlZ29yeS5uYW1lXCIgfSxcbiAgICAgICAgeyBkYXRhOiBcInVuaXRcIiwgbmFtZTogXCJ1bml0XCIgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgZGF0YTogXCJ0b3RhbF9zdG9ja1wiLFxuICAgICAgICAgICAgbmFtZTogXCJ0b3RhbF9zdG9ja1wiLFxuICAgICAgICAgICAgb3JkZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICB7IGRhdGE6IFwiYWN0aW9uXCIsIG5hbWU6IFwiYWN0aW9uXCIsIG9yZGVyYWJsZTogZmFsc2UsIHNlYXJjaGFibGU6IGZhbHNlIH0sXG4gICAgXSxcbn0pO1xuXG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1kZXN0cm95LXByb2R1Y3RcIiwgZnVuY3Rpb24gKCkge1xuICAgIFN3YWwuZmlyZSh7XG4gICAgICAgIHRpdGxlOiBcIkhhcHVzIHByb2R1az9cIixcbiAgICAgICAgdGV4dDogXCJBbmRhIHRpZGFrIGFrYW4gYmlzYSBtZW5nZW1iYWxpa2FubnlhIVwiLFxuICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiB0cnVlLFxuICAgICAgICBjb25maXJtQnV0dG9uQ29sb3I6IFwiI2QzM1wiLFxuICAgICAgICBjYW5jZWxCdXR0b25Db2xvcjogXCIjZGVkZWRlXCIsXG4gICAgICAgIGNvbmZpcm1CdXR0b25UZXh0OiBcIkhhcHVzXCIsXG4gICAgfSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQudmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9ICQodGhpcykuZGF0YShcImFjdGlvblwiKTtcbiAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIF9tZXRob2Q6IFwiREVMRVRFXCIsXG4gICAgICAgICAgICAgICAgICAgIF90b2tlbjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChcIlByb2R1ayBiZXJoYXNpbCBkaWhhcHVzLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgJChcIiNwcm9kdWN0cy10YWJsZVwiKS5EYXRhVGFibGUoKS5hamF4LnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICh4aHIpIHtcbiAgICAgICAgICAgICAgICAgICAgYWxlcnQoXCJHYWdhbCBtZW5naGFwdXMgcHJvZHVrLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcih4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn0pO1xuJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi5idG4tdG9nZ2xlLWFjdGl2ZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGJ1dHRvbiA9ICQodGhpcyk7XG4gICAgbGV0IHVybCA9IGJ1dHRvbi5kYXRhKFwidXJsXCIpO1xuXG4gICAgU3dhbC5maXJlKHtcbiAgICAgICAgdGl0bGU6IFwiU3RhdHVzIHByb2R1az9cIixcbiAgICAgICAgdGV4dDogXCJBbmRhIHlha2luIGluZ2luIG1lbmdnYW50aSBzdGF0dXMgcHJvZHVrIVwiLFxuICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiB0cnVlLFxuICAgICAgICBjb25maXJtQnV0dG9uQ29sb3I6IFwiI2QzM1wiLFxuICAgICAgICBjYW5jZWxCdXR0b25Db2xvcjogXCIjZGVkZWRlXCIsXG4gICAgICAgIGNvbmZpcm1CdXR0b25UZXh0OiBcIllhXCIsXG4gICAgfSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQudmFsdWUpIHtcbiAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIF90b2tlbjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKFwiI3Byb2R1Y3RzLXRhYmxlXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLkRhdGFUYWJsZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFqYXgucmVsb2FkKG51bGwsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChcIkdhZ2FsIG1lbmd1YmFoIHN0YXR1cyBwcm9kdWsuXCIpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xufSk7XG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1wcm9kdWN0LXN0b2NrLWRlYWxlcnNcIiwgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHByb2R1Y3RJZCA9ICQodGhpcykuZGF0YShcImlkXCIpO1xuICAgIGNvbnN0IHByb2R1Y3ROYW1lID0gJCh0aGlzKS5kYXRhKFwibmFtZVwiKTtcbiAgICBjb25zdCBhamF4VXJsID0gJCh0aGlzKS5kYXRhKFwidXJsXCIpO1xuXG4gICAgLy8gU2V0IHByb2R1Y3QgbmFtZSBpbiBtb2RhbCB0aXRsZVxuICAgICQoXCIjcHJvZHVjdC1uYW1lLXRpdGxlXCIpLnRleHQocHJvZHVjdE5hbWUpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBvciByZWxvYWQgRGF0YVRhYmxlIGluc2lkZSBtb2RhbFxuICAgICQoXCIjZGVhbGVyLXN0b2NrLXRhYmxlXCIpLkRhdGFUYWJsZSh7XG4gICAgICAgIGRlc3Ryb3k6IHRydWUsIC8vIHJlaW5pdCBpZiBleGlzdHNcbiAgICAgICAgcHJvY2Vzc2luZzogdHJ1ZSxcbiAgICAgICAgc2VydmVyU2lkZTogdHJ1ZSxcbiAgICAgICAgYWpheDoge1xuICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIHByb2R1Y3RfaWQ6IHByb2R1Y3RJZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGNvbHVtbnM6IFtcbiAgICAgICAgICAgIHsgZGF0YTogXCJkZWFsZXJfbmFtZVwiLCBuYW1lOiBcImRlYWxlcl9uYW1lXCIgfSxcbiAgICAgICAgICAgIHsgZGF0YTogXCJzeXN0ZW1fc3RvY2tcIiwgbmFtZTogXCJzeXN0ZW1fc3RvY2tcIiB9LFxuICAgICAgICAgICAgeyBkYXRhOiBcInBoeXNpY2FsX3N0b2NrXCIsIG5hbWU6IFwicGh5c2ljYWxfc3RvY2tcIiB9LFxuICAgICAgICAgICAgeyBkYXRhOiBcImRpZmZlcmVuY2VcIiwgbmFtZTogXCJkaWZmZXJlbmNlXCIgfSxcbiAgICAgICAgICAgIHsgZGF0YTogXCJvcG5hbWVfZGF0ZVwiLCBuYW1lOiBcIm9wbmFtZV9kYXRlXCIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaW5pdENvbXBsZXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkKFwiI2RlYWxlclN0b2NrTW9kYWxcIikubW9kYWwoXCJzaG93XCIpO1xuICAgICAgICB9LFxuICAgIH0pO1xufSk7XG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiI2RlYWxlclN0b2NrTW9kYWwgLmNsb3NlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAkKFwiI2RlYWxlclN0b2NrTW9kYWxcIikubW9kYWwoXCJoaWRlXCIpO1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBQSxDQUFDLENBQUNDLFNBQUYsQ0FBWTtFQUNSQyxPQUFPLEVBQUU7SUFDTCxnQkFBZ0JGLENBQUMsQ0FBQyx5QkFBRCxDQUFELENBQTZCRyxJQUE3QixDQUFrQyxTQUFsQztFQURYO0FBREQsQ0FBWjtBQUtBLElBQUlDLGNBQWMsR0FBR0osQ0FBQyxDQUFDLGlCQUFELENBQXRCO0FBQ0EsSUFBSUssR0FBRyxHQUFHRCxjQUFjLENBQUNFLElBQWYsQ0FBb0IsS0FBcEIsQ0FBVjtBQUNBLElBQUlDLEtBQUssR0FBR1AsQ0FBQyxDQUFDLGlCQUFELENBQUQsQ0FBcUJRLFNBQXJCLENBQStCO0VBQ3ZDQyxVQUFVLEVBQUUsSUFEMkI7RUFFdkNDLFVBQVUsRUFBRSxJQUYyQjtFQUd2Q0MsSUFBSSxFQUFFTixHQUhpQztFQUl2Q08sT0FBTyxFQUFFLENBQ0w7SUFBRU4sSUFBSSxFQUFFLE1BQVI7SUFBZ0JPLElBQUksRUFBRTtFQUF0QixDQURLLEVBRUw7SUFBRVAsSUFBSSxFQUFFLE1BQVI7SUFBZ0JPLElBQUksRUFBRTtFQUF0QixDQUZLLEVBR0w7SUFBRVAsSUFBSSxFQUFFLGVBQVI7SUFBeUJPLElBQUksRUFBRTtFQUEvQixDQUhLLEVBSUw7SUFBRVAsSUFBSSxFQUFFLE1BQVI7SUFBZ0JPLElBQUksRUFBRTtFQUF0QixDQUpLLEVBS0w7SUFDSVAsSUFBSSxFQUFFLGFBRFY7SUFFSU8sSUFBSSxFQUFFLGFBRlY7SUFHSUMsU0FBUyxFQUFFLEtBSGY7SUFJSUMsVUFBVSxFQUFFO0VBSmhCLENBTEssRUFXTDtJQUFFVCxJQUFJLEVBQUUsUUFBUjtJQUFrQk8sSUFBSSxFQUFFLFFBQXhCO0lBQWtDQyxTQUFTLEVBQUUsS0FBN0M7SUFBb0RDLFVBQVUsRUFBRTtFQUFoRSxDQVhLO0FBSjhCLENBQS9CLENBQVo7QUFtQkFmLENBQUMsQ0FBQ2dCLFFBQUQsQ0FBRCxDQUFZQyxFQUFaLENBQWUsT0FBZixFQUF3QixzQkFBeEIsRUFBZ0QsWUFBWTtFQUFBOztFQUN4REMsSUFBSSxDQUFDQyxJQUFMLENBQVU7SUFDTkMsS0FBSyxFQUFFLGVBREQ7SUFFTkMsSUFBSSxFQUFFLHdDQUZBO0lBR05DLGdCQUFnQixFQUFFLElBSFo7SUFJTkMsa0JBQWtCLEVBQUUsTUFKZDtJQUtOQyxpQkFBaUIsRUFBRSxTQUxiO0lBTU5DLGlCQUFpQixFQUFFO0VBTmIsQ0FBVixFQU9HQyxJQVBILENBT1EsVUFBQ0MsTUFBRCxFQUFZO0lBQ2hCLElBQUlBLE1BQU0sQ0FBQ0MsS0FBWCxFQUFrQjtNQUNkLElBQU12QixJQUFHLEdBQUdMLENBQUMsQ0FBQyxLQUFELENBQUQsQ0FBUU0sSUFBUixDQUFhLFFBQWIsQ0FBWjs7TUFDQU4sQ0FBQyxDQUFDVyxJQUFGLENBQU87UUFDSE4sR0FBRyxFQUFFQSxJQURGO1FBRUh3QixNQUFNLEVBQUUsTUFGTDtRQUdIdkIsSUFBSSxFQUFFO1VBQ0Z3QixPQUFPLEVBQUUsUUFEUDtVQUVGQyxNQUFNLEVBQUUvQixDQUFDLENBQUMseUJBQUQsQ0FBRCxDQUE2QkcsSUFBN0IsQ0FBa0MsU0FBbEM7UUFGTixDQUhIO1FBT0g2QixPQUFPLEVBQUUsbUJBQVk7VUFDakJDLEtBQUssQ0FBQywwQkFBRCxDQUFMO1VBQ0FqQyxDQUFDLENBQUMsaUJBQUQsQ0FBRCxDQUFxQlEsU0FBckIsR0FBaUNHLElBQWpDLENBQXNDdUIsTUFBdEM7UUFDSCxDQVZFO1FBV0hDLEtBQUssRUFBRSxlQUFVQyxHQUFWLEVBQWU7VUFDbEJILEtBQUssQ0FBQyx5QkFBRCxDQUFMO1VBQ0FJLE9BQU8sQ0FBQ0YsS0FBUixDQUFjQyxHQUFHLENBQUNFLFlBQWxCO1FBQ0g7TUFkRSxDQUFQO0lBZ0JIO0VBQ0osQ0EzQkQ7QUE0QkgsQ0E3QkQ7QUE4QkF0QyxDQUFDLENBQUNnQixRQUFELENBQUQsQ0FBWUMsRUFBWixDQUFlLE9BQWYsRUFBd0Isb0JBQXhCLEVBQThDLFlBQVk7RUFDdEQsSUFBSXNCLE1BQU0sR0FBR3ZDLENBQUMsQ0FBQyxJQUFELENBQWQ7RUFDQSxJQUFJSyxHQUFHLEdBQUdrQyxNQUFNLENBQUNqQyxJQUFQLENBQVksS0FBWixDQUFWO0VBRUFZLElBQUksQ0FBQ0MsSUFBTCxDQUFVO0lBQ05DLEtBQUssRUFBRSxnQkFERDtJQUVOQyxJQUFJLEVBQUUsMkNBRkE7SUFHTkMsZ0JBQWdCLEVBQUUsSUFIWjtJQUlOQyxrQkFBa0IsRUFBRSxNQUpkO0lBS05DLGlCQUFpQixFQUFFLFNBTGI7SUFNTkMsaUJBQWlCLEVBQUU7RUFOYixDQUFWLEVBT0dDLElBUEgsQ0FPUSxVQUFDQyxNQUFELEVBQVk7SUFDaEIsSUFBSUEsTUFBTSxDQUFDQyxLQUFYLEVBQWtCO01BQ2Q1QixDQUFDLENBQUNXLElBQUYsQ0FBTztRQUNITixHQUFHLEVBQUVBLEdBREY7UUFFSHdCLE1BQU0sRUFBRSxNQUZMO1FBR0h2QixJQUFJLEVBQUU7VUFDRnlCLE1BQU0sRUFBRS9CLENBQUMsQ0FBQyx5QkFBRCxDQUFELENBQTZCRyxJQUE3QixDQUFrQyxTQUFsQztRQUROLENBSEg7UUFNSDZCLE9BQU8sRUFBRSxpQkFBVVEsUUFBVixFQUFvQjtVQUN6QixJQUFJQSxRQUFRLENBQUNSLE9BQWIsRUFBc0I7WUFDbEJoQyxDQUFDLENBQUMsaUJBQUQsQ0FBRCxDQUNLUSxTQURMLEdBRUtHLElBRkwsQ0FFVXVCLE1BRlYsQ0FFaUIsSUFGakIsRUFFdUIsS0FGdkI7WUFHQUQsS0FBSyxDQUFDTyxRQUFRLENBQUNDLE9BQVYsQ0FBTDtVQUNIO1FBQ0osQ0FiRTtRQWNITixLQUFLLEVBQUUsaUJBQVk7VUFDZkYsS0FBSyxDQUFDLCtCQUFELENBQUw7UUFDSDtNQWhCRSxDQUFQO0lBa0JIO0VBQ0osQ0E1QkQ7QUE2QkgsQ0FqQ0Q7QUFrQ0FqQyxDQUFDLENBQUNnQixRQUFELENBQUQsQ0FBWUMsRUFBWixDQUFlLE9BQWYsRUFBd0IsNEJBQXhCLEVBQXNELFlBQVk7RUFDOUQsSUFBTXlCLFNBQVMsR0FBRzFDLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUU0sSUFBUixDQUFhLElBQWIsQ0FBbEI7RUFDQSxJQUFNcUMsV0FBVyxHQUFHM0MsQ0FBQyxDQUFDLElBQUQsQ0FBRCxDQUFRTSxJQUFSLENBQWEsTUFBYixDQUFwQjtFQUNBLElBQU1zQyxPQUFPLEdBQUc1QyxDQUFDLENBQUMsSUFBRCxDQUFELENBQVFNLElBQVIsQ0FBYSxLQUFiLENBQWhCLENBSDhELENBSzlEOztFQUNBTixDQUFDLENBQUMscUJBQUQsQ0FBRCxDQUF5QnFCLElBQXpCLENBQThCc0IsV0FBOUIsRUFOOEQsQ0FROUQ7O0VBQ0EzQyxDQUFDLENBQUMscUJBQUQsQ0FBRCxDQUF5QlEsU0FBekIsQ0FBbUM7SUFDL0JxQyxPQUFPLEVBQUUsSUFEc0I7SUFDaEI7SUFDZnBDLFVBQVUsRUFBRSxJQUZtQjtJQUcvQkMsVUFBVSxFQUFFLElBSG1CO0lBSS9CQyxJQUFJLEVBQUU7TUFDRk4sR0FBRyxFQUFFdUMsT0FESDtNQUVGdEMsSUFBSSxFQUFFO1FBQ0Z3QyxVQUFVLEVBQUVKO01BRFY7SUFGSixDQUp5QjtJQVUvQjlCLE9BQU8sRUFBRSxDQUNMO01BQUVOLElBQUksRUFBRSxhQUFSO01BQXVCTyxJQUFJLEVBQUU7SUFBN0IsQ0FESyxFQUVMO01BQUVQLElBQUksRUFBRSxjQUFSO01BQXdCTyxJQUFJLEVBQUU7SUFBOUIsQ0FGSyxFQUdMO01BQUVQLElBQUksRUFBRSxnQkFBUjtNQUEwQk8sSUFBSSxFQUFFO0lBQWhDLENBSEssRUFJTDtNQUFFUCxJQUFJLEVBQUUsWUFBUjtNQUFzQk8sSUFBSSxFQUFFO0lBQTVCLENBSkssRUFLTDtNQUFFUCxJQUFJLEVBQUUsYUFBUjtNQUF1Qk8sSUFBSSxFQUFFO0lBQTdCLENBTEssQ0FWc0I7SUFpQi9Ca0MsWUFBWSxFQUFFLHdCQUFZO01BQ3RCL0MsQ0FBQyxDQUFDLG1CQUFELENBQUQsQ0FBdUJnRCxLQUF2QixDQUE2QixNQUE3QjtJQUNIO0VBbkI4QixDQUFuQztBQXFCSCxDQTlCRDtBQStCQWhELENBQUMsQ0FBQ2dCLFFBQUQsQ0FBRCxDQUFZQyxFQUFaLENBQWUsT0FBZixFQUF3QiwwQkFBeEIsRUFBb0QsWUFBWTtFQUM1RGpCLENBQUMsQ0FBQyxtQkFBRCxDQUFELENBQXVCZ0QsS0FBdkIsQ0FBNkIsTUFBN0I7QUFDSCxDQUZEIiwiZmlsZSI6Ii4vcmVzb3VyY2VzL2pzL3dhcmVob3VzZV9tYW5hZ2VtZW50L3Byb2R1Y3RzL2luZGV4LmpzIiwic291cmNlUm9vdCI6IiJ9\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 = ''; - data.forEach((product) => { - options += ``; - }); - 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

-
-
- -
-
- @csrf -
- - -
- -
-
-
- - -
-
- - -
-
- - -
-
- -
+
+
+ + + +

Tambah Opnames

-
+
-
- -
- -
+
+ @if ($errors->any()) +
+
    + @foreach ($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+ @endif + +
+ @csrf +
+
+
+ + @php + $oldDealer = old('dealer'); + $dealerValue = is_array($oldDealer) ? '' : $oldDealer; + @endphp + + @error('dealer') +
{{ $message }}
+ @enderror +
+
+
+
+ + @php + $oldNote = old('note'); + $noteValue = is_array($oldNote) ? '' : $oldNote; + @endphp + + @error('note') +
{{ $message }}
+ @enderror +
+
+
+ +
+ +
+
+

Detail Produk

+
+
+ +
+
+ +
+ + + + + + + + + + + + @php + $oldProducts = old('product', []); + $oldSystemQuantities = old('system_quantity', []); + $oldPhysicalQuantities = old('physical_quantity', []); + $oldItemNotes = old('item_notes', []); + @endphp + + + + + + + + +
Produk *Stok Sistem *Stok Fisik *CatatanAksi
+ + @error('product.0') +
{{ $message }}
+ @enderror +
+
+ +
+ @error('system_quantity.0') +
{{ $message }}
+ @enderror +
+
+ +
+ @error('physical_quantity.0') +
{{ $message }}
+ @enderror +
+ + @error('item_notes.0') +
{{ $message }}
+ @enderror +
+ +
+
+ +
+ +
+ + + Batal + +
+
+
+ + + @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 @@ +
+ + + + + +
\ No newline at end of file diff --git a/resources/views/warehouse_management/stocks/index.blade.php b/resources/views/warehouse_management/stocks/index.blade.php new file mode 100644 index 0000000..669745f --- /dev/null +++ b/resources/views/warehouse_management/stocks/index.blade.php @@ -0,0 +1,234 @@ +@extends('layouts.backapp') + +@section('content') +
+
+
+ + + +

Manajemen Stok

+
+ +
+ +
+ +
+
+
+ + +
+
+
+
+ + +
+
+
+ + +
+ + + + + + + + + +
DealerProdukStokAksi
+
+
+
+ + + + + + +@endsection + +@section('javascripts') + +@endsection \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 03c2c0e..f2fd93f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -11,6 +11,7 @@ use App\Http\Controllers\WarehouseManagement\OpnamesController; use App\Http\Controllers\WarehouseManagement\ProductCategoriesController; use App\Http\Controllers\WarehouseManagement\ProductsController; use App\Http\Controllers\WorkController; +use App\Http\Controllers\WarehouseManagement\StocksController; use App\Models\Menu; use App\Models\Privilege; use App\Models\Role; @@ -237,12 +238,16 @@ Route::group(['middleware' => 'auth'], function() { Route::get('create','create')->name('opnames.create'); Route::post('/','store')->name('opnames.store'); Route::get('{opnames}','show')->name('opnames.show'); + Route::post('get-stock-data', 'getStockData')->name('opnames.get-stock-data'); + }); + + Route::prefix('stocks')->controller(StocksController::class)->group(function () { + Route::get('/', 'index')->name('stocks.index'); + Route::post('adjust', 'adjust')->name('stocks.adjust'); + Route::get('history', 'history')->name('stocks.history'); }); }); }); - - - Auth::routes(); // Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home'); diff --git a/webpack.mix.js b/webpack.mix.js index 6c33c8b..ab77fb3 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -21,14 +21,6 @@ mix.js("resources/js/app.js", "public/js") "resources/js/warehouse_management/products/index.js", "public/js/warehouse_management/products" ) - .js( - "resources/js/warehouse_management/products/create.js", - "public/js/warehouse_management/products" - ) - .js( - "resources/js/warehouse_management/products/edit.js", - "public/js/warehouse_management/products" - ) .js( "resources/js/warehouse_management/opnames/index.js", "public/js/warehouse_management/opnames"