diff --git a/.env.backup.20250611_220739 b/.env.backup.20250611_220739 new file mode 100644 index 0000000..775aaad --- /dev/null +++ b/.env.backup.20250611_220739 @@ -0,0 +1,56 @@ +APP_NAME="CKB Application" +APP_ENV=local +APP_KEY=base64:3XK9+3S0lhXOPnlBjPxik2Ru1oARb8REF5b/pfaHLKM= +APP_DEBUG=true +APP_URL=http://localhost:8000 + +LOG_CHANNEL=stack +LOG_LEVEL=debug + +# Database Configuration for Docker +DB_CONNECTION=mysql +DB_HOST=db +DB_PORT=3306 +DB_DATABASE=ckb_db +DB_USERNAME=laravel +DB_PASSWORD=password +DB_ROOT_PASSWORD=root + +# Redis Configuration for Docker +REDIS_HOST=redis +REDIS_PASSWORD=null +REDIS_PORT=6379 + +# Cache Configuration +CACHE_DRIVER=redis +QUEUE_CONNECTION=redis +SESSION_DRIVER=redis + +# Mail Configuration (using MailHog for development) +MAIL_MAILER=smtp +MAIL_HOST=mailhog +MAIL_PORT=1025 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS=noreply@ckb.local +MAIL_FROM_NAME="${APP_NAME}" + +# Broadcasting +BROADCAST_DRIVER=log + +# AWS (if needed) +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +# Pusher (if needed) +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= +PUSHER_APP_CLUSTER=mt1 + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" \ No newline at end of file diff --git a/app/Console/Commands/ClearMutationsCommand.php b/app/Console/Commands/ClearMutationsCommand.php new file mode 100644 index 0000000..911cd6a --- /dev/null +++ b/app/Console/Commands/ClearMutationsCommand.php @@ -0,0 +1,112 @@ +warn('⚠️ WARNING: This will permanently delete ALL mutations and mutation details!'); + $this->warn('⚠️ This action cannot be undone!'); + + // Check for force flag + if (!$this->option('force')) { + if (!$this->confirm('Are you sure you want to continue?')) { + $this->info('Operation cancelled.'); + return 0; + } + } + + // Show current counts + $mutationCount = Mutation::count(); + $detailCount = MutationDetail::count(); + $trashedMutationCount = Mutation::onlyTrashed()->count(); + + $this->info("Current data:"); + $this->info("- Mutations: {$mutationCount}"); + $this->info("- Mutation Details: {$detailCount}"); + if ($trashedMutationCount > 0) { + $this->info("- Soft Deleted Mutations: {$trashedMutationCount}"); + } + + if ($mutationCount === 0 && $detailCount === 0 && $trashedMutationCount === 0) { + $this->info('No data to clear.'); + return 0; + } + + $this->info('Starting cleanup process...'); + + try { + // Delete data within transaction + DB::beginTransaction(); + + // Delete mutation details first (foreign key constraint) + $this->info('🗑️ Deleting mutation details...'); + MutationDetail::query()->delete(); + + // Delete mutations (including soft deleted ones) + $this->info('🗑️ Deleting mutations...'); + Mutation::query()->delete(); + + // Force delete soft deleted mutations + $this->info('🗑️ Force deleting soft deleted mutations...'); + Mutation::onlyTrashed()->forceDelete(); + + DB::commit(); + + // Reset auto increment outside transaction (DDL operations auto-commit) + $this->info('🔄 Resetting mutation_details auto increment...'); + DB::statement('ALTER TABLE mutation_details AUTO_INCREMENT = 1'); + + $this->info('🔄 Resetting mutations auto increment...'); + DB::statement('ALTER TABLE mutations AUTO_INCREMENT = 1'); + + $this->info('✅ Successfully cleared all mutations and reset auto increment!'); + $this->info('📊 Final counts:'); + $this->info('- Mutations: ' . Mutation::count()); + $this->info('- Mutation Details: ' . MutationDetail::count()); + + return 0; + + } catch (\Exception $e) { + if (DB::transactionLevel() > 0) { + DB::rollback(); + } + $this->error('❌ Failed to clear mutations: ' . $e->getMessage()); + return 1; + } + } +} diff --git a/app/Enums/MutationStatus.php b/app/Enums/MutationStatus.php new file mode 100644 index 0000000..2f28ca0 --- /dev/null +++ b/app/Enums/MutationStatus.php @@ -0,0 +1,40 @@ + 'Menunggu Konfirmasi', + self::SENT => 'Terkirim ke Dealer', + self::RECEIVED => 'Diterima Dealer', + self::APPROVED => 'Disetujui', + self::REJECTED => 'Ditolak', + self::COMPLETED => 'Selesai', + self::CANCELLED => 'Dibatalkan', + }; + } + + public function color(): string + { + return match($this) { + self::PENDING => 'warning', + self::SENT => 'primary', + self::RECEIVED => 'info', + self::APPROVED => 'brand', + self::REJECTED => 'danger', + self::COMPLETED => 'success', + self::CANCELLED => 'secondary', + }; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/WarehouseManagement/MutationsController.php b/app/Http/Controllers/WarehouseManagement/MutationsController.php new file mode 100644 index 0000000..e75eb34 --- /dev/null +++ b/app/Http/Controllers/WarehouseManagement/MutationsController.php @@ -0,0 +1,278 @@ +first(); + + if ($request->ajax()) { + $data = Mutation::with(['fromDealer', 'toDealer', 'requestedBy', 'approvedBy', 'receivedBy']) + ->select('mutations.*'); + + // Filter berdasarkan dealer jika user bukan admin + if (auth()->user()->dealer_id) { + $data->where(function($query) { + $query->where('from_dealer_id', auth()->user()->dealer_id) + ->orWhere('to_dealer_id', auth()->user()->dealer_id); + }); + } + + return DataTables::of($data) + ->addIndexColumn() + ->addColumn('mutation_number', function($row) { + return $row->mutation_number; + }) + ->addColumn('from_dealer', function($row) { + return $row->fromDealer->name ?? '-'; + }) + ->addColumn('to_dealer', function($row) { + return $row->toDealer->name ?? '-'; + }) + ->addColumn('requested_by', function($row) { + return $row->requestedBy->name ?? '-'; + }) + ->addColumn('status', function($row) { + $statusColor = $row->status_color; + $statusLabel = $row->status_label; + return " {$statusLabel}"; + }) + ->addColumn('total_items', function($row) { + return number_format($row->total_items, 0); + }) + ->addColumn('created_at', function($row) { + return $row->created_at->format('d/m/Y H:i'); + }) + ->addColumn('action', function($row) { + return view('warehouse_management.mutations._action', compact('row'))->render(); + }) + ->rawColumns(['status', 'action']) + ->make(true); + } + + return view('warehouse_management.mutations.index', compact('menu')); + } + + public function create() + { + $menu = Menu::where('link','mutations.create')->first(); + $dealers = Dealer::all(); + $products = Product::with('stocks')->get(); + + return view('warehouse_management.mutations.create', compact('menu', 'dealers', 'products')); + } + + public function store(Request $request) + { + $request->validate([ + 'from_dealer_id' => 'required|exists:dealers,id', + 'to_dealer_id' => 'required|exists:dealers,id|different:from_dealer_id', + 'notes' => 'nullable|string', + 'products' => 'required|array|min:1', + 'products.*.product_id' => 'required|exists:products,id', + 'products.*.quantity_requested' => 'required|numeric|min:0.01' + ]); + + DB::beginTransaction(); + try { + // Buat mutation record dengan status SENT (langsung terkirim ke dealer tujuan) + $mutation = Mutation::create([ + 'from_dealer_id' => $request->from_dealer_id, + 'to_dealer_id' => $request->to_dealer_id, + 'status' => 'sent', + 'requested_by' => auth()->id(), + 'notes' => $request->notes + ]); + + // Buat mutation details + foreach ($request->products as $productData) { + MutationDetail::create([ + 'mutation_id' => $mutation->id, + 'product_id' => $productData['product_id'], + 'quantity_requested' => $productData['quantity_requested'], + 'notes' => $productData['notes'] ?? null + ]); + } + + DB::commit(); + return redirect()->route('mutations.index') + ->with('success', 'Mutasi berhasil dibuat dan terkirim ke dealer tujuan'); + + } catch (\Exception $e) { + DB::rollback(); + return back()->withErrors(['error' => 'Gagal membuat mutasi: ' . $e->getMessage()]); + } + } + + public function show(Mutation $mutation) + { + $mutation->load(['fromDealer', 'toDealer', 'requestedBy', 'approvedBy', 'receivedBy', 'mutationDetails.product']); + + return view('warehouse_management.mutations.show', compact('mutation')); + } + + public function receive(Mutation $mutation) + { + if (!$mutation->canBeReceived()) { + return back()->withErrors(['error' => 'Mutasi tidak dapat diterima dalam status saat ini']); + } + + try { + $mutation->receive(auth()->id()); + + return redirect()->route('mutations.index') + ->with('success', 'Mutasi berhasil diterima dan menunggu persetujuan pengirim'); + + } catch (\Exception $e) { + return back()->withErrors(['error' => 'Gagal menerima mutasi: ' . $e->getMessage()]); + } + } + + public function approve(Request $request, Mutation $mutation) + { + $request->validate([ + 'notes' => 'nullable|string', + 'details' => 'required|array', + 'details.*.quantity_approved' => 'required|numeric|min:0' + ]); + + if (!$mutation->canBeApproved()) { + return back()->withErrors(['error' => 'Mutasi tidak dapat disetujui dalam status saat ini']); + } + + DB::beginTransaction(); + try { + // Update mutation details dengan quantity approved + foreach ($request->details as $detailId => $detailData) { + $mutationDetail = MutationDetail::findOrFail($detailId); + $mutationDetail->update([ + 'quantity_approved' => $detailData['quantity_approved'] + ]); + } + + // Approve mutation + $mutation->approve(auth()->id(), $request->notes); + + DB::commit(); + return redirect()->route('mutations.index') + ->with('success', 'Mutasi berhasil disetujui'); + + } catch (\Exception $e) { + DB::rollback(); + return back()->withErrors(['error' => 'Gagal menyetujui mutasi: ' . $e->getMessage()]); + } + } + + public function reject(Request $request, Mutation $mutation) + { + $request->validate([ + 'rejection_reason' => 'required|string' + ]); + + if (!$mutation->canBeApproved()) { + return back()->withErrors(['error' => 'Mutasi tidak dapat ditolak dalam status saat ini']); + } + + try { + $mutation->reject(auth()->id(), $request->rejection_reason); + + return redirect()->route('mutations.index') + ->with('success', 'Mutasi berhasil ditolak'); + + } catch (\Exception $e) { + return back()->withErrors(['error' => 'Gagal menolak mutasi: ' . $e->getMessage()]); + } + } + + public function complete(Mutation $mutation) + { + if (!$mutation->canBeCompleted()) { + return back()->withErrors(['error' => 'Mutasi tidak dapat diselesaikan dalam status saat ini']); + } + + try { + $mutation->complete(); + + return redirect()->route('mutations.index') + ->with('success', 'Mutasi berhasil diselesaikan dan stock telah dipindahkan'); + + } catch (\Exception $e) { + return back()->withErrors(['error' => 'Gagal menyelesaikan mutasi: ' . $e->getMessage()]); + } + } + + public function cancel(Mutation $mutation) + { + if (!$mutation->canBeCancelled()) { + return back()->withErrors(['error' => 'Mutasi tidak dapat dibatalkan dalam status saat ini']); + } + + try { + $mutation->update(['status' => MutationStatus::CANCELLED]); + + return redirect()->route('mutations.index') + ->with('success', 'Mutasi berhasil dibatalkan'); + + } catch (\Exception $e) { + return back()->withErrors(['error' => 'Gagal membatalkan mutasi: ' . $e->getMessage()]); + } + } + + // API untuk mendapatkan detail mutasi untuk approval + public function getDetails(Mutation $mutation) + { + $mutation->load(['mutationDetails.product', 'fromDealer']); + + $details = $mutation->mutationDetails->map(function($detail) use ($mutation) { + $availableStock = $detail->product->getStockByDealer($mutation->from_dealer_id); + + return [ + 'id' => $detail->id, + 'product' => [ + 'id' => $detail->product->id, + 'name' => $detail->product->name + ], + 'quantity_requested' => $detail->quantity_requested, + 'quantity_approved' => $detail->quantity_approved, + 'available_stock' => $availableStock + ]; + }); + + return response()->json([ + 'mutation' => [ + 'id' => $mutation->id, + 'mutation_number' => $mutation->mutation_number, + 'from_dealer' => $mutation->fromDealer->name, + 'to_dealer' => $mutation->toDealer->name + ], + 'details' => $details + ]); + } + + // API untuk mendapatkan stock produk di dealer tertentu + public function getProductStock(Request $request) + { + $dealerId = $request->dealer_id; + $productId = $request->product_id; + + $product = Product::findOrFail($productId); + $stock = $product->getStockByDealer($dealerId); + + return response()->json([ + 'product_name' => $product->name, + 'current_stock' => $stock + ]); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/WarehouseManagement/ProductsController.php b/app/Http/Controllers/WarehouseManagement/ProductsController.php index 0f3451e..a88e076 100644 --- a/app/Http/Controllers/WarehouseManagement/ProductsController.php +++ b/app/Http/Controllers/WarehouseManagement/ProductsController.php @@ -41,13 +41,11 @@ class ProductsController extends Controller if (Gate::allows('update', $menu)) { $btn .= 'Edit'; + $btn .= '' + . ($row->active ? 'Nonaktifkan' : 'Aktifkan') . ''; } - - $btn .= '' - . ($row->active ? 'Nonaktifkan' : 'Aktifkan') . ''; - $btn .= '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/Dealer.php b/app/Models/Dealer.php index 1f68ea2..2869f13 100644 --- a/app/Models/Dealer.php +++ b/app/Models/Dealer.php @@ -26,4 +26,19 @@ class Dealer extends Model public function opnames(){ return $this->hasMany(Opname::class); } + + public function outgoingMutations() + { + return $this->hasMany(Mutation::class, 'from_dealer_id'); + } + + public function incomingMutations() + { + return $this->hasMany(Mutation::class, 'to_dealer_id'); + } + + public function stocks() + { + return $this->hasMany(Stock::class); + } } diff --git a/app/Models/Mutation.php b/app/Models/Mutation.php new file mode 100644 index 0000000..3f2ce88 --- /dev/null +++ b/app/Models/Mutation.php @@ -0,0 +1,262 @@ + MutationStatus::class, + 'approved_at' => 'datetime', + 'received_at' => 'datetime' + ]; + + protected static function booted() + { + static::creating(function ($mutation) { + if (empty($mutation->mutation_number)) { + $mutation->mutation_number = $mutation->generateMutationNumber(); + } + }); + } + + public function fromDealer() + { + return $this->belongsTo(Dealer::class, 'from_dealer_id'); + } + + public function toDealer() + { + return $this->belongsTo(Dealer::class, 'to_dealer_id'); + } + + public function requestedBy() + { + return $this->belongsTo(User::class, 'requested_by'); + } + + public function approvedBy() + { + return $this->belongsTo(User::class, 'approved_by'); + } + + public function receivedBy() + { + return $this->belongsTo(User::class, 'received_by'); + } + + public function mutationDetails() + { + return $this->hasMany(MutationDetail::class); + } + + public function stockLogs() + { + return $this->morphMany(StockLog::class, 'source'); + } + + // Helper methods + public function getStatusLabelAttribute() + { + return $this->status->label(); + } + + public function getStatusColorAttribute() + { + return $this->status->color(); + } + + public function getTotalItemsAttribute() + { + return $this->mutationDetails()->sum('quantity_requested'); + } + + public function getTotalApprovedItemsAttribute() + { + return $this->mutationDetails()->sum('quantity_approved'); + } + + public function canBeSent() + { + return $this->status === MutationStatus::PENDING; + } + + public function canBeReceived() + { + return $this->status === MutationStatus::SENT; + } + + public function canBeApproved() + { + return $this->status === MutationStatus::RECEIVED; + } + + public function canBeCompleted() + { + return $this->status === MutationStatus::APPROVED; + } + + public function canBeCancelled() + { + return in_array($this->status, [MutationStatus::PENDING, MutationStatus::SENT]); + } + + // Send mutation to destination dealer + public function send($userId) + { + if (!$this->canBeSent()) { + throw new \Exception('Mutasi tidak dapat dikirim dalam status saat ini'); + } + + $this->update([ + 'status' => MutationStatus::SENT + ]); + + return $this; + } + + // Receive mutation by destination dealer + public function receive($userId) + { + if (!$this->canBeReceived()) { + throw new \Exception('Mutasi tidak dapat diterima dalam status saat ini'); + } + + $this->update([ + 'status' => MutationStatus::RECEIVED, + 'received_by' => $userId, + 'received_at' => now() + ]); + + return $this; + } + + // Approve mutation + public function approve($userId, $notes = null) + { + if (!$this->canBeApproved()) { + throw new \Exception('Mutasi tidak dapat disetujui dalam status saat ini'); + } + + $this->update([ + 'status' => MutationStatus::APPROVED, + 'approved_by' => $userId, + 'approved_at' => now(), + 'notes' => $notes + ]); + + return $this; + } + + // Reject mutation + public function reject($userId, $rejectionReason) + { + if (!$this->canBeApproved()) { + throw new \Exception('Mutasi tidak dapat ditolak dalam status saat ini'); + } + + $this->update([ + 'status' => MutationStatus::REJECTED, + 'approved_by' => $userId, + 'approved_at' => now(), + 'rejection_reason' => $rejectionReason + ]); + + return $this; + } + + // Complete mutation (actually move the stock) + public function complete() + { + if (!$this->canBeCompleted()) { + throw new \Exception('Mutasi tidak dapat diselesaikan dalam status saat ini'); + } + + \DB::beginTransaction(); + try { + foreach ($this->mutationDetails as $detail) { + if ($detail->quantity_approved > 0) { + $this->processStockMovement($detail); + } + } + + $this->update(['status' => MutationStatus::COMPLETED]); + \DB::commit(); + } catch (\Exception $e) { + \DB::rollback(); + throw $e; + } + + return $this; + } + + private function processStockMovement(MutationDetail $detail) + { + // Kurangi stock dari dealer asal + $fromStock = Stock::firstOrCreate([ + 'product_id' => $detail->product_id, + 'dealer_id' => $this->from_dealer_id + ], ['quantity' => 0]); + + if ($fromStock->quantity < $detail->quantity_approved) { + throw new \Exception("Stock tidak mencukupi untuk produk {$detail->product->name} di {$this->fromDealer->name}"); + } + + $fromStock->updateStock( + $fromStock->quantity - $detail->quantity_approved, + $this, + "Mutasi keluar ke {$this->toDealer->name} - {$this->mutation_number}" + ); + + // Tambah stock ke dealer tujuan + $toStock = Stock::firstOrCreate([ + 'product_id' => $detail->product_id, + 'dealer_id' => $this->to_dealer_id + ], ['quantity' => 0]); + + $toStock->updateStock( + $toStock->quantity + $detail->quantity_approved, + $this, + "Mutasi masuk dari {$this->fromDealer->name} - {$this->mutation_number}" + ); + } + + private function generateMutationNumber() + { + $prefix = 'MUT'; + $date = now()->format('Ymd'); + $lastNumber = static::whereDate('created_at', today()) + ->whereNotNull('mutation_number') + ->latest('id') + ->first(); + + if ($lastNumber) { + $lastSequence = (int) substr($lastNumber->mutation_number, -4); + $sequence = str_pad($lastSequence + 1, 4, '0', STR_PAD_LEFT); + } else { + $sequence = '0001'; + } + + return "{$prefix}{$date}{$sequence}"; + } +} \ No newline at end of file diff --git a/app/Models/MutationDetail.php b/app/Models/MutationDetail.php new file mode 100644 index 0000000..2b6d16e --- /dev/null +++ b/app/Models/MutationDetail.php @@ -0,0 +1,98 @@ + 'decimal:2', + 'quantity_approved' => 'decimal:2' + ]; + + public function mutation() + { + return $this->belongsTo(Mutation::class); + } + + public function product() + { + return $this->belongsTo(Product::class); + } + + // Helper methods + public function getQuantityDifferenceAttribute() + { + return $this->quantity_approved - $this->quantity_requested; + } + + public function isFullyApproved() + { + return $this->quantity_approved == $this->quantity_requested; + } + + public function isPartiallyApproved() + { + return $this->quantity_approved > 0 && $this->quantity_approved < $this->quantity_requested; + } + + public function isRejected() + { + return $this->quantity_approved == 0; + } + + public function getApprovalStatusAttribute() + { + if ($this->isFullyApproved()) { + return 'Disetujui Penuh'; + } elseif ($this->isPartiallyApproved()) { + return 'Disetujui Sebagian'; + } elseif ($this->isRejected()) { + return 'Ditolak'; + } else { + return 'Menunggu'; + } + } + + public function getApprovalStatusColorAttribute() + { + if ($this->isFullyApproved()) { + return 'success'; + } elseif ($this->isPartiallyApproved()) { + return 'warning'; + } elseif ($this->isRejected()) { + return 'danger'; + } else { + return 'info'; + } + } + + // Scope untuk filter berdasarkan status approval + public function scopeFullyApproved($query) + { + return $query->whereColumn('quantity_approved', '=', 'quantity_requested'); + } + + public function scopePartiallyApproved($query) + { + return $query->where('quantity_approved', '>', 0) + ->whereColumn('quantity_approved', '<', 'quantity_requested'); + } + + public function scopeRejected($query) + { + return $query->where('quantity_approved', '=', 0); + } +} \ No newline at end of file diff --git a/app/Models/Product.php b/app/Models/Product.php index e2c232d..8eb7f30 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -24,9 +24,20 @@ class Product extends Model return $this->hasMany(Stock::class); } + public function mutationDetails() + { + return $this->hasMany(MutationDetail::class); + } + // Helper method untuk mendapatkan total stock saat ini public function getCurrentTotalStockAttribute() { return $this->stocks()->sum('quantity'); } + + // Helper method untuk mendapatkan stock di dealer tertentu + public function getStockByDealer($dealerId) + { + return $this->stocks()->where('dealer_id', $dealerId)->first()?->quantity ?? 0; + } } diff --git a/ckb.sql b/ckb.sql index 6fb3c5a..b0dd43d 100644 --- a/ckb.sql +++ b/ckb.sql @@ -1,13 +1,14 @@ --- MySQL dump 10.13 Distrib 8.0.42, for Linux (x86_64) +/*M!999999\- enable the sandbox mode */ +-- MariaDB dump 10.19 Distrib 10.6.22-MariaDB, for debian-linux-gnu (x86_64) -- --- Host: localhost Database: ckb +-- Host: localhost Database: ckb_db -- ------------------------------------------------------ --- Server version 8.0.42-0ubuntu0.22.04.1 +-- Server version 10.6.22-MariaDB-ubu2004-log /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!50503 SET NAMES utf8mb4 */; +/*!40101 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -21,13 +22,13 @@ DROP TABLE IF EXISTS `categories`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `categories` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, - `form` enum('work','wash') COLLATE utf8mb4_unicode_ci NOT NULL, + `form` enum('work','wash') NOT NULL, `deleted_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -49,15 +50,15 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `dealers`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `dealers` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `dealer_code` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `address` text COLLATE utf8mb4_unicode_ci NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `dealer_code` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `address` text NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, - `pic` bigint unsigned DEFAULT NULL, + `pic` bigint(20) unsigned DEFAULT NULL, `deleted_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `dealers_dealer_code_unique` (`dealer_code`), @@ -82,15 +83,15 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `failed_jobs`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `failed_jobs` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `uuid` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `connection` text COLLATE utf8mb4_unicode_ci NOT NULL, - `queue` text COLLATE utf8mb4_unicode_ci NOT NULL, - `payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `exception` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `failed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `uuid` varchar(255) NOT NULL, + `connection` text NOT NULL, + `queue` text NOT NULL, + `payload` longtext NOT NULL, + `exception` longtext NOT NULL, + `failed_at` timestamp NOT NULL DEFAULT current_timestamp(), PRIMARY KEY (`id`), UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -111,11 +112,11 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `menus`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `menus` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `link` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `link` varchar(255) NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) @@ -138,13 +139,13 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `migrations`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `migrations` ( - `id` int unsigned NOT NULL AUTO_INCREMENT, - `migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `batch` int NOT NULL, + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `migration` varchar(255) NOT NULL, + `batch` int(11) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=70 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=78 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -153,25 +154,107 @@ 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),(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); +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),(76,'2025_06_12_002513_create_mutations_table',15),(77,'2025_06_12_002623_create_mutation_details_table',15); /*!40000 ALTER TABLE `migrations` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `mutation_details` +-- + +DROP TABLE IF EXISTS `mutation_details`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `mutation_details` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `mutation_id` bigint(20) unsigned NOT NULL, + `product_id` bigint(20) unsigned NOT NULL, + `quantity_requested` decimal(15,2) NOT NULL, + `quantity_approved` decimal(15,2) NOT NULL DEFAULT 0.00, + `notes` text DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `mutation_details_product_id_foreign` (`product_id`), + KEY `mutation_details_mutation_id_product_id_index` (`mutation_id`,`product_id`), + CONSTRAINT `mutation_details_mutation_id_foreign` FOREIGN KEY (`mutation_id`) REFERENCES `mutations` (`id`) ON DELETE CASCADE, + CONSTRAINT `mutation_details_product_id_foreign` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `mutation_details` +-- + +LOCK TABLES `mutation_details` WRITE; +/*!40000 ALTER TABLE `mutation_details` DISABLE KEYS */; +/*!40000 ALTER TABLE `mutation_details` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `mutations` +-- + +DROP TABLE IF EXISTS `mutations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `mutations` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `mutation_number` varchar(255) NOT NULL, + `from_dealer_id` bigint(20) unsigned NOT NULL, + `to_dealer_id` bigint(20) unsigned NOT NULL, + `status` enum('pending','sent','received','approved','rejected','completed','cancelled') NOT NULL DEFAULT 'sent', + `requested_by` bigint(20) unsigned NOT NULL, + `approved_by` bigint(20) unsigned DEFAULT NULL, + `approved_at` timestamp NULL DEFAULT NULL, + `received_by` bigint(20) unsigned DEFAULT NULL, + `received_at` timestamp NULL DEFAULT NULL, + `notes` text DEFAULT NULL, + `rejection_reason` text DEFAULT NULL, + `created_at` timestamp NULL DEFAULT NULL, + `updated_at` timestamp NULL DEFAULT NULL, + `deleted_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `mutations_mutation_number_unique` (`mutation_number`), + KEY `mutations_requested_by_foreign` (`requested_by`), + KEY `mutations_approved_by_foreign` (`approved_by`), + KEY `mutations_received_by_foreign` (`received_by`), + KEY `mutations_from_dealer_id_status_index` (`from_dealer_id`,`status`), + KEY `mutations_to_dealer_id_status_index` (`to_dealer_id`,`status`), + KEY `mutations_status_created_at_index` (`status`,`created_at`), + KEY `mutations_mutation_number_index` (`mutation_number`), + CONSTRAINT `mutations_approved_by_foreign` FOREIGN KEY (`approved_by`) REFERENCES `users` (`id`), + CONSTRAINT `mutations_from_dealer_id_foreign` FOREIGN KEY (`from_dealer_id`) REFERENCES `dealers` (`id`), + CONSTRAINT `mutations_received_by_foreign` FOREIGN KEY (`received_by`) REFERENCES `users` (`id`), + CONSTRAINT `mutations_requested_by_foreign` FOREIGN KEY (`requested_by`) REFERENCES `users` (`id`), + CONSTRAINT `mutations_to_dealer_id_foreign` FOREIGN KEY (`to_dealer_id`) REFERENCES `dealers` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `mutations` +-- + +LOCK TABLES `mutations` WRITE; +/*!40000 ALTER TABLE `mutations` DISABLE KEYS */; +/*!40000 ALTER TABLE `mutations` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `opname_details` -- DROP TABLE IF EXISTS `opname_details`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `opname_details` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `opname_id` bigint unsigned NOT NULL, - `product_id` bigint unsigned NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `opname_id` bigint(20) unsigned NOT NULL, + `product_id` bigint(20) unsigned NOT NULL, `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, + `difference` decimal(10,2) NOT NULL DEFAULT 0.00, + `note` text DEFAULT NULL, `deleted_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, @@ -180,7 +263,7 @@ CREATE TABLE `opname_details` ( KEY `opname_details_product_id_foreign` (`product_id`), CONSTRAINT `opname_details_opname_id_foreign` FOREIGN KEY (`opname_id`) REFERENCES `opnames` (`id`) ON DELETE CASCADE, CONSTRAINT `opname_details_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; +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -189,7 +272,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,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'); +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'),(3,3,1,10.00,0.00,-10.00,NULL,NULL,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(4,3,2,0.00,0.00,0.00,NULL,NULL,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(5,3,3,0.00,0.00,0.00,NULL,NULL,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(6,3,4,0.00,0.00,0.00,NULL,NULL,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(7,3,5,0.00,0.00,0.00,NULL,NULL,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(8,3,6,0.00,0.00,0.00,NULL,NULL,'2025-06-11 22:21:32','2025-06-11 22:21:32'); /*!40000 ALTER TABLE `opname_details` ENABLE KEYS */; UNLOCK TABLES; @@ -199,20 +282,20 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `opnames`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `opnames` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `dealer_id` bigint unsigned NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `dealer_id` bigint(20) unsigned NOT NULL, `opname_date` date NOT NULL, - `user_id` bigint unsigned NOT NULL, - `note` text COLLATE utf8mb4_unicode_ci, + `user_id` bigint(20) unsigned NOT NULL, + `note` text DEFAULT NULL, `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, + `status` enum('draft','pending','approved','rejected') NOT NULL DEFAULT 'draft', + `approved_by` bigint(20) unsigned DEFAULT NULL, `approved_at` timestamp NULL DEFAULT NULL, - `rejection_note` text COLLATE utf8mb4_unicode_ci, + `rejection_note` text DEFAULT NULL, PRIMARY KEY (`id`), KEY `opnames_dealer_id_foreign` (`dealer_id`), KEY `opnames_user_id_foreign` (`user_id`), @@ -220,7 +303,7 @@ CREATE TABLE `opnames` ( 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=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -229,7 +312,7 @@ CREATE TABLE `opnames` ( LOCK TABLES `opnames` WRITE; /*!40000 ALTER TABLE `opnames` DISABLE KEYS */; -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); +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),(3,20,'2025-06-11',8,NULL,NULL,'2025-06-11 22:21:32','2025-06-11 22:21:32','approved',8,'2025-06-11 22:21:32',NULL); /*!40000 ALTER TABLE `opnames` ENABLE KEYS */; UNLOCK TABLES; @@ -239,10 +322,10 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `password_resets`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `password_resets` ( - `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `token` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `email` varchar(255) NOT NULL, + `token` varchar(255) NOT NULL, `created_at` timestamp NULL DEFAULT NULL, KEY `password_resets_email_index` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -263,14 +346,14 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `personal_access_tokens`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `personal_access_tokens` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `tokenable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `tokenable_id` bigint unsigned NOT NULL, - `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `token` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL, - `abilities` text COLLATE utf8mb4_unicode_ci, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `tokenable_type` varchar(255) NOT NULL, + `tokenable_id` bigint(20) unsigned NOT NULL, + `name` varchar(255) NOT NULL, + `token` varchar(64) NOT NULL, + `abilities` text DEFAULT NULL, `last_used_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, @@ -296,18 +379,18 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `privileges`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `privileges` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `role_id` bigint unsigned NOT NULL, - `create` tinyint NOT NULL, - `update` tinyint NOT NULL, - `delete` tinyint NOT NULL, - `view` tinyint NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `role_id` bigint(20) unsigned NOT NULL, + `create` tinyint(4) NOT NULL, + `update` tinyint(4) NOT NULL, + `delete` tinyint(4) NOT NULL, + `view` tinyint(4) NOT NULL, `deleted_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, - `menu_id` bigint unsigned NOT NULL, + `menu_id` bigint(20) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `privileges_role_id_foreign` (`role_id`), KEY `privileges_menu_id_foreign` (`menu_id`), @@ -332,11 +415,11 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `product_categories`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `product_categories` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `parent_id` bigint unsigned DEFAULT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `parent_id` bigint(20) unsigned DEFAULT NULL, `deleted_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, @@ -362,15 +445,15 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `products`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `products` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `code` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `active` tinyint(1) NOT NULL DEFAULT '1', - `unit` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `description` text COLLATE utf8mb4_unicode_ci, - `product_category_id` bigint unsigned NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `code` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `active` tinyint(1) NOT NULL DEFAULT 1, + `unit` varchar(255) DEFAULT NULL, + `description` text DEFAULT NULL, + `product_category_id` bigint(20) unsigned NOT NULL, `deleted_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, @@ -397,10 +480,10 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `roles`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `roles` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, `deleted_at` timestamp NULL DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, @@ -424,18 +507,18 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `stock_logs`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 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, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `stock_id` bigint(20) unsigned NOT NULL, + `source_type` varchar(255) NOT NULL, + `source_id` bigint(20) 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, + `change_type` enum('increase','decrease','adjustment','no_change') NOT NULL DEFAULT 'no_change', + `description` varchar(255) DEFAULT NULL, + `user_id` bigint(20) unsigned NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), @@ -444,7 +527,7 @@ CREATE TABLE `stock_logs` ( 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; +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -453,7 +536,7 @@ CREATE 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'); +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'),(3,1,'App\\Models\\Opname',3,10.00,0.00,-10.00,'decrease','Stock adjustment from auto-approved opname #3',8,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(4,3,'App\\Models\\Opname',3,0.00,0.00,0.00,'no_change','Stock adjustment from auto-approved opname #3',8,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(5,4,'App\\Models\\Opname',3,0.00,0.00,0.00,'no_change','Stock adjustment from auto-approved opname #3',8,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(6,5,'App\\Models\\Opname',3,0.00,0.00,0.00,'no_change','Stock adjustment from auto-approved opname #3',8,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(7,6,'App\\Models\\Opname',3,0.00,0.00,0.00,'no_change','Stock adjustment from auto-approved opname #3',8,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(8,7,'App\\Models\\Opname',3,0.00,0.00,0.00,'no_change','Stock adjustment from auto-approved opname #3',8,'2025-06-11 22:21:32','2025-06-11 22:21:32'); /*!40000 ALTER TABLE `stock_logs` ENABLE KEYS */; UNLOCK TABLES; @@ -463,12 +546,12 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `stocks`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 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', + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `product_id` bigint(20) unsigned NOT NULL, + `dealer_id` bigint(20) 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`), @@ -476,7 +559,7 @@ CREATE TABLE `stocks` ( 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; +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -485,7 +568,7 @@ CREATE 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'); +INSERT INTO `stocks` VALUES (1,1,20,0.00,'2025-06-10 10:26:24','2025-06-11 22:21:32'),(2,1,24,30.00,'2025-06-10 10:27:30','2025-06-10 10:27:30'),(3,2,20,0.00,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(4,3,20,0.00,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(5,4,20,0.00,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(6,5,20,0.00,'2025-06-11 22:21:32','2025-06-11 22:21:32'),(7,6,20,0.00,'2025-06-11 22:21:32','2025-06-11 22:21:32'); /*!40000 ALTER TABLE `stocks` ENABLE KEYS */; UNLOCK TABLES; @@ -495,22 +578,22 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `transactions`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `transactions` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `user_id` bigint unsigned NOT NULL, - `user_sa_id` bigint unsigned NOT NULL, - `work_id` bigint unsigned NOT NULL, - `spk` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `police_number` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `warranty` tinyint NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL, + `user_sa_id` bigint(20) unsigned NOT NULL, + `work_id` bigint(20) unsigned NOT NULL, + `spk` varchar(255) NOT NULL, + `police_number` varchar(255) NOT NULL, + `warranty` tinyint(4) NOT NULL, `date` datetime NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, - `form` enum('work','wash') COLLATE utf8mb4_unicode_ci NOT NULL, - `qty` bigint unsigned NOT NULL, - `status` tinyint NOT NULL DEFAULT '0', - `dealer_id` bigint unsigned NOT NULL, + `form` enum('work','wash') NOT NULL, + `qty` bigint(20) unsigned NOT NULL, + `status` tinyint(4) NOT NULL DEFAULT 0, + `dealer_id` bigint(20) unsigned NOT NULL, `deleted_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), KEY `transactions_user_id_foreign` (`user_id`), @@ -574,20 +657,20 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `users`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `users` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `dealer_id` bigint unsigned NOT NULL, - `role` enum('admin','sa','mechanic') COLLATE utf8mb4_unicode_ci NOT NULL, - `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `dealer_id` bigint(20) unsigned NOT NULL, + `role` enum('admin','sa','mechanic') NOT NULL, + `email` varchar(255) NOT NULL, `email_verified_at` timestamp NULL DEFAULT NULL, - `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `password` varchar(255) NOT NULL, + `remember_token` varchar(100) DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, `deleted_at` timestamp NULL DEFAULT NULL, - `role_id` bigint unsigned NOT NULL, + `role_id` bigint(20) unsigned NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `users_email_unique` (`email`), KEY `users_dealer_id_foreign` (`dealer_id`), @@ -611,15 +694,15 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `works`; /*!40101 SET @saved_cs_client = @@character_set_client */; -/*!50503 SET character_set_client = utf8mb4 */; +/*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `works` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, - `desc` text COLLATE utf8mb4_unicode_ci NOT NULL, + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `desc` text NOT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, - `category_id` bigint unsigned NOT NULL, - `shortname` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `category_id` bigint(20) unsigned NOT NULL, + `shortname` varchar(255) NOT NULL, `deleted_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), KEY `works_category_id_foreign` (`category_id`), @@ -636,6 +719,10 @@ LOCK TABLES `works` WRITE; INSERT INTO `works` VALUES (1,'CUCI','-',NULL,'2022-06-09 08:06:59',1,'Cuci',NULL),(6,'SPOORING','-',NULL,'2022-06-09 08:34:27',3,'SP',NULL),(7,'SPOORING TRUK','-',NULL,'2022-06-09 08:34:38',3,'SP TRUCK',NULL),(8,'SPOORING + BAUT CAMBER','-',NULL,'2022-06-09 08:34:56',3,'SP + BC',NULL),(9,'BALANCING','-',NULL,'2022-06-09 08:35:08',3,'BL',NULL),(10,'BALANCING R < 15','-',NULL,'2022-06-09 08:35:26',3,'BL R<15',NULL),(11,'BALANCING R > 15','-',NULL,'2022-06-09 08:35:43',3,'BL R>15',NULL),(12,'NITROGEN FULL','-',NULL,'2022-06-09 08:36:32',3,'N2',NULL),(13,'NITROGEN TAMBAH','-',NULL,'2022-06-09 08:41:19',3,'N+',NULL),(14,'BAUT CAMBER ','-',NULL,NULL,3,'BC',NULL),(15,'AC CLEANER SINGLE BLOWER','-',NULL,'2022-06-09 08:41:36',3,'SB',NULL),(16,'AC CLEANER DOUBLE BLOWER','-',NULL,'2022-06-09 08:41:45',3,'DB',NULL),(17,'FOGGING','-',NULL,'2022-06-09 08:42:29',3,'FOG',NULL),(18,'GLASS POLISH ','-',NULL,NULL,3,'GP',NULL),(19,'ENGINE DRESSING ','-',NULL,NULL,3,'ED',NULL),(20,'ENGINE CARE ','-',NULL,NULL,3,'EC',NULL),(21,'ENGINE CLEANING UAP ','-',NULL,NULL,3,'ECU',NULL),(22,'BUBUT DISC BRAKE','-',NULL,'2022-06-09 08:44:00',3,'DL',NULL),(23,'TIRE CHANGER ','-',NULL,NULL,3,'TC',NULL),(24,'CHAMBER CLEANER ','-',NULL,NULL,3,'CC',NULL),(25,'DIESEL PURGING ','-',NULL,NULL,3,'DP',NULL),(26,'FUEL INJECTOR CLEANER','-',NULL,'2022-06-09 08:48:35',3,'IC',NULL),(27,'TURBO CLEANER','-',NULL,'2022-06-09 08:45:19',3,'TCC',NULL),(28,'CATALYTIC CLEANER','-',NULL,NULL,3,'CTC',NULL),(29,'INTERIOR CLEANING UAP ','-',NULL,NULL,3,'ICU',NULL),(30,'HHO ','-',NULL,NULL,3,'HHO',NULL),(31,'engine flush','-','2023-06-02 03:35:58','2023-06-02 03:35:58',3,'EF',NULL),(32,'ISI FREON SINGLE BLOWER','-','2023-11-02 04:08:57','2023-11-02 04:08:57',3,'FR SB 1',NULL),(33,'ISI FREON DOUBLE BLOWER','-','2023-11-02 04:09:25','2023-11-02 04:09:25',3,'FR DB 2',NULL),(34,'Oil lining performance','jasa oil lining','2023-12-05 10:26:43','2023-12-05 10:28:49',3,'OLP',NULL),(35,'engine oil performance b1','jasa ganti oli','2023-12-05 10:27:36','2023-12-05 10:28:59',3,'B1',NULL),(36,'engine oil performance b2','jasa ganti oli b2','2023-12-05 10:28:03','2023-12-05 10:29:09',3,'B2',NULL),(37,'Oil lining performance non engine flush','jasa oil lining tanpa engine flush','2024-03-08 06:41:41','2024-03-08 06:42:53',3,'OLP NON EF',NULL),(38,'AC FRESH SERVICE','parfurmed ac','2024-03-13 05:08:15','2024-03-13 05:08:15',3,'AC FRESH',NULL),(39,'AC LIGHT SERVICE - SINGLE BLOWER','penggantian dryer, oli komprespor, dan refrigant','2024-03-13 05:12:47','2024-03-13 05:12:47',3,'AC LIGHT - SB',NULL),(40,'AC LIGHT SERVICE - DOUBLE BLOWER','penggantian dryer, oli komprespor, dan refrigant','2024-03-13 05:13:39','2024-03-13 05:14:18',3,'AC LIGHT - DB',NULL),(41,'AC HEAVY SERVICE - SINGLE BLOWER','penggantian dryer, oli komprespor, dan refrigant (cek kebocoran EVAP)','2024-03-13 05:15:29','2024-03-13 05:15:29',3,'AC HEAVY - SB',NULL),(42,'AC HEAVY SERVICE - DOUBLE BLOWER','penggantian dryer, oli komprespor, dan refrigant (cek kebocoran EVAP)','2024-03-13 05:16:05','2024-03-13 05:16:05',3,'AC HEAVY - DB',NULL),(43,'AC CLEAN SERVICE','pembersihan saluran ac dan evap','2024-04-24 09:49:02','2024-04-24 09:49:02',3,'ACCS',NULL),(44,'COOLANT CHANGER & COOLING SYSTEM CLEANER','kuras radiator dan penggantian coolant','2024-07-08 10:58:52','2024-07-08 10:58:52',3,'C3SC',NULL),(45,'AT CVT FLUSHING','pembersihan transmisi matic cvt','2024-09-18 09:33:09','2024-09-18 09:33:09',3,'AT CVT FLUSHING',NULL),(46,'CUCI SNOW','cuci snow','2024-09-19 08:20:30','2024-09-19 08:20:30',1,'CUCI SNOW',NULL); /*!40000 ALTER TABLE `works` ENABLE KEYS */; UNLOCK TABLES; + +-- +-- Dumping routines for database 'ckb_db' +-- /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -646,4 +733,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2025-06-10 18:16:53 +-- Dump completed on 2025-06-11 17:30:35 diff --git a/composer.json b/composer.json index 70d7194..52297fb 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "laravel/ui": "^3.4", "maatwebsite/excel": "^3.1", "nesbot/carbon": "^2.73", - "yajra/laravel-datatables-oracle": "^9.20" + "yajra/laravel-datatables-oracle": "^9.21" }, "require-dev": { "facade/ignition": "^2.5", diff --git a/composer.lock b/composer.lock index e0ec070..4dfb360 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3e3b47389d4bce664f705134cae65b49", + "content-hash": "a73100beed847d2c43aca4cca10a0d86", "packages": [ { "name": "asm89/stack-cors", @@ -6450,16 +6450,16 @@ }, { "name": "yajra/laravel-datatables-oracle", - "version": "v9.20.0", + "version": "v9.21.2", "source": { "type": "git", "url": "https://github.com/yajra/laravel-datatables.git", - "reference": "4c22b09c8c664df5aad9f17d99c3823c0f2d84e2" + "reference": "a7fd01f06282923e9c63fa27fe6b391e21dc321a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/4c22b09c8c664df5aad9f17d99c3823c0f2d84e2", - "reference": "4c22b09c8c664df5aad9f17d99c3823c0f2d84e2", + "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/a7fd01f06282923e9c63fa27fe6b391e21dc321a", + "reference": "a7fd01f06282923e9c63fa27fe6b391e21dc321a", "shasum": "" }, "require": { @@ -6481,16 +6481,16 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "9.0-dev" - }, "laravel": { - "providers": [ - "Yajra\\DataTables\\DataTablesServiceProvider" - ], "aliases": { "DataTables": "Yajra\\DataTables\\Facades\\DataTables" - } + }, + "providers": [ + "Yajra\\DataTables\\DataTablesServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "9.0-dev" } }, "autoload": { @@ -6519,7 +6519,7 @@ ], "support": { "issues": "https://github.com/yajra/laravel-datatables/issues", - "source": "https://github.com/yajra/laravel-datatables/tree/v9.20.0" + "source": "https://github.com/yajra/laravel-datatables/tree/v9.21.2" }, "funding": [ { @@ -6531,7 +6531,7 @@ "type": "patreon" } ], - "time": "2022-05-08T16:04:16+00:00" + "time": "2022-07-12T04:48:03+00:00" } ], "packages-dev": [ diff --git a/database/migrations/2025_06_12_002513_create_mutations_table.php b/database/migrations/2025_06_12_002513_create_mutations_table.php new file mode 100644 index 0000000..4925d3b --- /dev/null +++ b/database/migrations/2025_06_12_002513_create_mutations_table.php @@ -0,0 +1,46 @@ +id(); + $table->string('mutation_number')->unique(); + $table->foreignId('from_dealer_id')->constrained('dealers'); + $table->foreignId('to_dealer_id')->constrained('dealers'); + $table->enum('status', ['pending', 'sent', 'received', 'approved', 'rejected', 'completed', 'cancelled']) + ->default('sent'); + $table->foreignId('requested_by')->constrained('users'); + $table->foreignId('approved_by')->nullable()->constrained('users'); + $table->timestamp('approved_at')->nullable(); + $table->foreignId('received_by')->nullable()->constrained('users'); + $table->timestamp('received_at')->nullable(); + $table->text('notes')->nullable(); + $table->text('rejection_reason')->nullable(); + $table->timestamps(); + $table->softDeletes(); + + // Indexes untuk performa + $table->index(['from_dealer_id', 'status']); + $table->index(['to_dealer_id', 'status']); + $table->index(['status', 'created_at']); + $table->index('mutation_number'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('mutations'); + } +}; diff --git a/database/migrations/2025_06_12_002623_create_mutation_details_table.php b/database/migrations/2025_06_12_002623_create_mutation_details_table.php new file mode 100644 index 0000000..4a84068 --- /dev/null +++ b/database/migrations/2025_06_12_002623_create_mutation_details_table.php @@ -0,0 +1,35 @@ +id(); + $table->foreignId('mutation_id')->constrained('mutations')->onDelete('cascade'); + $table->foreignId('product_id')->constrained('products'); + $table->decimal('quantity_requested', 15, 2); + $table->decimal('quantity_approved', 15, 2)->default(0); + $table->text('notes')->nullable(); + $table->timestamps(); + + // Indexes untuk performa + $table->index(['mutation_id', 'product_id']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('mutation_details'); + } +}; diff --git a/database/seeders/MutationTestSeeder.php b/database/seeders/MutationTestSeeder.php new file mode 100644 index 0000000..e573498 --- /dev/null +++ b/database/seeders/MutationTestSeeder.php @@ -0,0 +1,159 @@ +get(); + $products = Product::take(5)->get(); + $users = User::take(3)->get(); + + $this->command->info('Dealers found: ' . $dealers->count()); + $this->command->info('Products found: ' . $products->count()); + $this->command->info('Users found: ' . $users->count()); + + if ($dealers->count() < 2 || $products->count() < 2 || $users->count() < 1) { + $this->command->error('Tidak cukup data dealer, produk, atau user untuk membuat test mutation'); + $this->command->error("Need at least 2 dealers, 2 products, 1 user"); + return; + } + + try { + // 1. Mutation dengan status SENT (baru terkirim, menunggu diterima dealer tujuan) + $this->command->info('Creating SENT mutation...'); + $mutation1 = Mutation::create([ + 'from_dealer_id' => $dealers[0]->id, + 'to_dealer_id' => $dealers[1]->id, + 'status' => MutationStatus::SENT, + 'requested_by' => $users[0]->id, + 'notes' => 'Mutasi test - status SENT (menunggu diterima)' + ]); + + MutationDetail::create([ + 'mutation_id' => $mutation1->id, + 'product_id' => $products[0]->id, + 'quantity_requested' => 10.00, + 'notes' => 'Produk test 1' + ]); + + MutationDetail::create([ + 'mutation_id' => $mutation1->id, + 'product_id' => $products[1]->id, + 'quantity_requested' => 5.00, + 'notes' => 'Produk test 2' + ]); + + // 2. Mutation dengan status RECEIVED (sudah diterima, menunggu approval pengirim) + $this->command->info('Creating RECEIVED mutation...'); + $mutation2 = Mutation::create([ + 'from_dealer_id' => $dealers[0]->id, + 'to_dealer_id' => $dealers[1]->id, + 'status' => MutationStatus::RECEIVED, + 'requested_by' => $users[0]->id, + 'received_by' => $users[1]->id ?? $users[0]->id, + 'received_at' => now()->subHours(2), + 'notes' => 'Mutasi test - status RECEIVED (menunggu approval)' + ]); + + MutationDetail::create([ + 'mutation_id' => $mutation2->id, + 'product_id' => $products[0]->id, + 'quantity_requested' => 8.00, + 'notes' => 'Produk untuk approval' + ]); + + // 3. Mutation dengan status APPROVED (sudah diapprove, siap dikompletkan) + $this->command->info('Creating APPROVED mutation...'); + $mutation3 = Mutation::create([ + 'from_dealer_id' => $dealers[0]->id, + 'to_dealer_id' => $dealers[1]->id, + 'status' => MutationStatus::APPROVED, + 'requested_by' => $users[0]->id, + 'received_by' => $users[1]->id ?? $users[0]->id, + 'received_at' => now()->subHours(4), + 'approved_by' => $users[0]->id, + 'approved_at' => now()->subHours(1), + 'notes' => 'Mutasi test - status APPROVED (siap dikompletkan)' + ]); + + $mutation3Detail = MutationDetail::create([ + 'mutation_id' => $mutation3->id, + 'product_id' => $products[0]->id, + 'quantity_requested' => 12.00, + 'quantity_approved' => 10.00, // Approved dengan jumlah berbeda + 'notes' => 'Produk approved parsial' + ]); + + // 4. Mutation dengan status COMPLETED (selesai) + $this->command->info('Creating COMPLETED mutation...'); + $mutation4 = Mutation::create([ + 'from_dealer_id' => $dealers[0]->id, + 'to_dealer_id' => $dealers[1]->id, + 'status' => MutationStatus::COMPLETED, + 'requested_by' => $users[0]->id, + 'received_by' => $users[1]->id ?? $users[0]->id, + 'received_at' => now()->subDay(), + 'approved_by' => $users[0]->id, + 'approved_at' => now()->subHours(6), + 'notes' => 'Mutasi test - status COMPLETED' + ]); + + MutationDetail::create([ + 'mutation_id' => $mutation4->id, + 'product_id' => $products[1]->id, + 'quantity_requested' => 6.00, + 'quantity_approved' => 6.00, + 'notes' => 'Produk completed' + ]); + + // 5. Mutation dengan status REJECTED + $this->command->info('Creating REJECTED mutation...'); + $mutation5 = Mutation::create([ + 'from_dealer_id' => $dealers[0]->id, + 'to_dealer_id' => $dealers[1]->id, + 'status' => MutationStatus::REJECTED, + 'requested_by' => $users[0]->id, + 'received_by' => $users[1]->id ?? $users[0]->id, + 'received_at' => now()->subHours(8), + 'approved_by' => $users[0]->id, + 'approved_at' => now()->subHours(3), + 'rejection_reason' => 'Stock tidak mencukupi untuk produk yang diminta', + 'notes' => 'Mutasi test - status REJECTED' + ]); + + MutationDetail::create([ + 'mutation_id' => $mutation5->id, + 'product_id' => $products[2]->id, + 'quantity_requested' => 20.00, + 'quantity_approved' => 0, + 'notes' => 'Produk rejected' + ]); + + $this->command->info('Test mutations created successfully!'); + $this->command->info('- Mutation SENT: ' . $mutation1->mutation_number); + $this->command->info('- Mutation RECEIVED: ' . $mutation2->mutation_number); + $this->command->info('- Mutation APPROVED: ' . $mutation3->mutation_number); + $this->command->info('- Mutation COMPLETED: ' . $mutation4->mutation_number); + $this->command->info('- Mutation REJECTED: ' . $mutation5->mutation_number); + + } catch (\Exception $e) { + $this->command->error('Error creating test mutations: ' . $e->getMessage()); + $this->command->error('Stack trace: ' . $e->getTraceAsString()); + } + } +} diff --git a/package-lock.json b/package-lock.json index 23f4255..44665ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "ckb", + "name": "html", "lockfileVersion": 2, "requires": true, "packages": { @@ -12664,19 +12664,22 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz", "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", - "dev": true + "dev": true, + "requires": {} }, "@webpack-cli/info": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz", "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", - "dev": true + "dev": true, + "requires": {} }, "@webpack-cli/serve": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz", "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", - "dev": true + "dev": true, + "requires": {} }, "@xtuc/ieee754": { "version": "1.2.0", @@ -12761,7 +12764,8 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "requires": {} }, "ansi-html-community": { "version": "0.0.8", @@ -13055,7 +13059,8 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz", "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==", - "dev": true + "dev": true, + "requires": {} }, "brace-expansion": { "version": "1.1.11", @@ -14026,7 +14031,8 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz", "integrity": "sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg==", - "dev": true + "dev": true, + "requires": {} }, "css-loader": { "version": "5.2.7", @@ -14157,7 +14163,8 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "dev": true + "dev": true, + "requires": {} }, "csso": { "version": "4.2.0", @@ -14469,7 +14476,8 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "dev": true + "dev": true, + "requires": {} } } }, @@ -14490,7 +14498,8 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "dev": true + "dev": true, + "requires": {} } } }, @@ -15337,7 +15346,8 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true + "dev": true, + "requires": {} }, "ieee754": { "version": "1.2.1", @@ -15719,7 +15729,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", - "dev": true + "dev": true, + "requires": {} }, "@webpack-cli/info": { "version": "1.5.0", @@ -15734,7 +15745,8 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", - "dev": true + "dev": true, + "requires": {} }, "interpret": { "version": "2.2.0", @@ -16617,25 +16629,29 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.1.tgz", "integrity": "sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ==", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-duplicates": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-empty": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-overridden": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-load-config": { "version": "3.1.4", @@ -16724,7 +16740,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -16759,7 +16776,8 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "dev": true + "dev": true, + "requires": {} }, "postcss-normalize-display-values": { "version": "5.1.0", @@ -17674,7 +17692,8 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "dev": true + "dev": true, + "requires": {} } } }, @@ -18630,7 +18649,8 @@ "version": "8.18.2", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", - "dev": true + "dev": true, + "requires": {} }, "xmlhttprequest-ssl": { "version": "2.1.2", diff --git a/public/js/warehouse_management/mutations/create.js b/public/js/warehouse_management/mutations/create.js new file mode 100644 index 0000000..11021a4 --- /dev/null +++ b/public/js/warehouse_management/mutations/create.js @@ -0,0 +1,32 @@ +/* + * 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/mutations/create.js": +/*!***************************************************************!*\ + !*** ./resources/js/warehouse_management/mutations/create.js ***! + \***************************************************************/ +/***/ (() => { + +eval("$(document).ready(function () {\n var productIndex = 1; // Initialize Select2\n\n $(\".select2\").select2({\n placeholder: \"Pilih...\",\n allowClear: true\n }); // Prevent same dealer selection\n\n $(\"#from_dealer_id, #to_dealer_id\").on(\"change\", function () {\n var fromDealerId = $(\"#from_dealer_id\").val();\n var toDealerId = $(\"#to_dealer_id\").val();\n\n if (fromDealerId && toDealerId && fromDealerId === toDealerId) {\n $(this).val(\"\").trigger(\"change\");\n alert(\"Dealer asal dan tujuan tidak boleh sama!\");\n } // Update available stock when dealer changes\n\n\n updateAllAvailableStock();\n }); // Add new product row\n\n $(\"#add-product\").on(\"click\", function () {\n var newRow = createProductRow(productIndex);\n $(\"#products-tbody\").append(newRow); // Initialize Select2 for new row\n\n var newSelect = $(\"#products-tbody tr[data-index=\\\"\".concat(productIndex, \"\\\"] .product-select\"));\n newSelect.select2({\n placeholder: \"Pilih Produk...\",\n allowClear: true\n });\n productIndex++;\n updateRemoveButtons();\n }); // Remove product row\n\n $(document).on(\"click\", \".remove-product\", function () {\n $(this).closest(\"tr\").remove();\n updateRemoveButtons();\n reindexRows();\n }); // Handle product selection change\n\n $(document).on(\"change\", \".product-select\", function () {\n var row = $(this).closest(\"tr\");\n var productId = $(this).val();\n var fromDealerId = $(\"#from_dealer_id\").val();\n\n if (productId && fromDealerId) {\n getAvailableStock(productId, fromDealerId, row);\n } else {\n row.find(\".available-stock\").text(\"-\");\n row.find(\".quantity-input\").attr(\"max\", \"\");\n }\n }); // Validate quantity input\n\n $(document).on(\"input\", \".quantity-input\", function () {\n var maxValue = parseFloat($(this).attr(\"max\"));\n var currentValue = parseFloat($(this).val());\n\n if (maxValue && currentValue > maxValue) {\n $(this).val(maxValue);\n $(this).addClass(\"is-invalid\");\n\n if (!$(this).siblings(\".invalid-feedback\").length) {\n $(this).after('Quantity melebihi stock yang tersedia');\n }\n } else {\n $(this).removeClass(\"is-invalid\");\n $(this).siblings(\".invalid-feedback\").remove();\n }\n }); // Form submission\n\n $(\"#mutation-form\").on(\"submit\", function (e) {\n e.preventDefault();\n\n if (!validateForm()) {\n return false;\n }\n\n var submitBtn = $(\"#submit-btn\");\n var originalText = submitBtn.html();\n submitBtn.prop(\"disabled\", true).html(' Menyimpan...'); // Submit form\n\n this.submit();\n });\n\n function createProductRow(index) {\n // Get product options from the existing select\n var existingSelect = $(\".product-select\").first();\n var productOptions = existingSelect.html();\n return \"\\n \\n \\n \\n \").concat(productOptions, \"\\n \\n \\n \\n -\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \");\n }\n\n function updateRemoveButtons() {\n var rows = $(\".product-row\");\n $(\".remove-product\").prop(\"disabled\", rows.length <= 1);\n }\n\n function reindexRows() {\n $(\".product-row\").each(function (index) {\n $(this).attr(\"data-index\", index);\n $(this).find('select[name*=\"product_id\"]').attr(\"name\", \"products[\".concat(index, \"][product_id]\"));\n $(this).find('input[name*=\"quantity_requested\"]').attr(\"name\", \"products[\".concat(index, \"][quantity_requested]\"));\n $(this).find('input[name*=\"notes\"]').attr(\"name\", \"products[\".concat(index, \"][notes]\"));\n });\n productIndex = $(\".product-row\").length;\n }\n\n function getAvailableStock(productId, dealerId, row) {\n $.ajax({\n url: \"/warehouse/mutations/get-product-stock\",\n method: \"GET\",\n data: {\n product_id: productId,\n dealer_id: dealerId\n },\n beforeSend: function beforeSend() {\n row.find(\".available-stock\").html('');\n },\n success: function success(response) {\n var stock = parseFloat(response.current_stock);\n row.find(\".available-stock\").text(stock.toLocaleString());\n row.find(\".quantity-input\").attr(\"max\", stock); // Set max value message\n\n if (stock <= 0) {\n row.find(\".available-stock\").addClass(\"text-danger\").removeClass(\"text-muted\");\n row.find(\".quantity-input\").attr(\"readonly\", true).val(\"\");\n } else {\n row.find(\".available-stock\").removeClass(\"text-danger\").addClass(\"text-muted\");\n row.find(\".quantity-input\").attr(\"readonly\", false);\n }\n },\n error: function error() {\n row.find(\".available-stock\").text(\"Error\").addClass(\"text-danger\");\n }\n });\n }\n\n function updateAllAvailableStock() {\n var fromDealerId = $(\"#from_dealer_id\").val();\n $(\".product-row\").each(function () {\n var row = $(this);\n var productId = row.find(\".product-select\").val();\n\n if (productId && fromDealerId) {\n getAvailableStock(productId, fromDealerId, row);\n } else {\n row.find(\".available-stock\").text(\"-\");\n row.find(\".quantity-input\").attr(\"max\", \"\");\n }\n });\n }\n\n function validateForm() {\n var isValid = true;\n var fromDealerId = $(\"#from_dealer_id\").val();\n var toDealerId = $(\"#to_dealer_id\").val(); // Check dealers\n\n if (!fromDealerId) {\n alert(\"Pilih dealer asal\");\n return false;\n }\n\n if (!toDealerId) {\n alert(\"Pilih dealer tujuan\");\n return false;\n }\n\n if (fromDealerId === toDealerId) {\n alert(\"Dealer asal dan tujuan tidak boleh sama\");\n return false;\n } // Check products\n\n\n var productRows = $(\".product-row\");\n\n if (productRows.length === 0) {\n alert(\"Tambahkan minimal satu produk\");\n return false;\n }\n\n var hasValidProduct = false;\n productRows.each(function () {\n var productId = $(this).find(\".product-select\").val();\n var quantity = $(this).find(\".quantity-input\").val();\n\n if (productId && quantity && parseFloat(quantity) > 0) {\n hasValidProduct = true;\n }\n });\n\n if (!hasValidProduct) {\n alert(\"Pilih minimal satu produk dengan quantity yang valid\");\n return false;\n }\n\n return isValid;\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyIkIiwiZG9jdW1lbnQiLCJyZWFkeSIsInByb2R1Y3RJbmRleCIsInNlbGVjdDIiLCJwbGFjZWhvbGRlciIsImFsbG93Q2xlYXIiLCJvbiIsImZyb21EZWFsZXJJZCIsInZhbCIsInRvRGVhbGVySWQiLCJ0cmlnZ2VyIiwiYWxlcnQiLCJ1cGRhdGVBbGxBdmFpbGFibGVTdG9jayIsIm5ld1JvdyIsImNyZWF0ZVByb2R1Y3RSb3ciLCJhcHBlbmQiLCJuZXdTZWxlY3QiLCJ1cGRhdGVSZW1vdmVCdXR0b25zIiwiY2xvc2VzdCIsInJlbW92ZSIsInJlaW5kZXhSb3dzIiwicm93IiwicHJvZHVjdElkIiwiZ2V0QXZhaWxhYmxlU3RvY2siLCJmaW5kIiwidGV4dCIsImF0dHIiLCJtYXhWYWx1ZSIsInBhcnNlRmxvYXQiLCJjdXJyZW50VmFsdWUiLCJhZGRDbGFzcyIsInNpYmxpbmdzIiwibGVuZ3RoIiwiYWZ0ZXIiLCJyZW1vdmVDbGFzcyIsImUiLCJwcmV2ZW50RGVmYXVsdCIsInZhbGlkYXRlRm9ybSIsInN1Ym1pdEJ0biIsIm9yaWdpbmFsVGV4dCIsImh0bWwiLCJwcm9wIiwic3VibWl0IiwiaW5kZXgiLCJleGlzdGluZ1NlbGVjdCIsImZpcnN0IiwicHJvZHVjdE9wdGlvbnMiLCJyb3dzIiwiZWFjaCIsImRlYWxlcklkIiwiYWpheCIsInVybCIsIm1ldGhvZCIsImRhdGEiLCJwcm9kdWN0X2lkIiwiZGVhbGVyX2lkIiwiYmVmb3JlU2VuZCIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsInN0b2NrIiwiY3VycmVudF9zdG9jayIsInRvTG9jYWxlU3RyaW5nIiwiZXJyb3IiLCJpc1ZhbGlkIiwicHJvZHVjdFJvd3MiLCJoYXNWYWxpZFByb2R1Y3QiLCJxdWFudGl0eSJdLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvbXV0YXRpb25zL2NyZWF0ZS5qcz8xNWI1Il0sInNvdXJjZXNDb250ZW50IjpbIiQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgcHJvZHVjdEluZGV4ID0gMTtcblxuICAgIC8vIEluaXRpYWxpemUgU2VsZWN0MlxuICAgICQoXCIuc2VsZWN0MlwiKS5zZWxlY3QyKHtcbiAgICAgICAgcGxhY2Vob2xkZXI6IFwiUGlsaWguLi5cIixcbiAgICAgICAgYWxsb3dDbGVhcjogdHJ1ZSxcbiAgICB9KTtcblxuICAgIC8vIFByZXZlbnQgc2FtZSBkZWFsZXIgc2VsZWN0aW9uXG4gICAgJChcIiNmcm9tX2RlYWxlcl9pZCwgI3RvX2RlYWxlcl9pZFwiKS5vbihcImNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGZyb21EZWFsZXJJZCA9ICQoXCIjZnJvbV9kZWFsZXJfaWRcIikudmFsKCk7XG4gICAgICAgIGNvbnN0IHRvRGVhbGVySWQgPSAkKFwiI3RvX2RlYWxlcl9pZFwiKS52YWwoKTtcblxuICAgICAgICBpZiAoZnJvbURlYWxlcklkICYmIHRvRGVhbGVySWQgJiYgZnJvbURlYWxlcklkID09PSB0b0RlYWxlcklkKSB7XG4gICAgICAgICAgICAkKHRoaXMpLnZhbChcIlwiKS50cmlnZ2VyKFwiY2hhbmdlXCIpO1xuICAgICAgICAgICAgYWxlcnQoXCJEZWFsZXIgYXNhbCBkYW4gdHVqdWFuIHRpZGFrIGJvbGVoIHNhbWEhXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXBkYXRlIGF2YWlsYWJsZSBzdG9jayB3aGVuIGRlYWxlciBjaGFuZ2VzXG4gICAgICAgIHVwZGF0ZUFsbEF2YWlsYWJsZVN0b2NrKCk7XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgbmV3IHByb2R1Y3Qgcm93XG4gICAgJChcIiNhZGQtcHJvZHVjdFwiKS5vbihcImNsaWNrXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbmV3Um93ID0gY3JlYXRlUHJvZHVjdFJvdyhwcm9kdWN0SW5kZXgpO1xuICAgICAgICAkKFwiI3Byb2R1Y3RzLXRib2R5XCIpLmFwcGVuZChuZXdSb3cpO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgU2VsZWN0MiBmb3IgbmV3IHJvd1xuICAgICAgICBjb25zdCBuZXdTZWxlY3QgPSAkKFxuICAgICAgICAgICAgYCNwcm9kdWN0cy10Ym9keSB0cltkYXRhLWluZGV4PVwiJHtwcm9kdWN0SW5kZXh9XCJdIC5wcm9kdWN0LXNlbGVjdGBcbiAgICAgICAgKTtcbiAgICAgICAgbmV3U2VsZWN0LnNlbGVjdDIoe1xuICAgICAgICAgICAgcGxhY2Vob2xkZXI6IFwiUGlsaWggUHJvZHVrLi4uXCIsXG4gICAgICAgICAgICBhbGxvd0NsZWFyOiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgICBwcm9kdWN0SW5kZXgrKztcbiAgICAgICAgdXBkYXRlUmVtb3ZlQnV0dG9ucygpO1xuICAgIH0pO1xuXG4gICAgLy8gUmVtb3ZlIHByb2R1Y3Qgcm93XG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi5yZW1vdmUtcHJvZHVjdFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICQodGhpcykuY2xvc2VzdChcInRyXCIpLnJlbW92ZSgpO1xuICAgICAgICB1cGRhdGVSZW1vdmVCdXR0b25zKCk7XG4gICAgICAgIHJlaW5kZXhSb3dzKCk7XG4gICAgfSk7XG5cbiAgICAvLyBIYW5kbGUgcHJvZHVjdCBzZWxlY3Rpb24gY2hhbmdlXG4gICAgJChkb2N1bWVudCkub24oXCJjaGFuZ2VcIiwgXCIucHJvZHVjdC1zZWxlY3RcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByb3cgPSAkKHRoaXMpLmNsb3Nlc3QoXCJ0clwiKTtcbiAgICAgICAgY29uc3QgcHJvZHVjdElkID0gJCh0aGlzKS52YWwoKTtcbiAgICAgICAgY29uc3QgZnJvbURlYWxlcklkID0gJChcIiNmcm9tX2RlYWxlcl9pZFwiKS52YWwoKTtcblxuICAgICAgICBpZiAocHJvZHVjdElkICYmIGZyb21EZWFsZXJJZCkge1xuICAgICAgICAgICAgZ2V0QXZhaWxhYmxlU3RvY2socHJvZHVjdElkLCBmcm9tRGVhbGVySWQsIHJvdyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByb3cuZmluZChcIi5hdmFpbGFibGUtc3RvY2tcIikudGV4dChcIi1cIik7XG4gICAgICAgICAgICByb3cuZmluZChcIi5xdWFudGl0eS1pbnB1dFwiKS5hdHRyKFwibWF4XCIsIFwiXCIpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBWYWxpZGF0ZSBxdWFudGl0eSBpbnB1dFxuICAgICQoZG9jdW1lbnQpLm9uKFwiaW5wdXRcIiwgXCIucXVhbnRpdHktaW5wdXRcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBtYXhWYWx1ZSA9IHBhcnNlRmxvYXQoJCh0aGlzKS5hdHRyKFwibWF4XCIpKTtcbiAgICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gcGFyc2VGbG9hdCgkKHRoaXMpLnZhbCgpKTtcblxuICAgICAgICBpZiAobWF4VmFsdWUgJiYgY3VycmVudFZhbHVlID4gbWF4VmFsdWUpIHtcbiAgICAgICAgICAgICQodGhpcykudmFsKG1heFZhbHVlKTtcbiAgICAgICAgICAgICQodGhpcykuYWRkQ2xhc3MoXCJpcy1pbnZhbGlkXCIpO1xuXG4gICAgICAgICAgICBpZiAoISQodGhpcykuc2libGluZ3MoXCIuaW52YWxpZC1mZWVkYmFja1wiKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAkKHRoaXMpLmFmdGVyKFxuICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5RdWFudGl0eSBtZWxlYmloaSBzdG9jayB5YW5nIHRlcnNlZGlhPC9kaXY+J1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkKHRoaXMpLnJlbW92ZUNsYXNzKFwiaXMtaW52YWxpZFwiKTtcbiAgICAgICAgICAgICQodGhpcykuc2libGluZ3MoXCIuaW52YWxpZC1mZWVkYmFja1wiKS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gRm9ybSBzdWJtaXNzaW9uXG4gICAgJChcIiNtdXRhdGlvbi1mb3JtXCIpLm9uKFwic3VibWl0XCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICBpZiAoIXZhbGlkYXRlRm9ybSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdWJtaXRCdG4gPSAkKFwiI3N1Ym1pdC1idG5cIik7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsVGV4dCA9IHN1Ym1pdEJ0bi5odG1sKCk7XG5cbiAgICAgICAgc3VibWl0QnRuXG4gICAgICAgICAgICAucHJvcChcImRpc2FibGVkXCIsIHRydWUpXG4gICAgICAgICAgICAuaHRtbCgnPGkgY2xhc3M9XCJsYSBsYS1zcGlubmVyIGxhLXNwaW5cIj48L2k+IE1lbnlpbXBhbi4uLicpO1xuXG4gICAgICAgIC8vIFN1Ym1pdCBmb3JtXG4gICAgICAgIHRoaXMuc3VibWl0KCk7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVQcm9kdWN0Um93KGluZGV4KSB7XG4gICAgICAgIC8vIEdldCBwcm9kdWN0IG9wdGlvbnMgZnJvbSB0aGUgZXhpc3Rpbmcgc2VsZWN0XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nU2VsZWN0ID0gJChcIi5wcm9kdWN0LXNlbGVjdFwiKS5maXJzdCgpO1xuICAgICAgICBjb25zdCBwcm9kdWN0T3B0aW9ucyA9IGV4aXN0aW5nU2VsZWN0Lmh0bWwoKTtcblxuICAgICAgICByZXR1cm4gYFxuICAgICAgICAgICAgPHRyIGNsYXNzPVwicHJvZHVjdC1yb3dcIiBkYXRhLWluZGV4PVwiJHtpbmRleH1cIj5cbiAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgbmFtZT1cInByb2R1Y3RzWyR7aW5kZXh9XVtwcm9kdWN0X2lkXVwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHNlbGVjdDIgcHJvZHVjdC1zZWxlY3RcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7cHJvZHVjdE9wdGlvbnN9XG4gICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImF2YWlsYWJsZS1zdG9jayB0ZXh0LW11dGVkXCI+LTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJwcm9kdWN0c1ske2luZGV4fV1bcXVhbnRpdHlfcmVxdWVzdGVkXVwiIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgcXVhbnRpdHktaW5wdXRcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbj1cIjAuMDFcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXA9XCIwLjAxXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIjBcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkPlxuICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJwcm9kdWN0c1ske2luZGV4fV1bbm90ZXNdXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJDYXRhdGFuIHByb2R1ayAob3BzaW9uYWwpXCI+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXIgYnRuLXNtIHJlbW92ZS1wcm9kdWN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImxhIGxhLXRyYXNoXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgYDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1cGRhdGVSZW1vdmVCdXR0b25zKCkge1xuICAgICAgICBjb25zdCByb3dzID0gJChcIi5wcm9kdWN0LXJvd1wiKTtcbiAgICAgICAgJChcIi5yZW1vdmUtcHJvZHVjdFwiKS5wcm9wKFwiZGlzYWJsZWRcIiwgcm93cy5sZW5ndGggPD0gMSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVpbmRleFJvd3MoKSB7XG4gICAgICAgICQoXCIucHJvZHVjdC1yb3dcIikuZWFjaChmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICAgICAgICAgICQodGhpcykuYXR0cihcImRhdGEtaW5kZXhcIiwgaW5kZXgpO1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCdzZWxlY3RbbmFtZSo9XCJwcm9kdWN0X2lkXCJdJylcbiAgICAgICAgICAgICAgICAuYXR0cihcIm5hbWVcIiwgYHByb2R1Y3RzWyR7aW5kZXh9XVtwcm9kdWN0X2lkXWApO1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCdpbnB1dFtuYW1lKj1cInF1YW50aXR5X3JlcXVlc3RlZFwiXScpXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJuYW1lXCIsIGBwcm9kdWN0c1ske2luZGV4fV1bcXVhbnRpdHlfcmVxdWVzdGVkXWApO1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCdpbnB1dFtuYW1lKj1cIm5vdGVzXCJdJylcbiAgICAgICAgICAgICAgICAuYXR0cihcIm5hbWVcIiwgYHByb2R1Y3RzWyR7aW5kZXh9XVtub3Rlc11gKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHByb2R1Y3RJbmRleCA9ICQoXCIucHJvZHVjdC1yb3dcIikubGVuZ3RoO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldEF2YWlsYWJsZVN0b2NrKHByb2R1Y3RJZCwgZGVhbGVySWQsIHJvdykge1xuICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBcIi93YXJlaG91c2UvbXV0YXRpb25zL2dldC1wcm9kdWN0LXN0b2NrXCIsXG4gICAgICAgICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgcHJvZHVjdF9pZDogcHJvZHVjdElkLFxuICAgICAgICAgICAgICAgIGRlYWxlcl9pZDogZGVhbGVySWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYmVmb3JlU2VuZDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJvdy5maW5kKFwiLmF2YWlsYWJsZS1zdG9ja1wiKS5odG1sKFxuICAgICAgICAgICAgICAgICAgICAnPGkgY2xhc3M9XCJsYSBsYS1zcGlubmVyIGxhLXNwaW5cIj48L2k+J1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RvY2sgPSBwYXJzZUZsb2F0KHJlc3BvbnNlLmN1cnJlbnRfc3RvY2spO1xuICAgICAgICAgICAgICAgIHJvdy5maW5kKFwiLmF2YWlsYWJsZS1zdG9ja1wiKS50ZXh0KHN0b2NrLnRvTG9jYWxlU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgIHJvdy5maW5kKFwiLnF1YW50aXR5LWlucHV0XCIpLmF0dHIoXCJtYXhcIiwgc3RvY2spO1xuXG4gICAgICAgICAgICAgICAgLy8gU2V0IG1heCB2YWx1ZSBtZXNzYWdlXG4gICAgICAgICAgICAgICAgaWYgKHN0b2NrIDw9IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcm93LmZpbmQoXCIuYXZhaWxhYmxlLXN0b2NrXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoXCJ0ZXh0LWRhbmdlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKFwidGV4dC1tdXRlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgcm93LmZpbmQoXCIucXVhbnRpdHktaW5wdXRcIikuYXR0cihcInJlYWRvbmx5XCIsIHRydWUpLnZhbChcIlwiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByb3cuZmluZChcIi5hdmFpbGFibGUtc3RvY2tcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhcInRleHQtZGFuZ2VyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoXCJ0ZXh0LW11dGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICByb3cuZmluZChcIi5xdWFudGl0eS1pbnB1dFwiKS5hdHRyKFwicmVhZG9ubHlcIiwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJvdy5maW5kKFwiLmF2YWlsYWJsZS1zdG9ja1wiKVxuICAgICAgICAgICAgICAgICAgICAudGV4dChcIkVycm9yXCIpXG4gICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhcInRleHQtZGFuZ2VyXCIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdXBkYXRlQWxsQXZhaWxhYmxlU3RvY2soKSB7XG4gICAgICAgIGNvbnN0IGZyb21EZWFsZXJJZCA9ICQoXCIjZnJvbV9kZWFsZXJfaWRcIikudmFsKCk7XG5cbiAgICAgICAgJChcIi5wcm9kdWN0LXJvd1wiKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHJvdyA9ICQodGhpcyk7XG4gICAgICAgICAgICBjb25zdCBwcm9kdWN0SWQgPSByb3cuZmluZChcIi5wcm9kdWN0LXNlbGVjdFwiKS52YWwoKTtcblxuICAgICAgICAgICAgaWYgKHByb2R1Y3RJZCAmJiBmcm9tRGVhbGVySWQpIHtcbiAgICAgICAgICAgICAgICBnZXRBdmFpbGFibGVTdG9jayhwcm9kdWN0SWQsIGZyb21EZWFsZXJJZCwgcm93KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcm93LmZpbmQoXCIuYXZhaWxhYmxlLXN0b2NrXCIpLnRleHQoXCItXCIpO1xuICAgICAgICAgICAgICAgIHJvdy5maW5kKFwiLnF1YW50aXR5LWlucHV0XCIpLmF0dHIoXCJtYXhcIiwgXCJcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbGlkYXRlRm9ybSgpIHtcbiAgICAgICAgbGV0IGlzVmFsaWQgPSB0cnVlO1xuICAgICAgICBjb25zdCBmcm9tRGVhbGVySWQgPSAkKFwiI2Zyb21fZGVhbGVyX2lkXCIpLnZhbCgpO1xuICAgICAgICBjb25zdCB0b0RlYWxlcklkID0gJChcIiN0b19kZWFsZXJfaWRcIikudmFsKCk7XG5cbiAgICAgICAgLy8gQ2hlY2sgZGVhbGVyc1xuICAgICAgICBpZiAoIWZyb21EZWFsZXJJZCkge1xuICAgICAgICAgICAgYWxlcnQoXCJQaWxpaCBkZWFsZXIgYXNhbFwiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdG9EZWFsZXJJZCkge1xuICAgICAgICAgICAgYWxlcnQoXCJQaWxpaCBkZWFsZXIgdHVqdWFuXCIpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZyb21EZWFsZXJJZCA9PT0gdG9EZWFsZXJJZCkge1xuICAgICAgICAgICAgYWxlcnQoXCJEZWFsZXIgYXNhbCBkYW4gdHVqdWFuIHRpZGFrIGJvbGVoIHNhbWFcIik7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBwcm9kdWN0c1xuICAgICAgICBjb25zdCBwcm9kdWN0Um93cyA9ICQoXCIucHJvZHVjdC1yb3dcIik7XG4gICAgICAgIGlmIChwcm9kdWN0Um93cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGFsZXJ0KFwiVGFtYmFoa2FuIG1pbmltYWwgc2F0dSBwcm9kdWtcIik7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgaGFzVmFsaWRQcm9kdWN0ID0gZmFsc2U7XG4gICAgICAgIHByb2R1Y3RSb3dzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgcHJvZHVjdElkID0gJCh0aGlzKS5maW5kKFwiLnByb2R1Y3Qtc2VsZWN0XCIpLnZhbCgpO1xuICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSAkKHRoaXMpLmZpbmQoXCIucXVhbnRpdHktaW5wdXRcIikudmFsKCk7XG5cbiAgICAgICAgICAgIGlmIChwcm9kdWN0SWQgJiYgcXVhbnRpdHkgJiYgcGFyc2VGbG9hdChxdWFudGl0eSkgPiAwKSB7XG4gICAgICAgICAgICAgICAgaGFzVmFsaWRQcm9kdWN0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFoYXNWYWxpZFByb2R1Y3QpIHtcbiAgICAgICAgICAgIGFsZXJ0KFwiUGlsaWggbWluaW1hbCBzYXR1IHByb2R1ayBkZW5nYW4gcXVhbnRpdHkgeWFuZyB2YWxpZFwiKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpc1ZhbGlkO1xuICAgIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQUEsQ0FBQyxDQUFDQyxRQUFELENBQUQsQ0FBWUMsS0FBWixDQUFrQixZQUFZO0VBQzFCLElBQUlDLFlBQVksR0FBRyxDQUFuQixDQUQwQixDQUcxQjs7RUFDQUgsQ0FBQyxDQUFDLFVBQUQsQ0FBRCxDQUFjSSxPQUFkLENBQXNCO0lBQ2xCQyxXQUFXLEVBQUUsVUFESztJQUVsQkMsVUFBVSxFQUFFO0VBRk0sQ0FBdEIsRUFKMEIsQ0FTMUI7O0VBQ0FOLENBQUMsQ0FBQyxnQ0FBRCxDQUFELENBQW9DTyxFQUFwQyxDQUF1QyxRQUF2QyxFQUFpRCxZQUFZO0lBQ3pELElBQU1DLFlBQVksR0FBR1IsQ0FBQyxDQUFDLGlCQUFELENBQUQsQ0FBcUJTLEdBQXJCLEVBQXJCO0lBQ0EsSUFBTUMsVUFBVSxHQUFHVixDQUFDLENBQUMsZUFBRCxDQUFELENBQW1CUyxHQUFuQixFQUFuQjs7SUFFQSxJQUFJRCxZQUFZLElBQUlFLFVBQWhCLElBQThCRixZQUFZLEtBQUtFLFVBQW5ELEVBQStEO01BQzNEVixDQUFDLENBQUMsSUFBRCxDQUFELENBQVFTLEdBQVIsQ0FBWSxFQUFaLEVBQWdCRSxPQUFoQixDQUF3QixRQUF4QjtNQUNBQyxLQUFLLENBQUMsMENBQUQsQ0FBTDtJQUNILENBUHdELENBU3pEOzs7SUFDQUMsdUJBQXVCO0VBQzFCLENBWEQsRUFWMEIsQ0F1QjFCOztFQUNBYixDQUFDLENBQUMsY0FBRCxDQUFELENBQWtCTyxFQUFsQixDQUFxQixPQUFyQixFQUE4QixZQUFZO0lBQ3RDLElBQU1PLE1BQU0sR0FBR0MsZ0JBQWdCLENBQUNaLFlBQUQsQ0FBL0I7SUFDQUgsQ0FBQyxDQUFDLGlCQUFELENBQUQsQ0FBcUJnQixNQUFyQixDQUE0QkYsTUFBNUIsRUFGc0MsQ0FJdEM7O0lBQ0EsSUFBTUcsU0FBUyxHQUFHakIsQ0FBQywy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\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/mutations/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/mutations/create.js"](); +/******/ +/******/ })() +; \ No newline at end of file diff --git a/public/js/warehouse_management/mutations/index.js b/public/js/warehouse_management/mutations/index.js new file mode 100644 index 0000000..c6bba40 --- /dev/null +++ b/public/js/warehouse_management/mutations/index.js @@ -0,0 +1,32 @@ +/* + * 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/mutations/index.js": +/*!**************************************************************!*\ + !*** ./resources/js/warehouse_management/mutations/index.js ***! + \**************************************************************/ +/***/ (() => { + +eval("$(document).ready(function () {\n // Initialize DataTable\n var table = $(\"#mutations-table\").DataTable({\n processing: true,\n serverSide: true,\n ajax: {\n url: $(\"#mutations-table\").data(\"url\"),\n type: \"GET\"\n },\n columns: [{\n data: \"DT_RowIndex\",\n name: \"DT_RowIndex\",\n orderable: false,\n searchable: false,\n width: \"5%\"\n }, {\n data: \"mutation_number\",\n name: \"mutation_number\",\n width: \"12%\"\n }, {\n data: \"created_at\",\n name: \"created_at\",\n width: \"12%\"\n }, {\n data: \"from_dealer\",\n name: \"fromDealer.name\",\n width: \"15%\"\n }, {\n data: \"to_dealer\",\n name: \"toDealer.name\",\n width: \"15%\"\n }, {\n data: \"requested_by\",\n name: \"requestedBy.name\",\n width: \"12%\"\n }, {\n data: \"total_items\",\n name: \"total_items\",\n width: \"8%\",\n className: \"text-center\"\n }, {\n data: \"status\",\n name: \"status\",\n width: \"12%\",\n className: \"text-center\"\n }, {\n data: \"action\",\n name: \"action\",\n orderable: false,\n searchable: false,\n width: \"15%\",\n className: \"text-center\"\n }],\n order: [[2, \"desc\"]],\n // Order by created_at desc\n pageLength: 10,\n responsive: true,\n language: {\n processing: \"Memuat data...\",\n lengthMenu: \"Tampilkan _MENU_ data per halaman\",\n zeroRecords: \"Data tidak ditemukan\",\n info: \"Menampilkan _START_ sampai _END_ dari _TOTAL_ data\",\n infoEmpty: \"Menampilkan 0 sampai 0 dari 0 data\",\n infoFiltered: \"(difilter dari _MAX_ total data)\"\n }\n }); // Handle Receive Button Click\n\n $(document).on(\"click\", \".btn-receive\", function () {\n var mutationId = $(this).data(\"id\");\n $(\"#receiveModal\" + mutationId).modal(\"show\");\n }); // Handle Approve Button Click\n\n $(document).on(\"click\", \".btn-approve\", function () {\n var mutationId = $(this).data(\"id\"); // Load mutation details via AJAX\n\n $.ajax({\n url: \"/warehouse/mutations/\" + mutationId + \"/details\",\n type: \"GET\",\n beforeSend: function beforeSend() {\n $(\"#mutation-details\" + mutationId).html('' + '' + 'Loading...' + \"\" + \"Memuat detail produk...\" + \"\");\n },\n success: function success(response) {\n var detailsHtml = \"Detail Produk:\";\n detailsHtml += '';\n detailsHtml += '';\n detailsHtml += \"\";\n detailsHtml += \"\";\n detailsHtml += \"Produk\";\n detailsHtml += \"Diminta\";\n detailsHtml += \"Disetujui\";\n detailsHtml += \"Stock Tersedia\";\n detailsHtml += \"\";\n detailsHtml += \"\";\n detailsHtml += \"\";\n response.details.forEach(function (detail, index) {\n detailsHtml += \"\";\n detailsHtml += \"\" + detail.product.name + \"\";\n detailsHtml += \"\" + parseFloat(detail.quantity_requested).toLocaleString() + \"\";\n detailsHtml += \"\";\n detailsHtml += '';\n detailsHtml += \"\";\n detailsHtml += \"\" + parseFloat(detail.available_stock).toLocaleString() + \"\";\n detailsHtml += \"\";\n });\n detailsHtml += \"\";\n detailsHtml += \"\";\n detailsHtml += \"\";\n $(\"#mutation-details\" + mutationId).html(detailsHtml);\n },\n error: function error() {\n $(\"#mutation-details\" + mutationId).html('Gagal memuat detail produk');\n }\n });\n $(\"#approveModal\" + mutationId).modal(\"show\");\n }); // Handle other button clicks\n\n $(document).on(\"click\", \".btn-reject\", function () {\n var mutationId = $(this).data(\"id\");\n $(\"#rejectModal\" + mutationId).modal(\"show\");\n });\n $(document).on(\"click\", \".btn-complete\", function () {\n var mutationId = $(this).data(\"id\");\n $(\"#completeModal\" + mutationId).modal(\"show\");\n }); // Handle Cancel Button Click with SweetAlert\n\n $(document).on(\"click\", \".btn-cancel\", function () {\n var mutationId = $(this).data(\"id\");\n\n if (typeof Swal !== \"undefined\") {\n Swal.fire({\n title: \"Batalkan Mutasi?\",\n text: \"Apakah Anda yakin ingin membatalkan mutasi ini?\",\n icon: \"warning\",\n showCancelButton: true,\n confirmButtonColor: \"#d33\",\n cancelButtonColor: \"#3085d6\",\n confirmButtonText: \"Ya, Batalkan\",\n cancelButtonText: \"Batal\"\n }).then(function (result) {\n if (result.isConfirmed) {\n cancelMutation(mutationId);\n }\n });\n } else {\n if (confirm(\"Apakah Anda yakin ingin membatalkan mutasi ini?\")) {\n cancelMutation(mutationId);\n }\n }\n });\n\n function cancelMutation(mutationId) {\n $.ajax({\n url: \"/warehouse/mutations/\" + mutationId + \"/cancel\",\n type: \"POST\",\n data: {\n _token: $('meta[name=\"csrf-token\"]').attr(\"content\")\n },\n success: function success(response) {\n if (typeof Swal !== \"undefined\") {\n Swal.fire({\n title: \"Berhasil!\",\n text: \"Mutasi berhasil dibatalkan\",\n icon: \"success\",\n timer: 2000,\n showConfirmButton: false\n });\n } else {\n alert(\"Mutasi berhasil dibatalkan\");\n }\n\n table.ajax.reload();\n },\n error: function error(xhr) {\n var _xhr$responseJSON;\n\n var errorMsg = ((_xhr$responseJSON = xhr.responseJSON) === null || _xhr$responseJSON === void 0 ? void 0 : _xhr$responseJSON.message) || \"Gagal membatalkan mutasi\";\n\n if (typeof Swal !== \"undefined\") {\n Swal.fire({\n title: \"Error!\",\n text: errorMsg,\n icon: \"error\"\n });\n } else {\n alert(\"Error: \" + errorMsg);\n }\n }\n });\n } // Handle form submissions with loading state\n\n\n $(document).on(\"submit\", \".approve-form\", function () {\n $(this).find('button[type=\"submit\"]').prop(\"disabled\", true).html(\"Memproses...\");\n }); // Auto-calculate approved quantity based on available stock\n\n $(document).on(\"input\", 'input[name*=\"quantity_approved\"]', function () {\n var maxValue = parseFloat($(this).attr(\"max\"));\n var currentValue = parseFloat($(this).val());\n\n if (maxValue && currentValue > maxValue) {\n $(this).val(maxValue);\n $(this).addClass(\"is-invalid\");\n\n if (!$(this).siblings(\".invalid-feedback\").length) {\n $(this).after('Jumlah melebihi stock yang tersedia');\n }\n } else {\n $(this).removeClass(\"is-invalid\");\n $(this).siblings(\".invalid-feedback\").remove();\n }\n });\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyIkIiwiZG9jdW1lbnQiLCJyZWFkeSIsInRhYmxlIiwiRGF0YVRhYmxlIiwicHJvY2Vzc2luZyIsInNlcnZlclNpZGUiLCJhamF4IiwidXJsIiwiZGF0YSIsInR5cGUiLCJjb2x1bW5zIiwibmFtZSIsIm9yZGVyYWJsZSIsInNlYXJjaGFibGUiLCJ3aWR0aCIsImNsYXNzTmFtZSIsIm9yZGVyIiwicGFnZUxlbmd0aCIsInJlc3BvbnNpdmUiLCJsYW5ndWFnZSIsImxlbmd0aE1lbnUiLCJ6ZXJvUmVjb3JkcyIsImluZm8iLCJpbmZvRW1wdHkiLCJpbmZvRmlsdGVyZWQiLCJvbiIsIm11dGF0aW9uSWQiLCJtb2RhbCIsImJlZm9yZVNlbmQiLCJodG1sIiwic3VjY2VzcyIsInJlc3BvbnNlIiwiZGV0YWlsc0h0bWwiLCJkZXRhaWxzIiwiZm9yRWFjaCIsImRldGFpbCIsImluZGV4IiwicHJvZHVjdCIsInBhcnNlRmxvYXQiLCJxdWFudGl0eV9yZXF1ZXN0ZWQiLCJ0b0xvY2FsZVN0cmluZyIsImlkIiwiTWF0aCIsIm1pbiIsImF2YWlsYWJsZV9zdG9jayIsImVycm9yIiwiU3dhbCIsImZpcmUiLCJ0aXRsZSIsInRleHQiLCJpY29uIiwic2hvd0NhbmNlbEJ1dHRvbiIsImNvbmZpcm1CdXR0b25Db2xvciIsImNhbmNlbEJ1dHRvbkNvbG9yIiwiY29uZmlybUJ1dHRvblRleHQiLCJjYW5jZWxCdXR0b25UZXh0IiwidGhlbiIsInJlc3VsdCIsImlzQ29uZmlybWVkIiwiY2FuY2VsTXV0YXRpb24iLCJjb25maXJtIiwiX3Rva2VuIiwiYXR0ciIsInRpbWVyIiwic2hvd0NvbmZpcm1CdXR0b24iLCJhbGVydCIsInJlbG9hZCIsInhociIsImVycm9yTXNnIiwicmVzcG9uc2VKU09OIiwibWVzc2FnZSIsImZpbmQiLCJwcm9wIiwibWF4VmFsdWUiLCJjdXJyZW50VmFsdWUiLCJ2YWwiLCJhZGRDbGFzcyIsInNpYmxpbmdzIiwibGVuZ3RoIiwiYWZ0ZXIiLCJyZW1vdmVDbGFzcyIsInJlbW92ZSJdLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvbXV0YXRpb25zL2luZGV4LmpzPzdhNGUiXSwic291cmNlc0NvbnRlbnQiOlsiJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24gKCkge1xuICAgIC8vIEluaXRpYWxpemUgRGF0YVRhYmxlXG4gICAgdmFyIHRhYmxlID0gJChcIiNtdXRhdGlvbnMtdGFibGVcIikuRGF0YVRhYmxlKHtcbiAgICAgICAgcHJvY2Vzc2luZzogdHJ1ZSxcbiAgICAgICAgc2VydmVyU2lkZTogdHJ1ZSxcbiAgICAgICAgYWpheDoge1xuICAgICAgICAgICAgdXJsOiAkKFwiI211dGF0aW9ucy10YWJsZVwiKS5kYXRhKFwidXJsXCIpLFxuICAgICAgICAgICAgdHlwZTogXCJHRVRcIixcbiAgICAgICAgfSxcbiAgICAgICAgY29sdW1uczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGRhdGE6IFwiRFRfUm93SW5kZXhcIixcbiAgICAgICAgICAgICAgICBuYW1lOiBcIkRUX1Jvd0luZGV4XCIsXG4gICAgICAgICAgICAgICAgb3JkZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzZWFyY2hhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB3aWR0aDogXCI1JVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBkYXRhOiBcIm11dGF0aW9uX251bWJlclwiLFxuICAgICAgICAgICAgICAgIG5hbWU6IFwibXV0YXRpb25fbnVtYmVyXCIsXG4gICAgICAgICAgICAgICAgd2lkdGg6IFwiMTIlXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGRhdGE6IFwiY3JlYXRlZF9hdFwiLFxuICAgICAgICAgICAgICAgIG5hbWU6IFwiY3JlYXRlZF9hdFwiLFxuICAgICAgICAgICAgICAgIHdpZHRoOiBcIjEyJVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBkYXRhOiBcImZyb21fZGVhbGVyXCIsXG4gICAgICAgICAgICAgICAgbmFtZTogXCJmcm9tRGVhbGVyLm5hbWVcIixcbiAgICAgICAgICAgICAgICB3aWR0aDogXCIxNSVcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZGF0YTogXCJ0b19kZWFsZXJcIixcbiAgICAgICAgICAgICAgICBuYW1lOiBcInRvRGVhbGVyLm5hbWVcIixcbiAgICAgICAgICAgICAgICB3aWR0aDogXCIxNSVcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZGF0YTogXCJyZXF1ZXN0ZWRfYnlcIixcbiAgICAgICAgICAgICAgICBuYW1lOiBcInJlcXVlc3RlZEJ5Lm5hbWVcIixcbiAgICAgICAgICAgICAgICB3aWR0aDogXCIxMiVcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZGF0YTogXCJ0b3RhbF9pdGVtc1wiLFxuICAgICAgICAgICAgICAgIG5hbWU6IFwidG90YWxfaXRlbXNcIixcbiAgICAgICAgICAgICAgICB3aWR0aDogXCI4JVwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJ0ZXh0LWNlbnRlclwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBkYXRhOiBcInN0YXR1c1wiLFxuICAgICAgICAgICAgICAgIG5hbWU6IFwic3RhdHVzXCIsXG4gICAgICAgICAgICAgICAgd2lkdGg6IFwiMTIlXCIsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcInRleHQtY2VudGVyXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGRhdGE6IFwiYWN0aW9uXCIsXG4gICAgICAgICAgICAgICAgbmFtZTogXCJhY3Rpb25cIixcbiAgICAgICAgICAgICAgICBvcmRlcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHdpZHRoOiBcIjE1JVwiLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJ0ZXh0LWNlbnRlclwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3JkZXI6IFtbMiwgXCJkZXNjXCJdXSwgLy8gT3JkZXIgYnkgY3JlYXRlZF9hdCBkZXNjXG4gICAgICAgIHBhZ2VMZW5ndGg6IDEwLFxuICAgICAgICByZXNwb25zaXZlOiB0cnVlLFxuICAgICAgICBsYW5ndWFnZToge1xuICAgICAgICAgICAgcHJvY2Vzc2luZzogXCJNZW11YXQgZGF0YS4uLlwiLFxuICAgICAgICAgICAgbGVuZ3RoTWVudTogXCJUYW1waWxrYW4gX01FTlVfIGRhdGEgcGVyIGhhbGFtYW5cIixcbiAgICAgICAgICAgIHplcm9SZWNvcmRzOiBcIkRhdGEgdGlkYWsgZGl0ZW11a2FuXCIsXG4gICAgICAgICAgICBpbmZvOiBcIk1lbmFtcGlsa2FuIF9TVEFSVF8gc2FtcGFpIF9FTkRfIGRhcmkgX1RPVEFMXyBkYXRhXCIsXG4gICAgICAgICAgICBpbmZvRW1wdHk6IFwiTWVuYW1waWxrYW4gMCBzYW1wYWkgMCBkYXJpIDAgZGF0YVwiLFxuICAgICAgICAgICAgaW5mb0ZpbHRlcmVkOiBcIihkaWZpbHRlciBkYXJpIF9NQVhfIHRvdGFsIGRhdGEpXCIsXG4gICAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBIYW5kbGUgUmVjZWl2ZSBCdXR0b24gQ2xpY2tcbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1yZWNlaXZlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG11dGF0aW9uSWQgPSAkKHRoaXMpLmRhdGEoXCJpZFwiKTtcbiAgICAgICAgJChcIiNyZWNlaXZlTW9kYWxcIiArIG11dGF0aW9uSWQpLm1vZGFsKFwic2hvd1wiKTtcbiAgICB9KTtcblxuICAgIC8vIEhhbmRsZSBBcHByb3ZlIEJ1dHRvbiBDbGlja1xuICAgICQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIuYnRuLWFwcHJvdmVcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbXV0YXRpb25JZCA9ICQodGhpcykuZGF0YShcImlkXCIpO1xuXG4gICAgICAgIC8vIExvYWQgbXV0YXRpb24gZGV0YWlscyB2aWEgQUpBWFxuICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBcIi93YXJlaG91c2UvbXV0YXRpb25zL1wiICsgbXV0YXRpb25JZCArIFwiL2RldGFpbHNcIixcbiAgICAgICAgICAgIHR5cGU6IFwiR0VUXCIsXG4gICAgICAgICAgICBiZWZvcmVTZW5kOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgJChcIiNtdXRhdGlvbi1kZXRhaWxzXCIgKyBtdXRhdGlvbklkKS5odG1sKFxuICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInRleHQtY2VudGVyXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInNwaW5uZXItYm9yZGVyXCIgcm9sZT1cInN0YXR1c1wiPicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic3Itb25seVwiPkxvYWRpbmcuLi48L3NwYW4+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBcIjwvZGl2PlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiPHA+TWVtdWF0IGRldGFpbCBwcm9kdWsuLi48L3A+XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCI8L2Rpdj5cIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRldGFpbHNIdG1sID0gXCI8aDY+RGV0YWlsIFByb2R1azo8L2g2PlwiO1xuICAgICAgICAgICAgICAgIGRldGFpbHNIdG1sICs9ICc8ZGl2IGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPic7XG4gICAgICAgICAgICAgICAgZGV0YWlsc0h0bWwgKz0gJzx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLXNtXCI+JztcbiAgICAgICAgICAgICAgICBkZXRhaWxzSHRtbCArPSBcIjx0aGVhZD5cIjtcbiAgICAgICAgICAgICAgICBkZXRhaWxzSHRtbCArPSBcIjx0cj5cIjtcbiAgICAgICAgICAgICAgICBkZXRhaWxzSHRtbCArPSBcIjx0aD5Qcm9kdWs8L3RoPlwiO1xuICAgICAgICAgICAgICAgIGRldGFpbHNIdG1sICs9IFwiPHRoPkRpbWludGE8L3RoPlwiO1xuICAgICAgICAgICAgICAgIGRldGFpbHNIdG1sICs9IFwiPHRoPkRpc2V0dWp1aTwvdGg+XCI7XG4gICAgICAgICAgICAgICAgZGV0YWlsc0h0bWwgKz0gXCI8dGg+U3RvY2sgVGVyc2VkaWE8L3RoPlwiO1xuICAgICAgICAgICAgICAgIGRldGFpbHNIdG1sICs9IFwiPC90cj5cIjtcbiAgICAgICAgICAgICAgICBkZXRhaWxzSHRtbCArPSBcIjwvdGhlYWQ+XCI7XG4gICAgICAgICAgICAgICAgZGV0YWlsc0h0bWwgKz0gXCI8dGJvZHk+XCI7XG5cbiAgICAgICAgICAgICAgICByZXNwb25zZS5kZXRhaWxzLmZvckVhY2goZnVuY3Rpb24gKGRldGFpbCwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgZGV0YWlsc0h0bWwgKz0gXCI8dHI+XCI7XG4gICAgICAgICAgICAgICAgICAgIGRldGFpbHNIdG1sICs9IFwiPHRkPlwiICsgZGV0YWlsLnByb2R1Y3QubmFtZSArIFwiPC90ZD5cIjtcbiAgICAgICAgICAgICAgICAgICAgZGV0YWlsc0h0bWwgKz1cbiAgICAgICAgICAgICAgICAgICAgICAgIFwiPHRkPlwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlRmxvYXQoZGV0YWlsLnF1YW50aXR5X3JlcXVlc3RlZCkudG9Mb2NhbGVTdHJpbmcoKSArXG4gICAgICAgICAgICAgICAgICAgICAgICBcIjwvdGQ+XCI7XG4gICAgICAgICAgICAgICAgICAgIGRldGFpbHNIdG1sICs9IFwiPHRkPlwiO1xuICAgICAgICAgICAgICAgICAgICBkZXRhaWxzSHRtbCArPVxuICAgICAgICAgICAgICAgICAgICAgICAgJzxpbnB1dCB0eXBlPVwibnVtYmVyXCIgbmFtZT1cImRldGFpbHNbJyArXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXRhaWwuaWQgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ11bcXVhbnRpdHlfYXBwcm92ZWRdXCIgJztcbiAgICAgICAgICAgICAgICAgICAgZGV0YWlsc0h0bWwgKz0gJ2NsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tY29udHJvbC1zbVwiICc7XG4gICAgICAgICAgICAgICAgICAgIGRldGFpbHNIdG1sICs9ICd2YWx1ZT1cIicgKyBkZXRhaWwucXVhbnRpdHlfcmVxdWVzdGVkICsgJ1wiICc7XG4gICAgICAgICAgICAgICAgICAgIGRldGFpbHNIdG1sICs9XG4gICAgICAgICAgICAgICAgICAgICAgICAnbWluPVwiMFwiIG1heD1cIicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5taW4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV0YWlsLnF1YW50aXR5X3JlcXVlc3RlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXRhaWwuYXZhaWxhYmxlX3N0b2NrXG4gICAgICAgICAgICAgICAgICAgICAgICApICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdcIiAnO1xuICAgICAgICAgICAgICAgICAgICBkZXRhaWxzSHRtbCArPSAnc3RlcD1cIjAuMDFcIiByZXF1aXJlZD4nO1xuICAgICAgICAgICAgICAgICAgICBkZXRhaWxzSHRtbCArPSBcIjwvdGQ+XCI7XG4gICAgICAgICAgICAgICAgICAgIGRldGFpbHNIdG1sICs9XG4gICAgICAgICAgICAgICAgICAgICAgICBcIjx0ZD5cIiArXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZUZsb2F0KGRldGFpbC5hdmFpbGFibGVfc3RvY2spLnRvTG9jYWxlU3RyaW5nKCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCI8L3RkPlwiO1xuICAgICAgICAgICAgICAgICAgICBkZXRhaWxzSHRtbCArPSBcIjwvdHI+XCI7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBkZXRhaWxzSHRtbCArPSBcIjwvdGJvZHk+XCI7XG4gICAgICAgICAgICAgICAgZGV0YWlsc0h0bWwgKz0gXCI8L3RhYmxlPlwiO1xuICAgICAgICAgICAgICAgIGRldGFpbHNIdG1sICs9IFwiPC9kaXY+XCI7XG5cbiAgICAgICAgICAgICAgICAkKFwiI211dGF0aW9uLWRldGFpbHNcIiArIG11dGF0aW9uSWQpLmh0bWwoZGV0YWlsc0h0bWwpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgJChcIiNtdXRhdGlvbi1kZXRhaWxzXCIgKyBtdXRhdGlvbklkKS5odG1sKFxuICAgICAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlclwiPkdhZ2FsIG1lbXVhdCBkZXRhaWwgcHJvZHVrPC9kaXY+J1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICAkKFwiI2FwcHJvdmVNb2RhbFwiICsgbXV0YXRpb25JZCkubW9kYWwoXCJzaG93XCIpO1xuICAgIH0pO1xuXG4gICAgLy8gSGFuZGxlIG90aGVyIGJ1dHRvbiBjbGlja3NcbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1yZWplY3RcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgbXV0YXRpb25JZCA9ICQodGhpcykuZGF0YShcImlkXCIpO1xuICAgICAgICAkKFwiI3JlamVjdE1vZGFsXCIgKyBtdXRhdGlvbklkKS5tb2RhbChcInNob3dcIik7XG4gICAgfSk7XG5cbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1jb21wbGV0ZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtdXRhdGlvbklkID0gJCh0aGlzKS5kYXRhKFwiaWRcIik7XG4gICAgICAgICQoXCIjY29tcGxldGVNb2RhbFwiICsgbXV0YXRpb25JZCkubW9kYWwoXCJzaG93XCIpO1xuICAgIH0pO1xuXG4gICAgLy8gSGFuZGxlIENhbmNlbCBCdXR0b24gQ2xpY2sgd2l0aCBTd2VldEFsZXJ0XG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi5idG4tY2FuY2VsXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG11dGF0aW9uSWQgPSAkKHRoaXMpLmRhdGEoXCJpZFwiKTtcblxuICAgICAgICBpZiAodHlwZW9mIFN3YWwgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIFN3YWwuZmlyZSh7XG4gICAgICAgICAgICAgICAgdGl0bGU6IFwiQmF0YWxrYW4gTXV0YXNpP1wiLFxuICAgICAgICAgICAgICAgIHRleHQ6IFwiQXBha2FoIEFuZGEgeWFraW4gaW5naW4gbWVtYmF0YWxrYW4gbXV0YXNpIGluaT9cIixcbiAgICAgICAgICAgICAgICBpY29uOiBcIndhcm5pbmdcIixcbiAgICAgICAgICAgICAgICBzaG93Q2FuY2VsQnV0dG9uOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNvbmZpcm1CdXR0b25Db2xvcjogXCIjZDMzXCIsXG4gICAgICAgICAgICAgICAgY2FuY2VsQnV0dG9uQ29sb3I6IFwiIzMwODVkNlwiLFxuICAgICAgICAgICAgICAgIGNvbmZpcm1CdXR0b25UZXh0OiBcIllhLCBCYXRhbGthblwiLFxuICAgICAgICAgICAgICAgIGNhbmNlbEJ1dHRvblRleHQ6IFwiQmF0YWxcIixcbiAgICAgICAgICAgIH0pLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaXNDb25maXJtZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FuY2VsTXV0YXRpb24obXV0YXRpb25JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29uZmlybShcIkFwYWthaCBBbmRhIHlha2luIGluZ2luIG1lbWJhdGFsa2FuIG11dGFzaSBpbmk/XCIpKSB7XG4gICAgICAgICAgICAgICAgY2FuY2VsTXV0YXRpb24obXV0YXRpb25JZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIGNhbmNlbE11dGF0aW9uKG11dGF0aW9uSWQpIHtcbiAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgIHVybDogXCIvd2FyZWhvdXNlL211dGF0aW9ucy9cIiArIG11dGF0aW9uSWQgKyBcIi9jYW5jZWxcIixcbiAgICAgICAgICAgIHR5cGU6IFwiUE9TVFwiLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIF90b2tlbjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgU3dhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgICAgICBTd2FsLmZpcmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IFwiQmVyaGFzaWwhXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiBcIk11dGFzaSBiZXJoYXNpbCBkaWJhdGFsa2FuXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29uOiBcInN1Y2Nlc3NcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVyOiAyMDAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2hvd0NvbmZpcm1CdXR0b246IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChcIk11dGFzaSBiZXJoYXNpbCBkaWJhdGFsa2FuXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0YWJsZS5hamF4LnJlbG9hZCgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoeGhyKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVycm9yTXNnID1cbiAgICAgICAgICAgICAgICAgICAgeGhyLnJlc3BvbnNlSlNPTj8ubWVzc2FnZSB8fCBcIkdhZ2FsIG1lbWJhdGFsa2FuIG11dGFzaVwiO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgU3dhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgICAgICBTd2FsLmZpcmUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IFwiRXJyb3IhXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiBlcnJvck1zZyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb246IFwiZXJyb3JcIixcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYWxlcnQoXCJFcnJvcjogXCIgKyBlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGZvcm0gc3VibWlzc2lvbnMgd2l0aCBsb2FkaW5nIHN0YXRlXG4gICAgJChkb2N1bWVudCkub24oXCJzdWJtaXRcIiwgXCIuYXBwcm92ZS1mb3JtXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgLmZpbmQoJ2J1dHRvblt0eXBlPVwic3VibWl0XCJdJylcbiAgICAgICAgICAgIC5wcm9wKFwiZGlzYWJsZWRcIiwgdHJ1ZSlcbiAgICAgICAgICAgIC5odG1sKFwiTWVtcHJvc2VzLi4uXCIpO1xuICAgIH0pO1xuXG4gICAgLy8gQXV0by1jYWxjdWxhdGUgYXBwcm92ZWQgcXVhbnRpdHkgYmFzZWQgb24gYXZhaWxhYmxlIHN0b2NrXG4gICAgJChkb2N1bWVudCkub24oXCJpbnB1dFwiLCAnaW5wdXRbbmFtZSo9XCJxdWFudGl0eV9hcHByb3ZlZFwiXScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1heFZhbHVlID0gcGFyc2VGbG9hdCgkKHRoaXMpLmF0dHIoXCJtYXhcIikpO1xuICAgICAgICB2YXIgY3VycmVudFZhbHVlID0gcGFyc2VGbG9hdCgkKHRoaXMpLnZhbCgpKTtcblxuICAgICAgICBpZiAobWF4VmFsdWUgJiYgY3VycmVudFZhbHVlID4gbWF4VmFsdWUpIHtcbiAgICAgICAgICAgICQodGhpcykudmFsKG1heFZhbHVlKTtcbiAgICAgICAgICAgICQodGhpcykuYWRkQ2xhc3MoXCJpcy1pbnZhbGlkXCIpO1xuICAgICAgICAgICAgaWYgKCEkKHRoaXMpLnNpYmxpbmdzKFwiLmludmFsaWQtZmVlZGJhY2tcIikubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgJCh0aGlzKS5hZnRlcihcbiAgICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCI+SnVtbGFoIG1lbGViaWhpIHN0b2NrIHlhbmcgdGVyc2VkaWE8L2Rpdj4nXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoXCJpcy1pbnZhbGlkXCIpO1xuICAgICAgICAgICAgJCh0aGlzKS5zaWJsaW5ncyhcIi5pbnZhbGlkLWZlZWRiYWNrXCIpLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgfSk7XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUFBLENBQUMsQ0FBQ0MsUUFBRCxDQUFELENBQVlDLEtBQVosQ0FBa0IsWUFBWTtFQUMxQjtFQUNBLElBQUlDLEtBQUssR0FBR0gsQ0FBQyxDQUFDLGtCQUFELENBQUQsQ0FBc0JJLFNBQXRCLENBQWdDO0lBQ3hDQyxVQUFVLEVBQUUsSUFENEI7SUFFeENDLFVBQVUsRUFBRSxJQUY0QjtJQUd4Q0MsSUFBSSxFQUFFO01BQ0ZDLEdBQUcsRUFBRVIsQ0FBQyxDQUFDLGtCQUFELENBQUQsQ0FBc0JTLElBQXRCLENBQTJCLEtBQTNCLENBREg7TUFFRkMsSUFBSSxFQUFFO0lBRkosQ0FIa0M7SUFPeENDLE9BQU8sRUFBRSxDQUNMO01BQ0lGLElBQUksRUFBRSxhQURWO01BRUlHLElBQUksRUFBRSxhQUZWO01BR0lDLFNBQVMsRUFBRSxLQUhmO01BSUlDLFVBQVUsRUFBRSxLQUpoQjtNQUtJQyxLQUFLLEVBQUU7SUFMWCxDQURLLEVBUUw7TUFDSU4sSUFBSSxFQUFFLGlCQURWO01BRUlHLElBQUksRUFBRSxpQkFGVjtNQUdJRyxLQUFLLEVBQUU7SUFIWCxDQVJLLEVBYUw7TUFDSU4sSUFBSSxFQUFFLFlBRFY7TUFFSUcsSUFBSSxFQUFFLFlBRlY7TUFHSUcsS0FBSyxFQUFFO0lBSFgsQ0FiSyxFQWtCTDtNQUNJTixJQUFJLEVBQUUsYUFEVjtNQUVJRyxJQUFJLEVBQUUsaUJBRlY7TUFHSUcsS0FBSyxFQUFFO0lBSFgsQ0FsQkssRUF1Qkw7TUFDSU4sSUFBSSxFQUFFLFdBRFY7TUFFSUcsSUFBSSxFQUFFLGVBRlY7TUFHSUcsS0FBSyxFQUFFO0lBSFgsQ0F2QkssRUE0Qkw7TUFDSU4sSUFBSSxFQUFFLGNBRFY7TUFFSUcsSUFBSSxFQUFFLGtCQUZWO01BR0lHLEtBQUssRUFBRTtJQUhYLENBNUJLLEVBaUNMO01BQ0lOLElBQUksRUFBRSxhQURWO01BRUlH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RDFCLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FDS3dFLElBREwsQ0FDVSx1QkFEVixFQUVLQyxJQUZMLENBRVUsVUFGVixFQUVzQixJQUZ0QixFQUdLM0MsSUFITCxDQUdVLGNBSFY7RUFJSCxDQUxELEVBM08wQixDQWtQMUI7O0VBQ0E5QixDQUFDLENBQUNDLFFBQUQsQ0FBRCxDQUFZeUIsRUFBWixDQUFlLE9BQWYsRUFBd0Isa0NBQXhCLEVBQTRELFlBQVk7SUFDcEUsSUFBSWdELFFBQVEsR0FBR25DLFVBQVUsQ0FBQ3ZDLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUStELElBQVIsQ0FBYSxLQUFiLENBQUQsQ0FBekI7SUFDQSxJQUFJWSxZQUFZLEdBQUdwQyxVQUFVLENBQUN2QyxDQUFDLENBQUMsSUFBRCxDQUFELENBQVE0RSxHQUFSLEVBQUQsQ0FBN0I7O0lBRUEsSUFBSUYsUUFBUSxJQUFJQyxZQUFZLEdBQUdELFFBQS9CLEVBQXlDO01BQ3JDMUUsQ0FBQyxDQUFDLElBQUQsQ0FBRCxDQUFRNEUsR0FBUixDQUFZRixRQUFaO01BQ0ExRSxDQUFDLENBQUMsSUFBRCxDQUFELENBQVE2RSxRQUFSLENBQWlCLFlBQWpCOztNQUNBLElBQUksQ0FBQzdFLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUThFLFFBQVIsQ0FBaUIsbUJBQWpCLEVBQXNDQyxNQUEzQyxFQUFtRDtRQUMvQy9FLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUWdGLEtBQVIsQ0FDSSx5RUFESjtNQUdIO0lBQ0osQ0FSRCxNQVFPO01BQ0hoRixDQUFDLENBQUMsSUFBRCxDQUFELENBQVFpRixXQUFSLENBQW9CLFlBQXBCO01BQ0FqRixDQUFDLENBQUMsSUFBRCxDQUFELENBQVE4RSxRQUFSLENBQWlCLG1CQUFqQixFQUFzQ0ksTUFBdEM7SUFDSDtFQUNKLENBaEJEO0FBaUJILENBcFFEIiwiZmlsZSI6Ii4vcmVzb3VyY2VzL2pzL3dhcmVob3VzZV9tYW5hZ2VtZW50L211dGF0aW9ucy9pbmRleC5qcyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/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/mutations/index.js"](); +/******/ +/******/ })() +; \ No newline at end of file diff --git a/public/js/warehouse_management/products/index.js b/public/js/warehouse_management/products/index.js index aa056c4..c3dbefa 100755 --- 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 order: [[0, \"desc\"]],\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvcHJvZHVjdHMvaW5kZXguanMiLCJuYW1lcyI6WyIkIiwiYWpheFNldHVwIiwiaGVhZGVycyIsImF0dHIiLCJ0YWJsZUNvbnRhaW5lciIsInVybCIsImRhdGEiLCJ0YWJsZSIsIkRhdGFUYWJsZSIsInByb2Nlc3NpbmciLCJzZXJ2ZXJTaWRlIiwiYWpheCIsIm9yZGVyIiwiY29sdW1ucyIsIm5hbWUiLCJvcmRlcmFibGUiLCJzZWFyY2hhYmxlIiwiZG9jdW1lbnQiLCJvbiIsIlN3YWwiLCJmaXJlIiwidGl0bGUiLCJ0ZXh0Iiwic2hvd0NhbmNlbEJ1dHRvbiIsImNvbmZpcm1CdXR0b25Db2xvciIsImNhbmNlbEJ1dHRvbkNvbG9yIiwiY29uZmlybUJ1dHRvblRleHQiLCJ0aGVuIiwicmVzdWx0IiwidmFsdWUiLCJtZXRob2QiLCJfbWV0aG9kIiwiX3Rva2VuIiwic3VjY2VzcyIsImFsZXJ0IiwicmVsb2FkIiwiZXJyb3IiLCJ4aHIiLCJjb25zb2xlIiwicmVzcG9uc2VUZXh0IiwiYnV0dG9uIiwicmVzcG9uc2UiLCJtZXNzYWdlIiwicHJvZHVjdElkIiwicHJvZHVjdE5hbWUiLCJhamF4VXJsIiwiZGVzdHJveSIsInByb2R1Y3RfaWQiLCJpbml0Q29tcGxldGUiLCJtb2RhbCJdLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vcmVzb3VyY2VzL2pzL3dhcmVob3VzZV9tYW5hZ2VtZW50L3Byb2R1Y3RzL2luZGV4LmpzP2ZjZDYiXSwic291cmNlc0NvbnRlbnQiOlsiJC5hamF4U2V0dXAoe1xuICAgIGhlYWRlcnM6IHtcbiAgICAgICAgXCJYLUNTUkYtVE9LRU5cIjogJCgnbWV0YVtuYW1lPVwiY3NyZi10b2tlblwiXScpLmF0dHIoXCJjb250ZW50XCIpLFxuICAgIH0sXG59KTtcbmxldCB0YWJsZUNvbnRhaW5lciA9ICQoXCIjcHJvZHVjdHMtdGFibGVcIik7XG5sZXQgdXJsID0gdGFibGVDb250YWluZXIuZGF0YShcInVybFwiKTtcbmxldCB0YWJsZSA9ICQoXCIjcHJvZHVjdHMtdGFibGVcIikuRGF0YVRhYmxlKHtcbiAgICBwcm9jZXNzaW5nOiB0cnVlLFxuICAgIHNlcnZlclNpZGU6IHRydWUsXG4gICAgYWpheDogdXJsLFxuICAgIG9yZGVyOiBbWzAsIFwiZGVzY1wiXV0sXG4gICAgY29sdW1uczogW1xuICAgICAgICB7IGRhdGE6IFwiY29kZVwiLCBuYW1lOiBcImNvZGVcIiB9LFxuICAgICAgICB7IGRhdGE6IFwibmFtZVwiLCBuYW1lOiBcIm5hbWVcIiB9LFxuICAgICAgICB7IGRhdGE6IFwiY2F0ZWdvcnlfbmFtZVwiLCBuYW1lOiBcImNhdGVnb3J5Lm5hbWVcIiB9LFxuICAgICAgICB7IGRhdGE6IFwidW5pdFwiLCBuYW1lOiBcInVuaXRcIiB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBkYXRhOiBcInRvdGFsX3N0b2NrXCIsXG4gICAgICAgICAgICBuYW1lOiBcInRvdGFsX3N0b2NrXCIsXG4gICAgICAgICAgICBvcmRlcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgc2VhcmNoYWJsZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHsgZGF0YTogXCJhY3Rpb25cIiwgbmFtZTogXCJhY3Rpb25cIiwgb3JkZXJhYmxlOiBmYWxzZSwgc2VhcmNoYWJsZTogZmFsc2UgfSxcbiAgICBdLFxufSk7XG5cbiQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIuYnRuLWRlc3Ryb3ktcHJvZHVjdFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgU3dhbC5maXJlKHtcbiAgICAgICAgdGl0bGU6IFwiSGFwdXMgcHJvZHVrP1wiLFxuICAgICAgICB0ZXh0OiBcIkFuZGEgdGlkYWsgYWthbiBiaXNhIG1lbmdlbWJhbGlrYW5ueWEhXCIsXG4gICAgICAgIHNob3dDYW5jZWxCdXR0b246IHRydWUsXG4gICAgICAgIGNvbmZpcm1CdXR0b25Db2xvcjogXCIjZDMzXCIsXG4gICAgICAgIGNhbmNlbEJ1dHRvbkNvbG9yOiBcIiNkZWRlZGVcIixcbiAgICAgICAgY29uZmlybUJ1dHRvblRleHQ6IFwiSGFwdXNcIixcbiAgICB9KS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdC52YWx1ZSkge1xuICAgICAgICAgICAgY29uc3QgdXJsID0gJCh0aGlzKS5kYXRhKFwiYWN0aW9uXCIpO1xuICAgICAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgICAgICB1cmw6IHVybCxcbiAgICAgICAgICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgX21ldGhvZDogXCJERUxFVEVcIixcbiAgICAgICAgICAgICAgICAgICAgX3Rva2VuOiAkKCdtZXRhW25hbWU9XCJjc3JmLXRva2VuXCJdJykuYXR0cihcImNvbnRlbnRcIiksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KFwiUHJvZHVrIGJlcmhhc2lsIGRpaGFwdXMuXCIpO1xuICAgICAgICAgICAgICAgICAgICAkKFwiI3Byb2R1Y3RzLXRhYmxlXCIpLkRhdGFUYWJsZSgpLmFqYXgucmVsb2FkKCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKHhocikge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChcIkdhZ2FsIG1lbmdoYXB1cyBwcm9kdWsuXCIpO1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHhoci5yZXNwb25zZVRleHQpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xufSk7XG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi10b2dnbGUtYWN0aXZlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgYnV0dG9uID0gJCh0aGlzKTtcbiAgICBsZXQgdXJsID0gYnV0dG9uLmRhdGEoXCJ1cmxcIik7XG5cbiAgICBTd2FsLmZpcmUoe1xuICAgICAgICB0aXRsZTogXCJTdGF0dXMgcHJvZHVrP1wiLFxuICAgICAgICB0ZXh0OiBcIkFuZGEgeWFraW4gaW5naW4gbWVuZ2dhbnRpIHN0YXR1cyBwcm9kdWshXCIsXG4gICAgICAgIHNob3dDYW5jZWxCdXR0b246IHRydWUsXG4gICAgICAgIGNvbmZpcm1CdXR0b25Db2xvcjogXCIjZDMzXCIsXG4gICAgICAgIGNhbmNlbEJ1dHRvbkNvbG9yOiBcIiNkZWRlZGVcIixcbiAgICAgICAgY29uZmlybUJ1dHRvblRleHQ6IFwiWWFcIixcbiAgICB9KS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdC52YWx1ZSkge1xuICAgICAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgICAgICB1cmw6IHVybCxcbiAgICAgICAgICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgX3Rva2VuOiAkKCdtZXRhW25hbWU9XCJjc3JmLXRva2VuXCJdJykuYXR0cihcImNvbnRlbnRcIiksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICQoXCIjcHJvZHVjdHMtdGFibGVcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuRGF0YVRhYmxlKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWpheC5yZWxvYWQobnVsbCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYWxlcnQocmVzcG9uc2UubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KFwiR2FnYWwgbWVuZ3ViYWggc3RhdHVzIHByb2R1ay5cIik7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG59KTtcbiQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIuYnRuLXByb2R1Y3Qtc3RvY2stZGVhbGVyc1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgcHJvZHVjdElkID0gJCh0aGlzKS5kYXRhKFwiaWRcIik7XG4gICAgY29uc3QgcHJvZHVjdE5hbWUgPSAkKHRoaXMpLmRhdGEoXCJuYW1lXCIpO1xuICAgIGNvbnN0IGFqYXhVcmwgPSAkKHRoaXMpLmRhdGEoXCJ1cmxcIik7XG5cbiAgICAvLyBTZXQgcHJvZHVjdCBuYW1lIGluIG1vZGFsIHRpdGxlXG4gICAgJChcIiNwcm9kdWN0LW5hbWUtdGl0bGVcIikudGV4dChwcm9kdWN0TmFtZSk7XG5cbiAgICAvLyBJbml0aWFsaXplIG9yIHJlbG9hZCBEYXRhVGFibGUgaW5zaWRlIG1vZGFsXG4gICAgJChcIiNkZWFsZXItc3RvY2stdGFibGVcIikuRGF0YVRhYmxlKHtcbiAgICAgICAgZGVzdHJveTogdHJ1ZSwgLy8gcmVpbml0IGlmIGV4aXN0c1xuICAgICAgICBwcm9jZXNzaW5nOiB0cnVlLFxuICAgICAgICBzZXJ2ZXJTaWRlOiB0cnVlLFxuICAgICAgICBhamF4OiB7XG4gICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgcHJvZHVjdF9pZDogcHJvZHVjdElkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgY29sdW1uczogW1xuICAgICAgICAgICAgeyBkYXRhOiBcImRlYWxlcl9uYW1lXCIsIG5hbWU6IFwiZGVhbGVyX25hbWVcIiB9LFxuICAgICAgICAgICAgeyBkYXRhOiBcInF1YW50aXR5XCIsIG5hbWU6IFwicXVhbnRpdHlcIiB9LFxuICAgICAgICBdLFxuICAgICAgICBpbml0Q29tcGxldGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICQoXCIjZGVhbGVyU3RvY2tNb2RhbFwiKS5tb2RhbChcInNob3dcIik7XG4gICAgICAgIH0sXG4gICAgfSk7XG59KTtcbiQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIjZGVhbGVyU3RvY2tNb2RhbCAuY2xvc2VcIiwgZnVuY3Rpb24gKCkge1xuICAgICQoXCIjZGVhbGVyU3RvY2tNb2RhbFwiKS5tb2RhbChcImhpZGVcIik7XG59KTtcbiJdLCJtYXBwaW5ncyI6IkFBQUFBLENBQUMsQ0FBQ0MsU0FBRixDQUFZO0VBQ1JDLE9BQU8sRUFBRTtJQUNMLGdCQUFnQkYsQ0FBQyxDQUFDLHlCQUFELENBQUQsQ0FBNkJHLElBQTdCLENBQWtDLFNBQWxDO0VBRFg7QUFERCxDQUFaO0FBS0EsSUFBSUMsY0FBYyxHQUFHSixDQUFDLENBQUMsaUJBQUQsQ0FBdEI7QUFDQSxJQUFJSyxHQUFHLEdBQUdELGNBQWMsQ0FBQ0UsSUFBZixDQUFvQixLQUFwQixDQUFWO0FBQ0EsSUFBSUMsS0FBSyxHQUFHUCxDQUFDLENBQUMsaUJBQUQsQ0FBRCxDQUFxQlEsU0FBckIsQ0FBK0I7RUFDdkNDLFVBQVUsRUFBRSxJQUQyQjtFQUV2Q0MsVUFBVSxFQUFFLElBRjJCO0VBR3ZDQyxJQUFJLEVBQUVOLEdBSGlDO0VBSXZDTyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUQsRUFBSSxNQUFKLENBQUQsQ0FKZ0M7RUFLdkNDLE9BQU8sRUFBRSxDQUNMO0lBQUVQLElBQUksRUFBRSxNQUFSO0lBQWdCUSxJQUFJLEVBQUU7RUFBdEIsQ0FESyxFQUVMO0lBQUVSLElBQUksRUFBRSxNQUFSO0lBQWdCUSxJQUFJLEVBQUU7RUFBdEIsQ0FGSyxFQUdMO0lBQUVSLElBQUksRUFBRSxlQUFSO0lBQXlCUSxJQUFJLEVBQUU7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\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 order: [[0, \"desc\"]],\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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyIkIiwiYWpheFNldHVwIiwiaGVhZGVycyIsImF0dHIiLCJ0YWJsZUNvbnRhaW5lciIsInVybCIsImRhdGEiLCJ0YWJsZSIsIkRhdGFUYWJsZSIsInByb2Nlc3NpbmciLCJzZXJ2ZXJTaWRlIiwiYWpheCIsIm9yZGVyIiwiY29sdW1ucyIsIm5hbWUiLCJvcmRlcmFibGUiLCJzZWFyY2hhYmxlIiwiZG9jdW1lbnQiLCJvbiIsIlN3YWwiLCJmaXJlIiwidGl0bGUiLCJ0ZXh0Iiwic2hvd0NhbmNlbEJ1dHRvbiIsImNvbmZpcm1CdXR0b25Db2xvciIsImNhbmNlbEJ1dHRvbkNvbG9yIiwiY29uZmlybUJ1dHRvblRleHQiLCJ0aGVuIiwicmVzdWx0IiwidmFsdWUiLCJtZXRob2QiLCJfbWV0aG9kIiwiX3Rva2VuIiwic3VjY2VzcyIsImFsZXJ0IiwicmVsb2FkIiwiZXJyb3IiLCJ4aHIiLCJjb25zb2xlIiwicmVzcG9uc2VUZXh0IiwiYnV0dG9uIiwicmVzcG9uc2UiLCJtZXNzYWdlIiwicHJvZHVjdElkIiwicHJvZHVjdE5hbWUiLCJhamF4VXJsIiwiZGVzdHJveSIsInByb2R1Y3RfaWQiLCJpbml0Q29tcGxldGUiLCJtb2RhbCJdLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvcHJvZHVjdHMvaW5kZXguanM/ZmNkNiJdLCJzb3VyY2VzQ29udGVudCI6WyIkLmFqYXhTZXR1cCh7XG4gICAgaGVhZGVyczoge1xuICAgICAgICBcIlgtQ1NSRi1UT0tFTlwiOiAkKCdtZXRhW25hbWU9XCJjc3JmLXRva2VuXCJdJykuYXR0cihcImNvbnRlbnRcIiksXG4gICAgfSxcbn0pO1xubGV0IHRhYmxlQ29udGFpbmVyID0gJChcIiNwcm9kdWN0cy10YWJsZVwiKTtcbmxldCB1cmwgPSB0YWJsZUNvbnRhaW5lci5kYXRhKFwidXJsXCIpO1xubGV0IHRhYmxlID0gJChcIiNwcm9kdWN0cy10YWJsZVwiKS5EYXRhVGFibGUoe1xuICAgIHByb2Nlc3Npbmc6IHRydWUsXG4gICAgc2VydmVyU2lkZTogdHJ1ZSxcbiAgICBhamF4OiB1cmwsXG4gICAgb3JkZXI6IFtbMCwgXCJkZXNjXCJdXSxcbiAgICBjb2x1bW5zOiBbXG4gICAgICAgIHsgZGF0YTogXCJjb2RlXCIsIG5hbWU6IFwiY29kZVwiIH0sXG4gICAgICAgIHsgZGF0YTogXCJuYW1lXCIsIG5hbWU6IFwibmFtZVwiIH0sXG4gICAgICAgIHsgZGF0YTogXCJjYXRlZ29yeV9uYW1lXCIsIG5hbWU6IFwiY2F0ZWdvcnkubmFtZVwiIH0sXG4gICAgICAgIHsgZGF0YTogXCJ1bml0XCIsIG5hbWU6IFwidW5pdFwiIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIGRhdGE6IFwidG90YWxfc3RvY2tcIixcbiAgICAgICAgICAgIG5hbWU6IFwidG90YWxfc3RvY2tcIixcbiAgICAgICAgICAgIG9yZGVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBzZWFyY2hhYmxlOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgeyBkYXRhOiBcImFjdGlvblwiLCBuYW1lOiBcImFjdGlvblwiLCBvcmRlcmFibGU6IGZhbHNlLCBzZWFyY2hhYmxlOiBmYWxzZSB9LFxuICAgIF0sXG59KTtcblxuJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi5idG4tZGVzdHJveS1wcm9kdWN0XCIsIGZ1bmN0aW9uICgpIHtcbiAgICBTd2FsLmZpcmUoe1xuICAgICAgICB0aXRsZTogXCJIYXB1cyBwcm9kdWs/XCIsXG4gICAgICAgIHRleHQ6IFwiQW5kYSB0aWRhayBha2FuIGJpc2EgbWVuZ2VtYmFsaWthbm55YSFcIixcbiAgICAgICAgc2hvd0NhbmNlbEJ1dHRvbjogdHJ1ZSxcbiAgICAgICAgY29uZmlybUJ1dHRvbkNvbG9yOiBcIiNkMzNcIixcbiAgICAgICAgY2FuY2VsQnV0dG9uQ29sb3I6IFwiI2RlZGVkZVwiLFxuICAgICAgICBjb25maXJtQnV0dG9uVGV4dDogXCJIYXB1c1wiLFxuICAgIH0pLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICBpZiAocmVzdWx0LnZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSAkKHRoaXMpLmRhdGEoXCJhY3Rpb25cIik7XG4gICAgICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogdXJsLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBfbWV0aG9kOiBcIkRFTEVURVwiLFxuICAgICAgICAgICAgICAgICAgICBfdG9rZW46ICQoJ21ldGFbbmFtZT1cImNzcmYtdG9rZW5cIl0nKS5hdHRyKFwiY29udGVudFwiKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgYWxlcnQoXCJQcm9kdWsgYmVyaGFzaWwgZGloYXB1cy5cIik7XG4gICAgICAgICAgICAgICAgICAgICQoXCIjcHJvZHVjdHMtdGFibGVcIikuRGF0YVRhYmxlKCkuYWpheC5yZWxvYWQoKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoeGhyKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KFwiR2FnYWwgbWVuZ2hhcHVzIHByb2R1ay5cIik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoeGhyLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSk7XG59KTtcbiQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIuYnRuLXRvZ2dsZS1hY3RpdmVcIiwgZnVuY3Rpb24gKCkge1xuICAgIGxldCBidXR0b24gPSAkKHRoaXMpO1xuICAgIGxldCB1cmwgPSBidXR0b24uZGF0YShcInVybFwiKTtcblxuICAgIFN3YWwuZmlyZSh7XG4gICAgICAgIHRpdGxlOiBcIlN0YXR1cyBwcm9kdWs/XCIsXG4gICAgICAgIHRleHQ6IFwiQW5kYSB5YWtpbiBpbmdpbiBtZW5nZ2FudGkgc3RhdHVzIHByb2R1ayFcIixcbiAgICAgICAgc2hvd0NhbmNlbEJ1dHRvbjogdHJ1ZSxcbiAgICAgICAgY29uZmlybUJ1dHRvbkNvbG9yOiBcIiNkMzNcIixcbiAgICAgICAgY2FuY2VsQnV0dG9uQ29sb3I6IFwiI2RlZGVkZVwiLFxuICAgICAgICBjb25maXJtQnV0dG9uVGV4dDogXCJZYVwiLFxuICAgIH0pLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICBpZiAocmVzdWx0LnZhbHVlKSB7XG4gICAgICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogdXJsLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBfdG9rZW46ICQoJ21ldGFbbmFtZT1cImNzcmYtdG9rZW5cIl0nKS5hdHRyKFwiY29udGVudFwiKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2Uuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgJChcIiNwcm9kdWN0cy10YWJsZVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5EYXRhVGFibGUoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hamF4LnJlbG9hZChudWxsLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbGVydChyZXNwb25zZS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgYWxlcnQoXCJHYWdhbCBtZW5ndWJhaCBzdGF0dXMgcHJvZHVrLlwiKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn0pO1xuJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi5idG4tcHJvZHVjdC1zdG9jay1kZWFsZXJzXCIsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBwcm9kdWN0SWQgPSAkKHRoaXMpLmRhdGEoXCJpZFwiKTtcbiAgICBjb25zdCBwcm9kdWN0TmFtZSA9ICQodGhpcykuZGF0YShcIm5hbWVcIik7XG4gICAgY29uc3QgYWpheFVybCA9ICQodGhpcykuZGF0YShcInVybFwiKTtcblxuICAgIC8vIFNldCBwcm9kdWN0IG5hbWUgaW4gbW9kYWwgdGl0bGVcbiAgICAkKFwiI3Byb2R1Y3QtbmFtZS10aXRsZVwiKS50ZXh0KHByb2R1Y3ROYW1lKTtcblxuICAgIC8vIEluaXRpYWxpemUgb3IgcmVsb2FkIERhdGFUYWJsZSBpbnNpZGUgbW9kYWxcbiAgICAkKFwiI2RlYWxlci1zdG9jay10YWJsZVwiKS5EYXRhVGFibGUoe1xuICAgICAgICBkZXN0cm95OiB0cnVlLCAvLyByZWluaXQgaWYgZXhpc3RzXG4gICAgICAgIHByb2Nlc3Npbmc6IHRydWUsXG4gICAgICAgIHNlcnZlclNpZGU6IHRydWUsXG4gICAgICAgIGFqYXg6IHtcbiAgICAgICAgICAgIHVybDogYWpheFVybCxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBwcm9kdWN0X2lkOiBwcm9kdWN0SWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBjb2x1bW5zOiBbXG4gICAgICAgICAgICB7IGRhdGE6IFwiZGVhbGVyX25hbWVcIiwgbmFtZTogXCJkZWFsZXJfbmFtZVwiIH0sXG4gICAgICAgICAgICB7IGRhdGE6IFwicXVhbnRpdHlcIiwgbmFtZTogXCJxdWFudGl0eVwiIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGluaXRDb21wbGV0ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgJChcIiNkZWFsZXJTdG9ja01vZGFsXCIpLm1vZGFsKFwic2hvd1wiKTtcbiAgICAgICAgfSxcbiAgICB9KTtcbn0pO1xuJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIiNkZWFsZXJTdG9ja01vZGFsIC5jbG9zZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgJChcIiNkZWFsZXJTdG9ja01vZGFsXCIpLm1vZGFsKFwiaGlkZVwiKTtcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQUEsQ0FBQyxDQUFDQyxTQUFGLENBQVk7RUFDUkMsT0FBTyxFQUFFO0lBQ0wsZ0JBQWdCRixDQUFDLENBQUMseUJBQUQsQ0FBRCxDQUE2QkcsSUFBN0IsQ0FBa0MsU0FBbEM7RUFEWDtBQURELENBQVo7QUFLQSxJQUFJQyxjQUFjLEdBQUdKLENBQUMsQ0FBQyxpQkFBRCxDQUF0QjtBQUNBLElBQUlLLEdBQUcsR0FBR0QsY0FBYyxDQUFDRSxJQUFmLENBQW9CLEtBQXBCLENBQVY7QUFDQSxJQUFJQyxLQUFLLEdBQUdQLENBQUMsQ0FBQyxpQkFBRCxDQUFELENBQXFCUSxTQUFyQixDQUErQjtFQUN2Q0MsVUFBVSxFQUFFLElBRDJCO0VBRXZDQyxVQUFVLEVBQUUsSUFGMkI7RUFHdkNDLElBQUksRUFBRU4sR0FIaUM7RUFJdkNPLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBRCxFQUFJLE1BQUosQ0FBRCxDQUpnQztFQUt2Q0MsT0FBTyxFQUFFLENBQ0w7SUFBRVAsSUFBSSxFQUFFLE1BQVI7SUFBZ0JRLElBQUksRUFBRTtFQUF0QixDQURLLEVBRUw7SUFBRVIsSUFBSSxFQUFFLE1BQVI7SUFBZ0JRLElBQUksRUFBRTtFQUF0QixDQUZLLEVBR0w7SUFBRVIsSUFBSSxFQUFFLGVBQVI7SUFBeUJRLElBQUksRUFBRTtFQUEvQixDQUhLLEVBSUw7SUFBRVIsSUFBSSxFQUFFLE1BQVI7SUFBZ0JRLElBQUksRUFBRTtFQUF0QixDQUpLLEVBS0w7SUFDSVIsSUFB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QyxPQUFWLENBQUw7VUFDSDtRQUNKLENBYkU7UUFjSE4sS0FBSyxFQUFFLGlCQUFZO1VBQ2ZGLEtBQUssQ0FBQywrQkFBRCxDQUFMO1FBQ0g7TUFoQkUsQ0FBUDtJQWtCSDtFQUNKLENBNUJEO0FBNkJILENBakNEO0FBa0NBbEMsQ0FBQyxDQUFDaUIsUUFBRCxDQUFELENBQVlDLEVBQVosQ0FBZSxPQUFmLEVBQXdCLDRCQUF4QixFQUFzRCxZQUFZO0VBQzlELElBQU15QixTQUFTLEdBQUczQyxDQUFDLENBQUMsSUFBRCxDQUFELENBQVFNLElBQVIsQ0FBYSxJQUFiLENBQWxCO0VBQ0EsSUFBTXNDLFdBQVcsR0FBRzVDLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUU0sSUFBUixDQUFhLE1BQWIsQ0FBcEI7RUFDQSxJQUFNdUMsT0FBTyxHQUFHN0MsQ0FBQyxDQUFDLElBQUQsQ0FBRCxDQUFRTSxJQUFSLENBQWEsS0FBYixDQUFoQixDQUg4RCxDQUs5RDs7RUFDQU4sQ0FBQyxDQUFDLHFCQUFELENBQUQsQ0FBeUJzQixJQUF6QixDQUE4QnNCLFdBQTlCLEVBTjhELENBUTlEOztFQUNBNUMsQ0FBQyxDQUFDLHFCQUFELENBQUQsQ0FBeUJRLFNBQXpCLENBQW1DO0lBQy9Cc0MsT0FBTyxFQUFFLElBRHNCO0lBQ2hCO0lBQ2ZyQyxVQUFVLEVBQUUsSUFGbUI7SUFHL0JDLFVBQVUsRUFBRSxJQUhtQjtJQUkvQkMsSUFBSSxFQUFFO01BQ0ZOLEdBQUcsRUFBRXdDLE9BREg7TUFFRnZDLElBQUksRUFBRTtRQUNGeUMsVUFBVSxFQUFFSjtNQURWO0lBRkosQ0FKeUI7SUFVL0I5QixPQUFPLEVBQUUsQ0FDTDtNQUFFUCxJQUFJLEVBQUUsYUFBUjtNQUF1QlEsSUFBSSxFQUFFO0lBQTdCLENBREssRUFFTDtNQUFFUixJQUFJLEVBQUUsVUFBUjtNQUFvQlEsSUFBSSxFQUFFO0lBQTFCLENBRkssQ0FWc0I7SUFjL0JrQyxZQUFZLEVBQUUsd0JBQVk7TUFDdEJoRCxDQUFDLENBQUMsbUJBQUQsQ0FBRCxDQUF1QmlELEtBQXZCLENBQTZCLE1BQTdCO0lBQ0g7RUFoQjhCLENBQW5DO0FBa0JILENBM0JEO0FBNEJBakQsQ0FBQyxDQUFDaUIsUUFBRCxDQUFELENBQVlDLEVBQVosQ0FBZSxPQUFmLEVBQXdCLDBCQUF4QixFQUFvRCxZQUFZO0VBQzVEbEIsQ0FBQyxDQUFDLG1CQUFELENBQUQsQ0FBdUJpRCxLQUF2QixDQUE2QixNQUE3QjtBQUNILENBRkQiLCJmaWxlIjoiLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvcHJvZHVjdHMvaW5kZXguanMiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/products/index.js\n"); /***/ }) diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 7f75923..98eca69 100755 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -5,5 +5,7 @@ "/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", + "/js/warehouse_management/mutations/index.js": "/js/warehouse_management/mutations/index.js", + "/js/warehouse_management/mutations/create.js": "/js/warehouse_management/mutations/create.js", "/css/app.css": "/css/app.css" } diff --git a/resources/js/warehouse_management/mutations/create.js b/resources/js/warehouse_management/mutations/create.js new file mode 100644 index 0000000..ef319ec --- /dev/null +++ b/resources/js/warehouse_management/mutations/create.js @@ -0,0 +1,262 @@ +$(document).ready(function () { + let productIndex = 1; + + // Initialize Select2 + $(".select2").select2({ + placeholder: "Pilih...", + allowClear: true, + }); + + // Prevent same dealer selection + $("#from_dealer_id, #to_dealer_id").on("change", function () { + const fromDealerId = $("#from_dealer_id").val(); + const toDealerId = $("#to_dealer_id").val(); + + if (fromDealerId && toDealerId && fromDealerId === toDealerId) { + $(this).val("").trigger("change"); + alert("Dealer asal dan tujuan tidak boleh sama!"); + } + + // Update available stock when dealer changes + updateAllAvailableStock(); + }); + + // Add new product row + $("#add-product").on("click", function () { + const newRow = createProductRow(productIndex); + $("#products-tbody").append(newRow); + + // Initialize Select2 for new row + const newSelect = $( + `#products-tbody tr[data-index="${productIndex}"] .product-select` + ); + newSelect.select2({ + placeholder: "Pilih Produk...", + allowClear: true, + }); + + productIndex++; + updateRemoveButtons(); + }); + + // Remove product row + $(document).on("click", ".remove-product", function () { + $(this).closest("tr").remove(); + updateRemoveButtons(); + reindexRows(); + }); + + // Handle product selection change + $(document).on("change", ".product-select", function () { + const row = $(this).closest("tr"); + const productId = $(this).val(); + const fromDealerId = $("#from_dealer_id").val(); + + if (productId && fromDealerId) { + getAvailableStock(productId, fromDealerId, row); + } else { + row.find(".available-stock").text("-"); + row.find(".quantity-input").attr("max", ""); + } + }); + + // Validate quantity input + $(document).on("input", ".quantity-input", function () { + const maxValue = parseFloat($(this).attr("max")); + const currentValue = parseFloat($(this).val()); + + if (maxValue && currentValue > maxValue) { + $(this).val(maxValue); + $(this).addClass("is-invalid"); + + if (!$(this).siblings(".invalid-feedback").length) { + $(this).after( + 'Quantity melebihi stock yang tersedia' + ); + } + } else { + $(this).removeClass("is-invalid"); + $(this).siblings(".invalid-feedback").remove(); + } + }); + + // Form submission + $("#mutation-form").on("submit", function (e) { + e.preventDefault(); + + if (!validateForm()) { + return false; + } + + const submitBtn = $("#submit-btn"); + const originalText = submitBtn.html(); + + submitBtn + .prop("disabled", true) + .html(' Menyimpan...'); + + // Submit form + this.submit(); + }); + + function createProductRow(index) { + // Get product options from the existing select + const existingSelect = $(".product-select").first(); + const productOptions = existingSelect.html(); + + return ` + + + + ${productOptions} + + + + - + + + + + + + + + + + + + + `; + } + + function updateRemoveButtons() { + const rows = $(".product-row"); + $(".remove-product").prop("disabled", rows.length <= 1); + } + + function reindexRows() { + $(".product-row").each(function (index) { + $(this).attr("data-index", index); + $(this) + .find('select[name*="product_id"]') + .attr("name", `products[${index}][product_id]`); + $(this) + .find('input[name*="quantity_requested"]') + .attr("name", `products[${index}][quantity_requested]`); + $(this) + .find('input[name*="notes"]') + .attr("name", `products[${index}][notes]`); + }); + productIndex = $(".product-row").length; + } + + function getAvailableStock(productId, dealerId, row) { + $.ajax({ + url: "/warehouse/mutations/get-product-stock", + method: "GET", + data: { + product_id: productId, + dealer_id: dealerId, + }, + beforeSend: function () { + row.find(".available-stock").html( + '' + ); + }, + success: function (response) { + const stock = parseFloat(response.current_stock); + row.find(".available-stock").text(stock.toLocaleString()); + row.find(".quantity-input").attr("max", stock); + + // Set max value message + if (stock <= 0) { + row.find(".available-stock") + .addClass("text-danger") + .removeClass("text-muted"); + row.find(".quantity-input").attr("readonly", true).val(""); + } else { + row.find(".available-stock") + .removeClass("text-danger") + .addClass("text-muted"); + row.find(".quantity-input").attr("readonly", false); + } + }, + error: function () { + row.find(".available-stock") + .text("Error") + .addClass("text-danger"); + }, + }); + } + + function updateAllAvailableStock() { + const fromDealerId = $("#from_dealer_id").val(); + + $(".product-row").each(function () { + const row = $(this); + const productId = row.find(".product-select").val(); + + if (productId && fromDealerId) { + getAvailableStock(productId, fromDealerId, row); + } else { + row.find(".available-stock").text("-"); + row.find(".quantity-input").attr("max", ""); + } + }); + } + + function validateForm() { + let isValid = true; + const fromDealerId = $("#from_dealer_id").val(); + const toDealerId = $("#to_dealer_id").val(); + + // Check dealers + if (!fromDealerId) { + alert("Pilih dealer asal"); + return false; + } + + if (!toDealerId) { + alert("Pilih dealer tujuan"); + return false; + } + + if (fromDealerId === toDealerId) { + alert("Dealer asal dan tujuan tidak boleh sama"); + return false; + } + + // Check products + const productRows = $(".product-row"); + if (productRows.length === 0) { + alert("Tambahkan minimal satu produk"); + return false; + } + + let hasValidProduct = false; + productRows.each(function () { + const productId = $(this).find(".product-select").val(); + const quantity = $(this).find(".quantity-input").val(); + + if (productId && quantity && parseFloat(quantity) > 0) { + hasValidProduct = true; + } + }); + + if (!hasValidProduct) { + alert("Pilih minimal satu produk dengan quantity yang valid"); + return false; + } + + return isValid; + } +}); diff --git a/resources/js/warehouse_management/mutations/index.js b/resources/js/warehouse_management/mutations/index.js new file mode 100644 index 0000000..f47f3c5 --- /dev/null +++ b/resources/js/warehouse_management/mutations/index.js @@ -0,0 +1,261 @@ +$(document).ready(function () { + // Initialize DataTable + var table = $("#mutations-table").DataTable({ + processing: true, + serverSide: true, + ajax: { + url: $("#mutations-table").data("url"), + type: "GET", + }, + columns: [ + { + data: "DT_RowIndex", + name: "DT_RowIndex", + orderable: false, + searchable: false, + width: "5%", + }, + { + data: "mutation_number", + name: "mutation_number", + width: "12%", + }, + { + data: "created_at", + name: "created_at", + width: "12%", + }, + { + data: "from_dealer", + name: "fromDealer.name", + width: "15%", + }, + { + data: "to_dealer", + name: "toDealer.name", + width: "15%", + }, + { + data: "requested_by", + name: "requestedBy.name", + width: "12%", + }, + { + data: "total_items", + name: "total_items", + width: "8%", + className: "text-center", + }, + { + data: "status", + name: "status", + width: "12%", + className: "text-center", + }, + { + data: "action", + name: "action", + orderable: false, + searchable: false, + width: "15%", + className: "text-center", + }, + ], + order: [[2, "desc"]], // Order by created_at desc + pageLength: 10, + responsive: true, + language: { + processing: "Memuat data...", + lengthMenu: "Tampilkan _MENU_ data per halaman", + zeroRecords: "Data tidak ditemukan", + info: "Menampilkan _START_ sampai _END_ dari _TOTAL_ data", + infoEmpty: "Menampilkan 0 sampai 0 dari 0 data", + infoFiltered: "(difilter dari _MAX_ total data)", + }, + }); + + // Handle Receive Button Click + $(document).on("click", ".btn-receive", function () { + var mutationId = $(this).data("id"); + $("#receiveModal" + mutationId).modal("show"); + }); + + // Handle Approve Button Click + $(document).on("click", ".btn-approve", function () { + var mutationId = $(this).data("id"); + + // Load mutation details via AJAX + $.ajax({ + url: "/warehouse/mutations/" + mutationId + "/details", + type: "GET", + beforeSend: function () { + $("#mutation-details" + mutationId).html( + '' + + '' + + 'Loading...' + + "" + + "Memuat detail produk..." + + "" + ); + }, + success: function (response) { + var detailsHtml = "Detail Produk:"; + detailsHtml += ''; + detailsHtml += ''; + detailsHtml += ""; + detailsHtml += ""; + detailsHtml += "Produk"; + detailsHtml += "Diminta"; + detailsHtml += "Disetujui"; + detailsHtml += "Stock Tersedia"; + detailsHtml += ""; + detailsHtml += ""; + detailsHtml += ""; + + response.details.forEach(function (detail, index) { + detailsHtml += ""; + detailsHtml += "" + detail.product.name + ""; + detailsHtml += + "" + + parseFloat(detail.quantity_requested).toLocaleString() + + ""; + detailsHtml += ""; + detailsHtml += + ''; + detailsHtml += ""; + detailsHtml += + "" + + parseFloat(detail.available_stock).toLocaleString() + + ""; + detailsHtml += ""; + }); + + detailsHtml += ""; + detailsHtml += ""; + detailsHtml += ""; + + $("#mutation-details" + mutationId).html(detailsHtml); + }, + error: function () { + $("#mutation-details" + mutationId).html( + 'Gagal memuat detail produk' + ); + }, + }); + + $("#approveModal" + mutationId).modal("show"); + }); + + // Handle other button clicks + $(document).on("click", ".btn-reject", function () { + var mutationId = $(this).data("id"); + $("#rejectModal" + mutationId).modal("show"); + }); + + $(document).on("click", ".btn-complete", function () { + var mutationId = $(this).data("id"); + $("#completeModal" + mutationId).modal("show"); + }); + + // Handle Cancel Button Click with SweetAlert + $(document).on("click", ".btn-cancel", function () { + var mutationId = $(this).data("id"); + + if (typeof Swal !== "undefined") { + Swal.fire({ + title: "Batalkan Mutasi?", + text: "Apakah Anda yakin ingin membatalkan mutasi ini?", + icon: "warning", + showCancelButton: true, + confirmButtonColor: "#d33", + cancelButtonColor: "#3085d6", + confirmButtonText: "Ya, Batalkan", + cancelButtonText: "Batal", + }).then((result) => { + if (result.isConfirmed) { + cancelMutation(mutationId); + } + }); + } else { + if (confirm("Apakah Anda yakin ingin membatalkan mutasi ini?")) { + cancelMutation(mutationId); + } + } + }); + + function cancelMutation(mutationId) { + $.ajax({ + url: "/warehouse/mutations/" + mutationId + "/cancel", + type: "POST", + data: { + _token: $('meta[name="csrf-token"]').attr("content"), + }, + success: function (response) { + if (typeof Swal !== "undefined") { + Swal.fire({ + title: "Berhasil!", + text: "Mutasi berhasil dibatalkan", + icon: "success", + timer: 2000, + showConfirmButton: false, + }); + } else { + alert("Mutasi berhasil dibatalkan"); + } + table.ajax.reload(); + }, + error: function (xhr) { + var errorMsg = + xhr.responseJSON?.message || "Gagal membatalkan mutasi"; + if (typeof Swal !== "undefined") { + Swal.fire({ + title: "Error!", + text: errorMsg, + icon: "error", + }); + } else { + alert("Error: " + errorMsg); + } + }, + }); + } + + // Handle form submissions with loading state + $(document).on("submit", ".approve-form", function () { + $(this) + .find('button[type="submit"]') + .prop("disabled", true) + .html("Memproses..."); + }); + + // Auto-calculate approved quantity based on available stock + $(document).on("input", 'input[name*="quantity_approved"]', function () { + var maxValue = parseFloat($(this).attr("max")); + var currentValue = parseFloat($(this).val()); + + if (maxValue && currentValue > maxValue) { + $(this).val(maxValue); + $(this).addClass("is-invalid"); + if (!$(this).siblings(".invalid-feedback").length) { + $(this).after( + 'Jumlah melebihi stock yang tersedia' + ); + } + } else { + $(this).removeClass("is-invalid"); + $(this).siblings(".invalid-feedback").remove(); + } + }); +}); diff --git a/resources/views/layouts/partials/sidebarMenu.blade.php b/resources/views/layouts/partials/sidebarMenu.blade.php index 104744e..76eca2f 100644 --- a/resources/views/layouts/partials/sidebarMenu.blade.php +++ b/resources/views/layouts/partials/sidebarMenu.blade.php @@ -215,9 +215,9 @@ @endcan - @can('view', $menus['opnames.index']) + @can('view', $menus['mutations.index']) - + Mutasi Produk diff --git a/resources/views/warehouse_management/mutations/_action.blade.php b/resources/views/warehouse_management/mutations/_action.blade.php new file mode 100644 index 0000000..16d0e4e --- /dev/null +++ b/resources/views/warehouse_management/mutations/_action.blade.php @@ -0,0 +1,214 @@ + + + + + + + @if($row->status->value === 'sent') + + @if(auth()->user()->dealer_id == $row->to_dealer_id) + + + + @endif + + + @if(auth()->user()->dealer_id == $row->from_dealer_id || auth()->user()->hasRole('admin')) + + + + @endif + @endif + + @if($row->status->value === 'received') + + @if(auth()->user()->dealer_id == $row->from_dealer_id || auth()->user()->hasRole('admin')) + + + + @endif + + + @if(auth()->user()->dealer_id == $row->from_dealer_id || auth()->user()->hasRole('admin')) + + + + @endif + @endif + + @if($row->status->value === 'approved') + + @can('complete-mutation') + + + + @endcan + + + @can('edit-mutation') + + + + @endcan + @endif + + @if(in_array($row->status->value, ['pending', 'approved']) && auth()->user()->id === $row->requested_by) + + + + + @endif + + @if($row->status->value === 'completed') + + + + + @endif + + + + + + + + Setujui Mutasi + + × + + + + @csrf + + + Catatan Persetujuan + + + + + + + + Loading... + + Memuat detail produk... + + + + + + + + + + + + + + + Tolak Mutasi + + × + + + + @csrf + + + Peringatan! Mutasi yang ditolak tidak dapat diubah lagi. + + + Alasan Penolakan * + + + + + + + + + + + + + + + Terima Mutasi + + × + + + + @csrf + + + Konfirmasi! Anda akan menerima mutasi dari {{ $row->fromDealer->name }}. + + Setelah menerima, mutasi akan menunggu persetujuan dari pengirim sebelum stock dipindahkan. + + + + + + + + + + + + + Selesaikan Mutasi + + × + + + + @csrf + + + Konfirmasi! Stock akan dipindahkan dari {{ $row->fromDealer->name }} ke {{ $row->toDealer->name }}. + + Apakah Anda yakin ingin menyelesaikan mutasi ini? Tindakan ini tidak dapat dibatalkan. + + + + + + \ No newline at end of file diff --git a/resources/views/warehouse_management/mutations/create.blade.php b/resources/views/warehouse_management/mutations/create.blade.php new file mode 100644 index 0000000..d105c4c --- /dev/null +++ b/resources/views/warehouse_management/mutations/create.blade.php @@ -0,0 +1,159 @@ +@extends('layouts.backapp') + +@section('content') + + + + + + + Tambah Mutasi Baru + + + + + + + + Kembali + + + + + + + + @csrf + + @if ($errors->any()) + + + @foreach ($errors->all() as $error) + {{ $error }} + @endforeach + + + @endif + + + + + Dealer Asal * + + Pilih Dealer Asal + @foreach($dealers as $dealer) + id ? 'selected' : '' }}> + {{ $dealer->name }} + + @endforeach + + + + + + + Dealer Tujuan * + + Pilih Dealer Tujuan + @foreach($dealers as $dealer) + id ? 'selected' : '' }}> + {{ $dealer->name }} + + @endforeach + + + + + + + Catatan + {{ old('notes') }} + + + + + + + Detail Produk * + + Tambah Produk + + + + + + + + Produk + Stock Tersedia + Quantity + Catatan + Aksi + + + + + + + Pilih Produk + @foreach($products as $product) + {{ $product->name }} + @endforeach + + + + - + + + + + + + + + + + + + + + + + + + + + Informasi: + Mutasi akan dibuat dengan status "Menunggu Persetujuan" dan memerlukan approval sebelum stock dipindahkan. + + + + + + + Batal + + + + Simpan Mutasi + + + + + + + +@endsection + +@section('javascripts') + +@endsection \ No newline at end of file diff --git a/resources/views/warehouse_management/mutations/index.blade.php b/resources/views/warehouse_management/mutations/index.blade.php new file mode 100644 index 0000000..54f4b7b --- /dev/null +++ b/resources/views/warehouse_management/mutations/index.blade.php @@ -0,0 +1,52 @@ +@extends('layouts.backapp') + +@section('content') + + + + + + + + Tabel Mutasi + + + + + + + + Tambah Mutasi + + + + + + + + + + + + + No. + No. Mutasi + Tanggal + Dari Dealer + Ke Dealer + Dibuat Oleh + Total Item + Status + Aksi + + + + + + + +@endsection + +@section('javascripts') + +@endsection \ No newline at end of file diff --git a/resources/views/warehouse_management/mutations/show.blade.php b/resources/views/warehouse_management/mutations/show.blade.php new file mode 100644 index 0000000..a6b1723 --- /dev/null +++ b/resources/views/warehouse_management/mutations/show.blade.php @@ -0,0 +1,457 @@ +@extends('layouts.backapp') + +@section('content') + + + + + + + + Detail Mutasi - {{ $mutation->mutation_number }} + + + + + + + + Kembali + + + + + + + + + + No. Mutasi: + {{ $mutation->mutation_number }} + + + Dari Dealer: + {{ $mutation->fromDealer->name }} + + + Ke Dealer: + {{ $mutation->toDealer->name }} + + + Status: + + + {{ $mutation->status_label }} + + + + + + Dibuat Oleh: + {{ $mutation->requestedBy->name }} + + + Tanggal Dibuat: + {{ $mutation->created_at->format('d/m/Y H:i:s') }} + + @if($mutation->receivedBy) + + Diterima Oleh: + {{ $mutation->receivedBy->name }} + + + Tanggal Diterima: + {{ $mutation->received_at->format('d/m/Y H:i:s') }} + + @endif + @if($mutation->approvedBy) + + Disetujui Oleh: + {{ $mutation->approvedBy->name }} + + + Tanggal Disetujui: + {{ $mutation->approved_at->format('d/m/Y H:i:s') }} + + @endif + + + @if($mutation->notes) + + Catatan: + {{ $mutation->notes }} + + @endif + @if($mutation->rejection_reason) + + Alasan Penolakan: + {{ $mutation->rejection_reason }} + + @endif + + + + + + + + + Detail Produk + + + + + + + + + No. + Nama Produk + Jumlah Diminta + Jumlah Disetujui + Status Approval + Catatan + + + + @foreach($mutation->mutationDetails as $index => $detail) + + {{ $index + 1 }} + {{ $detail->product->name }} + {{ number_format($detail->quantity_requested, 2) }} + + @if($mutation->status->value === 'received' || $mutation->status->value === 'approved' || $mutation->status->value === 'completed') + {{ number_format($detail->quantity_approved ?? 0, 2) }} + @else + Belum ditentukan + @endif + + + @if($mutation->status->value === 'received' || $mutation->status->value === 'approved' || $mutation->status->value === 'completed') + + {{ $detail->approval_status }} + + @else + Menunggu + @endif + + {{ $detail->notes ?? '-' }} + + @endforeach + + + + Total + {{ number_format($mutation->mutationDetails->sum('quantity_requested'), 2) }} + + @if($mutation->status->value === 'received' || $mutation->status->value === 'approved' || $mutation->status->value === 'completed') + {{ number_format($mutation->mutationDetails->sum('quantity_approved'), 2) }} + @else + - + @endif + + + + + + + + + + + + + + + @if($mutation->status->value === 'sent' && auth()->user()->dealer_id == $mutation->to_dealer_id) + + + + Terima Mutasi + + @endif + + @if($mutation->status->value === 'received' && (auth()->user()->dealer_id == $mutation->from_dealer_id || auth()->user()->hasRole('admin'))) + + + + Setujui Mutasi + + + + + Tolak Mutasi + + @endif + + @if($mutation->status->value === 'approved') + + + + Selesaikan Mutasi + + @endif + + @if($mutation->canBeCancelled() && (auth()->user()->dealer_id == $mutation->from_dealer_id || auth()->user()->hasRole('admin'))) + + + + Batalkan Mutasi + + @endif + + @if($mutation->status->value === 'completed') + + + + Cetak Laporan + + @endif + + + + + + + + +@if($mutation->status->value === 'sent' && auth()->user()->dealer_id == $mutation->to_dealer_id) + + + + + + Terima Mutasi + + × + + + + @csrf + + + Konfirmasi! Anda akan menerima mutasi dari {{ $mutation->fromDealer->name }}. + + Setelah menerima, mutasi akan menunggu persetujuan dari pengirim sebelum stock dipindahkan. + + + + + + +@endif + +@if($mutation->status->value === 'received' && (auth()->user()->dealer_id == $mutation->from_dealer_id || auth()->user()->hasRole('admin'))) + + + + + + Setujui Mutasi + + × + + + + @csrf + + + Catatan Persetujuan + + + + + + + + Loading... + + Memuat detail produk... + + + + + + + + + + + + + + + Tolak Mutasi + + × + + + + @csrf + + + Peringatan! Mutasi yang ditolak tidak dapat diubah lagi. + + + Alasan Penolakan * + + + + + + + + +@endif + +@if($mutation->status->value === 'approved') + + + + + + Selesaikan Mutasi + + × + + + + @csrf + + + Konfirmasi! Stock akan dipindahkan dari {{ $mutation->fromDealer->name }} ke {{ $mutation->toDealer->name }}. + + Apakah Anda yakin ingin menyelesaikan mutasi ini? Tindakan ini tidak dapat dibatalkan. + + + + + + +@endif + +@if($mutation->canBeCancelled() && (auth()->user()->dealer_id == $mutation->from_dealer_id || auth()->user()->hasRole('admin'))) + + + + + + Batalkan Mutasi + + × + + + + @csrf + + + Peringatan! Mutasi yang dibatalkan tidak dapat diubah lagi. + + Apakah Anda yakin ingin membatalkan mutasi ini? + + + + + + +@endif +@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 deleted file mode 100644 index 53d1e84..0000000 --- a/resources/views/warehouse_management/stocks/_action.blade.php +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - \ 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 deleted file mode 100644 index 669745f..0000000 --- a/resources/views/warehouse_management/stocks/index.blade.php +++ /dev/null @@ -1,234 +0,0 @@ -@extends('layouts.backapp') - -@section('content') - - - - - - - Manajemen Stok - - - - - Buat Opname - - - - - - - - - - - Filter Dealer - - Semua Dealer - @foreach($dealers as $dealer) - {{ $dealer->name }} - @endforeach - - - - - - Filter Produk - - Semua Produk - @foreach($products as $product) - {{ $product->name }} - @endforeach - - - - - - - - - - - Dealer - Produk - Stok - Aksi - - - - - - - - - - - - - Adjust Stok - - × - - - - - - - - - Jumlah - - - - pcs - - - - - - Catatan - - - - - - - - - - - - - - - Riwayat Stok - - × - - - - - - - - Tanggal - User - Perubahan - Stok Lama - Stok Baru - Catatan - - - - - - - - - -@endsection - -@section('javascripts') - -@endsection \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index f2fd93f..d47a44e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -11,7 +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\Http\Controllers\WarehouseManagement\MutationsController; use App\Models\Menu; use App\Models\Privilege; use App\Models\Role; @@ -241,10 +241,19 @@ Route::group(['middleware' => 'auth'], function() { 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'); + Route::prefix('mutations')->name('mutations.')->controller(MutationsController::class)->group(function () { + Route::get('/', 'index')->name('index'); + Route::get('create', 'create')->name('create'); + Route::post('/', 'store')->name('store'); + Route::get('get-product-stock', 'getProductStock')->name('get-product-stock'); + Route::get('{mutation}', 'show')->name('show'); + Route::get('{mutation}/edit', 'edit')->name('edit'); + Route::get('{mutation}/details', 'getDetails')->name('details'); + Route::post('{mutation}/receive', 'receive')->name('receive'); + Route::post('{mutation}/approve', 'approve')->name('approve'); + Route::post('{mutation}/reject', 'reject')->name('reject'); + Route::post('{mutation}/complete', 'complete')->name('complete'); + Route::post('{mutation}/cancel', 'cancel')->name('cancel'); }); }); }); diff --git a/webpack.mix.js b/webpack.mix.js index ab77fb3..e2ff34f 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -33,6 +33,14 @@ mix.js("resources/js/app.js", "public/js") "resources/js/warehouse_management/opnames/detail.js", "public/js/warehouse_management/opnames" ) + .js( + "resources/js/warehouse_management/mutations/index.js", + "public/js/warehouse_management/mutations" + ) + .js( + "resources/js/warehouse_management/mutations/create.js", + "public/js/warehouse_management/mutations" + ) .sourceMaps(); mix.browserSync({
Memuat detail produk...
Setelah menerima, mutasi akan menunggu persetujuan dari pengirim sebelum stock dipindahkan.
Apakah Anda yakin ingin menyelesaikan mutasi ini? Tindakan ini tidak dapat dibatalkan.
{{ $mutation->mutation_number }}
{{ $mutation->fromDealer->name }}
{{ $mutation->toDealer->name }}
+ + {{ $mutation->status_label }} +
{{ $mutation->requestedBy->name }}
{{ $mutation->created_at->format('d/m/Y H:i:s') }}
{{ $mutation->receivedBy->name }}
{{ $mutation->received_at->format('d/m/Y H:i:s') }}
{{ $mutation->approvedBy->name }}
{{ $mutation->approved_at->format('d/m/Y H:i:s') }}
{{ $mutation->notes }}
Apakah Anda yakin ingin membatalkan mutasi ini?