From ce0a4718e061863b17017aa3917b3ea399197b9a Mon Sep 17 00:00:00 2001 From: arifal Date: Thu, 5 Jun 2025 12:05:20 +0700 Subject: [PATCH] partial update create modal list dealers --- .../WarehouseManagement/OpnamesController.php | 47 +++++++++++++- .../ProductsController.php | 63 +++++++++++-------- .../js/warehouse_management/opnames/create.js | 32 ++++++++++ .../js/warehouse_management/opnames/index.js | 2 +- public/mix-manifest.json | 1 + .../js/warehouse_management/opnames/create.js | 60 ++++++++++++++++++ .../js/warehouse_management/opnames/index.js | 31 +++++++++ .../views/layouts/partials/header.blade.php | 4 +- .../opnames/create.blade.php | 59 +++++++++++++++++ .../opnames/index.blade.php | 28 +++++++++ routes/web.php | 3 + webpack.mix.js | 4 ++ 12 files changed, 303 insertions(+), 31 deletions(-) create mode 100644 public/js/warehouse_management/opnames/create.js create mode 100644 resources/js/warehouse_management/opnames/create.js diff --git a/app/Http/Controllers/WarehouseManagement/OpnamesController.php b/app/Http/Controllers/WarehouseManagement/OpnamesController.php index 688bc09..d5d23fe 100644 --- a/app/Http/Controllers/WarehouseManagement/OpnamesController.php +++ b/app/Http/Controllers/WarehouseManagement/OpnamesController.php @@ -3,8 +3,11 @@ namespace App\Http\Controllers\WarehouseManagement; use App\Http\Controllers\Controller; +use App\Models\Dealer; use App\Models\Menu; use App\Models\Opname; +use App\Models\OpnameDetail; +use App\Models\Product; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; @@ -41,12 +44,52 @@ class OpnamesController extends Controller } public function create(){ - return view('warehouse_management.opnames.create'); + try{ + $dealers = Dealer::all(); + $products = Product::all(); + return view('warehouse_management.opnames.create', compact('dealers','products')); + }catch(\Exception $ex){ + Log::error($ex->getMessage()); + } } public function store(Request $request){ try{ - + $request->validate([ + 'dealer' => 'required|exists:dealers,id', + 'product' => 'required|array', + 'product.*' => 'nullable|exists:products,id', + 'system_quantity' => 'required|array', + 'physical_quantity' => 'required|array', + ]); + + // 1. Create Opname master record + $opname = Opname::create([ + 'dealer_id' => $request->dealer, + 'opname_date' => now(), // or $request->opname_date if you provide it + 'user_id' => auth()->id(), // assuming the user is logged in + 'note' => null, // or $request->note if needed + ]); + + // 2. Loop over products to create OpnameDetails + foreach ($request->product as $index => $productId) { + if (!$productId) continue; // Skip empty rows + + $system = $request->system_quantity[$index] ?? 0; + $physical = $request->physical_quantity[$index] ?? 0; + + OpnameDetail::create([ + 'opname_id' => $opname->id, + 'product_id' => $productId, + 'system_stock' => $system, + 'physical_stock' => $physical, + 'difference' => $physical - $system, + 'note' => null, // or include from input + ]); + } + + return redirect()->route('opnames.index') + ->with('success', 'Opname berhasil disimpan.'); }catch(\Exception $ex){ Log::error($ex->getMessage()); } diff --git a/app/Http/Controllers/WarehouseManagement/ProductsController.php b/app/Http/Controllers/WarehouseManagement/ProductsController.php index f3f129c..62c7d5f 100644 --- a/app/Http/Controllers/WarehouseManagement/ProductsController.php +++ b/app/Http/Controllers/WarehouseManagement/ProductsController.php @@ -25,14 +25,14 @@ class ProductsController extends Controller { $menu = Menu::where('link','products.index')->first(); if($request->ajax()){ - $data = Product::with(['category','dealers']); + $data = Product::with(['category','opnameDetails']); return DataTables::of($data) ->addIndexColumn() ->addColumn('category_name', function ($row) { return $row->category ? $row->category->name : '-'; }) ->addColumn('total_stock', function ($row){ - return 0; + return $row->opnameDetails->sum('system_stock'); }) ->addColumn('action', function ($row) use ($menu) { $btn = '
'; @@ -46,8 +46,11 @@ class ProductsController extends Controller data-url="' . route('products.toggleActive', $row->id) . '" data-active="'.$row->active.'" style="margin-right: 8px;">' . ($row->active ? 'Nonaktifkan' : 'Aktifkan') . ''; - $btn .= ''; - + $btn .= ''; + $btn .= '
'; return $btn; @@ -104,6 +107,7 @@ class ProductsController extends Controller return redirect()->route('products.index')->with('success', 'Produk berhasil ditambahkan.'); }catch(\Exception $ex){ + Log::error($ex->getMessage()); throw $ex; } } @@ -174,34 +178,12 @@ class ProductsController extends Controller */ public function destroy(Product $product) { - // Ambil stok pivot sebelum hapus - $dealerStocks = $product->dealers()->pluck('quantity', 'dealer_id')->toArray(); - - // Buat mutasi stok keluar (out) untuk semua stok yang dihapus - foreach ($dealerStocks as $dealerId => $qty) { - if ($qty > 0) { - StockMutation::create([ - 'product_id' => $product->id, - 'dealer_id' => $dealerId, - 'mutation_type' => 'out', - 'quantity' => $qty, - 'description' => 'Stock removed due to product deletion', - 'user_id' => auth()->id(), - ]); - } - } - - // Hapus pivot stok dealer - $product->dealers()->detach(); - - // Hapus produk $product->delete(); return redirect()->route('products.index')->with('success', 'Produk berhasil dihapus.'); } public function toggleActive(Request $request, Product $product) { - // You can add authorization here $product->active = !$product->active; $product->save(); @@ -211,4 +193,33 @@ class ProductsController extends Controller 'message' => 'Status produk berhasil diperbarui.' ]); } + + public function all_products(){ + try{ + $products = Product::select('id','name')->get(); + return response()->json($products); + }catch(\Exception $ex){ + Log::error($ex->getMessage()); + } + } + + public function dealers_stock(Request $request){ + $productId = $request->get('product_id'); + + $product = Product::with(['opnameDetails.opname.dealer'])->findOrFail($productId); + + $opnameDetails = $product->opnameDetails; + + $data = $opnameDetails->map(function ($detail) { + return [ + 'dealer_name' => $detail->opname->dealer->name ?? '-', + 'system_stock' => $detail->system_stock, + 'physical_stock' => $detail->physical_stock, + 'difference' => $detail->physical_stock - $detail->system_stock, + 'opname_date' => optional($detail->opname)->created_at->format('d M Y') + ]; + }); + + return DataTables::of($data)->make(true); + } } diff --git a/public/js/warehouse_management/opnames/create.js b/public/js/warehouse_management/opnames/create.js new file mode 100644 index 0000000..86dfcb8 --- /dev/null +++ b/public/js/warehouse_management/opnames/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/opnames/create.js": +/*!*************************************************************!*\ + !*** ./resources/js/warehouse_management/opnames/create.js ***! + \*************************************************************/ +/***/ (() => { + +eval("var productUrl = $(\"#product-container\").data(\"url\");\n\nfunction createProductSelectOptions(callback) {\n $.ajax({\n url: productUrl,\n method: \"GET\",\n success: function success(data) {\n var options = '';\n data.forEach(function (product) {\n options += \"\");\n });\n callback(options);\n },\n error: function error() {\n alert(\"Gagal memuat produk.\");\n }\n });\n}\n\n$(document).ready(function () {\n // Initial load only for the first row\n createProductSelectOptions(function (options) {\n $(\".product-select\").first().html(options);\n }); // When adding a new row\n\n $(document).on(\"click\", \".btn-add-row\", function () {\n var row = \"\\n
\\n
\\n \\n
\\n
\\n \\n
\\n
\\n \\n
\\n
\\n \\n
\\n
\\n \";\n var $newRow = $(row);\n $(\"#product-container\").append($newRow); // Load options only for the new select\n\n createProductSelectOptions(function (options) {\n $newRow.find(\".product-select\").html(options);\n });\n }); // Remove row\n\n $(document).on(\"click\", \".btn-remove-row\", function () {\n $(this).closest(\".product-row\").remove();\n });\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvb3BuYW1lcy9jcmVhdGUuanMiLCJuYW1lcyI6WyJwcm9kdWN0VXJsIiwiJCIsImRhdGEiLCJjcmVhdGVQcm9kdWN0U2VsZWN0T3B0aW9ucyIsImNhbGxiYWNrIiwiYWpheCIsInVybCIsIm1ldGhvZCIsInN1Y2Nlc3MiLCJvcHRpb25zIiwiZm9yRWFjaCIsInByb2R1Y3QiLCJpZCIsIm5hbWUiLCJlcnJvciIsImFsZXJ0IiwiZG9jdW1lbnQiLCJyZWFkeSIsImZpcnN0IiwiaHRtbCIsIm9uIiwicm93IiwiJG5ld1JvdyIsImFwcGVuZCIsImZpbmQiLCJjbG9zZXN0IiwicmVtb3ZlIl0sInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvb3BuYW1lcy9jcmVhdGUuanM/NWVlZiJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBwcm9kdWN0VXJsID0gJChcIiNwcm9kdWN0LWNvbnRhaW5lclwiKS5kYXRhKFwidXJsXCIpO1xuXG5mdW5jdGlvbiBjcmVhdGVQcm9kdWN0U2VsZWN0T3B0aW9ucyhjYWxsYmFjaykge1xuICAgICQuYWpheCh7XG4gICAgICAgIHVybDogcHJvZHVjdFVybCxcbiAgICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgbGV0IG9wdGlvbnMgPSAnPG9wdGlvbiB2YWx1ZT1cIlwiPlBpbGloIFByb2R1azwvb3B0aW9uPic7XG4gICAgICAgICAgICBkYXRhLmZvckVhY2goKHByb2R1Y3QpID0+IHtcbiAgICAgICAgICAgICAgICBvcHRpb25zICs9IGA8b3B0aW9uIHZhbHVlPVwiJHtwcm9kdWN0LmlkfVwiPiR7cHJvZHVjdC5uYW1lfTwvb3B0aW9uPmA7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNhbGxiYWNrKG9wdGlvbnMpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYWxlcnQoXCJHYWdhbCBtZW11YXQgcHJvZHVrLlwiKTtcbiAgICAgICAgfSxcbiAgICB9KTtcbn1cblxuJChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24gKCkge1xuICAgIC8vIEluaXRpYWwgbG9hZCBvbmx5IGZvciB0aGUgZmlyc3Qgcm93XG4gICAgY3JlYXRlUHJvZHVjdFNlbGVjdE9wdGlvbnMoKG9wdGlvbnMpID0+IHtcbiAgICAgICAgJChcIi5wcm9kdWN0LXNlbGVjdFwiKS5maXJzdCgpLmh0bWwob3B0aW9ucyk7XG4gICAgfSk7XG5cbiAgICAvLyBXaGVuIGFkZGluZyBhIG5ldyByb3dcbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1hZGQtcm93XCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgcm93ID0gYFxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXJvdyBhbGlnbi1pdGVtcy1lbmQgcHJvZHVjdC1yb3dcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIGNvbC1tZC00XCI+XG4gICAgICAgICAgICAgIDxzZWxlY3QgbmFtZT1cInByb2R1Y3RbXVwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHByb2R1Y3Qtc2VsZWN0XCI+XG4gICAgICAgICAgICAgICAgPG9wdGlvbj5Mb2FkaW5nLi4uPC9vcHRpb24+XG4gICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBjb2wtbWQtM1wiPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBuYW1lPVwic3lzdGVtX3F1YW50aXR5W11cIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIHBsYWNlaG9sZGVyPVwiU3RvayBzaXN0ZW1cIj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgY29sLW1kLTNcIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgbmFtZT1cInBoeXNpY2FsX3F1YW50aXR5W11cIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIHBsYWNlaG9sZGVyPVwiU3RvayBmaXNpa1wiPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBjb2wtbWQtMlwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyIGJ0bi1yZW1vdmUtcm93XCI+PGkgY2xhc3M9XCJmbGF0aWNvbjItZGVsZXRlXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIGA7XG5cbiAgICAgICAgY29uc3QgJG5ld1JvdyA9ICQocm93KTtcbiAgICAgICAgJChcIiNwcm9kdWN0LWNvbnRhaW5lclwiKS5hcHBlbmQoJG5ld1Jvdyk7XG5cbiAgICAgICAgLy8gTG9hZCBvcHRpb25zIG9ubHkgZm9yIHRoZSBuZXcgc2VsZWN0XG4gICAgICAgIGNyZWF0ZVByb2R1Y3RTZWxlY3RPcHRpb25zKChvcHRpb25zKSA9PiB7XG4gICAgICAgICAgICAkbmV3Um93LmZpbmQoXCIucHJvZHVjdC1zZWxlY3RcIikuaHRtbChvcHRpb25zKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBSZW1vdmUgcm93XG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi5idG4tcmVtb3ZlLXJvd1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICQodGhpcykuY2xvc2VzdChcIi5wcm9kdWN0LXJvd1wiKS5yZW1vdmUoKTtcbiAgICB9KTtcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxVQUFVLEdBQUdDLENBQUMsQ0FBQyxvQkFBRCxDQUFELENBQXdCQyxJQUF4QixDQUE2QixLQUE3QixDQUFuQjs7QUFFQSxTQUFTQywwQkFBVCxDQUFvQ0MsUUFBcEMsRUFBOEM7RUFDMUNILENBQUMsQ0FBQ0ksSUFBRixDQUFPO0lBQ0hDLEdBQUcsRUFBRU4sVUFERjtJQUVITyxNQUFNLEVBQUUsS0FGTDtJQUdIQyxPQUFPLEVBQUUsaUJBQVVOLElBQVYsRUFBZ0I7TUFDckIsSUFBSU8sT0FBTyxHQUFHLHdDQUFkO01BQ0FQLElBQUksQ0FBQ1EsT0FBTCxDQUFhLFVBQUNDLE9BQUQsRUFBYTtRQUN0QkYsT0FBTyw4QkFBc0JFLE9BQU8sQ0FBQ0MsRUFBOUIsZ0JBQXFDRCxPQUFPLENBQUNFLElBQTdDLGNBQVA7TUFDSCxDQUZEO01BR0FULFFBQVEsQ0FBQ0ssT0FBRCxDQUFSO0lBQ0gsQ0FURTtJQVVISyxLQUFLLEVBQUUsaUJBQVk7TUFDZkMsS0FBSyxDQUFDLHNCQUFELENBQUw7SUFDSDtFQVpFLENBQVA7QUFjSDs7QUFFRGQsQ0FBQyxDQUFDZSxRQUFELENBQUQsQ0FBWUMsS0FBWixDQUFrQixZQUFZO0VBQzFCO0VBQ0FkLDBCQUEwQixDQUFDLFVBQUNNLE9BQUQsRUFBYTtJQUNwQ1IsQ0FBQyxDQUFDLGlCQUFELENBQUQsQ0FBcUJpQixLQUFyQixHQUE2QkMsSUFBN0IsQ0FBa0NWLE9BQWxDO0VBQ0gsQ0FGeUIsQ0FBMUIsQ0FGMEIsQ0FNMUI7O0VBQ0FSLENBQUMsQ0FBQ2UsUUFBRCxDQUFELENBQVlJLEVBQVosQ0FBZSxPQUFmLEVBQXdCLGNBQXhCLEVBQXdDLFlBQVk7SUFDaEQsSUFBTUMsR0FBRyw4MkJBQVQ7SUFtQkEsSUFBTUMsT0FBTyxHQUFHckIsQ0FBQyxDQUFDb0IsR0FBRCxDQUFqQjtJQUNBcEIsQ0FBQyxDQUFDLG9CQUFELENBQUQsQ0FBd0JzQixNQUF4QixDQUErQkQsT0FBL0IsRUFyQmdELENBdUJoRDs7SUFDQW5CLDBCQUEwQixDQUFDLFVBQUNNLE9BQUQsRUFBYTtNQUNwQ2EsT0FBTyxDQUFDRSxJQUFSLENBQWEsaUJBQWIsRUFBZ0NMLElBQWhDLENBQXFDVixPQUFyQztJQUNILENBRnlCLENBQTFCO0VBR0gsQ0EzQkQsRUFQMEIsQ0FvQzFCOztFQUNBUixDQUFDLENBQUNlLFFBQUQsQ0FBRCxDQUFZSSxFQUFaLENBQWUsT0FBZixFQUF3QixpQkFBeEIsRUFBMkMsWUFBWTtJQUNuRG5CLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUXdCLE9BQVIsQ0FBZ0IsY0FBaEIsRUFBZ0NDLE1BQWhDO0VBQ0gsQ0FGRDtBQUdILENBeENEIn0=\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/opnames/create.js\n"); + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module can't be inlined because the eval-source-map devtool is used. +/******/ var __webpack_exports__ = {}; +/******/ __webpack_modules__["./resources/js/warehouse_management/opnames/create.js"](); +/******/ +/******/ })() +; \ No newline at end of file diff --git a/public/js/warehouse_management/opnames/index.js b/public/js/warehouse_management/opnames/index.js index 7165d83..c6da8b8 100644 --- a/public/js/warehouse_management/opnames/index.js +++ b/public/js/warehouse_management/opnames/index.js @@ -15,7 +15,7 @@ \************************************************************/ /***/ (() => { -eval("$.ajaxSetup({\n headers: {\n \"X-CSRF-TOKEN\": $('meta[name=\"csrf-token\"]').attr(\"content\")\n }\n});\nvar tableContainer = $(\"#opnames-table\");\nvar url = tableContainer.data(\"url\");\nvar table = $(\"#opnames-table\").DataTable({\n processing: true,\n serverSide: true,\n ajax: url,\n columns: [{\n data: \"dealer_name\",\n name: \"dealer.name\"\n }, {\n data: \"user_name\",\n name: \"user.name\"\n }, {\n data: \"opname_date\",\n name: \"opname_date\"\n }, {\n data: \"action\",\n name: \"action\",\n orderable: false,\n searchable: false\n }]\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvb3BuYW1lcy9pbmRleC5qcyIsIm5hbWVzIjpbIiQiLCJhamF4U2V0dXAiLCJoZWFkZXJzIiwiYXR0ciIsInRhYmxlQ29udGFpbmVyIiwidXJsIiwiZGF0YSIsInRhYmxlIiwiRGF0YVRhYmxlIiwicHJvY2Vzc2luZyIsInNlcnZlclNpZGUiLCJhamF4IiwiY29sdW1ucyIsIm5hbWUiLCJvcmRlcmFibGUiLCJzZWFyY2hhYmxlIl0sInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvb3BuYW1lcy9pbmRleC5qcz9hNGM4Il0sInNvdXJjZXNDb250ZW50IjpbIiQuYWpheFNldHVwKHtcbiAgICBoZWFkZXJzOiB7XG4gICAgICAgIFwiWC1DU1JGLVRPS0VOXCI6ICQoJ21ldGFbbmFtZT1cImNzcmYtdG9rZW5cIl0nKS5hdHRyKFwiY29udGVudFwiKSxcbiAgICB9LFxufSk7XG5sZXQgdGFibGVDb250YWluZXIgPSAkKFwiI29wbmFtZXMtdGFibGVcIik7XG5sZXQgdXJsID0gdGFibGVDb250YWluZXIuZGF0YShcInVybFwiKTtcbmxldCB0YWJsZSA9ICQoXCIjb3BuYW1lcy10YWJsZVwiKS5EYXRhVGFibGUoe1xuICAgIHByb2Nlc3Npbmc6IHRydWUsXG4gICAgc2VydmVyU2lkZTogdHJ1ZSxcbiAgICBhamF4OiB1cmwsXG4gICAgY29sdW1uczogW1xuICAgICAgICB7IGRhdGE6IFwiZGVhbGVyX25hbWVcIiwgbmFtZTogXCJkZWFsZXIubmFtZVwiIH0sXG4gICAgICAgIHsgZGF0YTogXCJ1c2VyX25hbWVcIiwgbmFtZTogXCJ1c2VyLm5hbWVcIiB9LFxuICAgICAgICB7IGRhdGE6IFwib3BuYW1lX2RhdGVcIiwgbmFtZTogXCJvcG5hbWVfZGF0ZVwiIH0sXG4gICAgICAgIHsgZGF0YTogXCJhY3Rpb25cIiwgbmFtZTogXCJhY3Rpb25cIiwgb3JkZXJhYmxlOiBmYWxzZSwgc2VhcmNoYWJsZTogZmFsc2UgfSxcbiAgICBdLFxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBQSxDQUFDLENBQUNDLFNBQUYsQ0FBWTtFQUNSQyxPQUFPLEVBQUU7SUFDTCxnQkFBZ0JGLENBQUMsQ0FBQyx5QkFBRCxDQUFELENBQTZCRyxJQUE3QixDQUFrQyxTQUFsQztFQURYO0FBREQsQ0FBWjtBQUtBLElBQUlDLGNBQWMsR0FBR0osQ0FBQyxDQUFDLGdCQUFELENBQXRCO0FBQ0EsSUFBSUssR0FBRyxHQUFHRCxjQUFjLENBQUNFLElBQWYsQ0FBb0IsS0FBcEIsQ0FBVjtBQUNBLElBQUlDLEtBQUssR0FBR1AsQ0FBQyxDQUFDLGdCQUFELENBQUQsQ0FBb0JRLFNBQXBCLENBQThCO0VBQ3RDQyxVQUFVLEVBQUUsSUFEMEI7RUFFdENDLFVBQVUsRUFBRSxJQUYwQjtFQUd0Q0MsSUFBSSxFQUFFTixHQUhnQztFQUl0Q08sT0FBTyxFQUFFLENBQ0w7SUFBRU4sSUFBSSxFQUFFLGFBQVI7SUFBdUJPLElBQUksRUFBRTtFQUE3QixDQURLLEVBRUw7SUFBRVAsSUFBSSxFQUFFLFdBQVI7SUFBcUJPLElBQUksRUFBRTtFQUEzQixDQUZLLEVBR0w7SUFBRVAsSUFBSSxFQUFFLGFBQVI7SUFBdUJPLElBQUksRUFBRTtFQUE3QixDQUhLLEVBSUw7SUFBRVAsSUFBSSxFQUFFLFFBQVI7SUFBa0JPLElBQUksRUFBRSxRQUF4QjtJQUFrQ0MsU0FBUyxFQUFFLEtBQTdDO0lBQW9EQyxVQUFVLEVBQUU7RUFBaEUsQ0FKSztBQUo2QixDQUE5QixDQUFaIn0=\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/opnames/index.js\n"); +eval("$.ajaxSetup({\n headers: {\n \"X-CSRF-TOKEN\": $('meta[name=\"csrf-token\"]').attr(\"content\")\n }\n});\nvar tableContainer = $(\"#opnames-table\");\nvar url = tableContainer.data(\"url\");\nvar table = $(\"#opnames-table\").DataTable({\n processing: true,\n serverSide: true,\n ajax: url,\n columns: [{\n data: \"dealer_name\",\n name: \"dealer.name\"\n }, {\n data: \"user_name\",\n name: \"user.name\"\n }, {\n data: \"opname_date\",\n name: \"opname_date\"\n }, {\n data: \"action\",\n name: \"action\",\n orderable: false,\n searchable: false\n }]\n});\n$(document).on(\"click\", \".btn-product-stock-dealers\", function () {\n var productId = $(this).data(\"id\");\n var productName = $(this).data(\"name\");\n var ajaxUrl = $(this).data(\"url\"); // Set product name in modal title\n\n $(\"#product-name-title\").text(productName); // Initialize or reload DataTable inside modal\n\n $(\"#dealer-stock-table\").DataTable({\n destroy: true,\n // reinit if exists\n processing: true,\n serverSide: true,\n ajax: {\n url: ajaxUrl,\n data: {\n product_id: productId\n }\n },\n columns: [{\n data: \"dealer_name\",\n name: \"dealer_name\"\n }, {\n data: \"system_stock\",\n name: \"system_stock\"\n }, {\n data: \"physical_stock\",\n name: \"physical_stock\"\n }, {\n data: \"difference\",\n name: \"difference\"\n }, {\n data: \"opname_date\",\n name: \"opname_date\"\n }]\n }); // Show the modal\n\n $(\"#dealerStockModal\").modal(\"show\");\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvb3BuYW1lcy9pbmRleC5qcyIsIm5hbWVzIjpbIiQiLCJhamF4U2V0dXAiLCJoZWFkZXJzIiwiYXR0ciIsInRhYmxlQ29udGFpbmVyIiwidXJsIiwiZGF0YSIsInRhYmxlIiwiRGF0YVRhYmxlIiwicHJvY2Vzc2luZyIsInNlcnZlclNpZGUiLCJhamF4IiwiY29sdW1ucyIsIm5hbWUiLCJvcmRlcmFibGUiLCJzZWFyY2hhYmxlIiwiZG9jdW1lbnQiLCJvbiIsInByb2R1Y3RJZCIsInByb2R1Y3ROYW1lIiwiYWpheFVybCIsInRleHQiLCJkZXN0cm95IiwicHJvZHVjdF9pZCIsIm1vZGFsIl0sInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvanMvd2FyZWhvdXNlX21hbmFnZW1lbnQvb3BuYW1lcy9pbmRleC5qcz9hNGM4Il0sInNvdXJjZXNDb250ZW50IjpbIiQuYWpheFNldHVwKHtcbiAgICBoZWFkZXJzOiB7XG4gICAgICAgIFwiWC1DU1JGLVRPS0VOXCI6ICQoJ21ldGFbbmFtZT1cImNzcmYtdG9rZW5cIl0nKS5hdHRyKFwiY29udGVudFwiKSxcbiAgICB9LFxufSk7XG5sZXQgdGFibGVDb250YWluZXIgPSAkKFwiI29wbmFtZXMtdGFibGVcIik7XG5sZXQgdXJsID0gdGFibGVDb250YWluZXIuZGF0YShcInVybFwiKTtcbmxldCB0YWJsZSA9ICQoXCIjb3BuYW1lcy10YWJsZVwiKS5EYXRhVGFibGUoe1xuICAgIHByb2Nlc3Npbmc6IHRydWUsXG4gICAgc2VydmVyU2lkZTogdHJ1ZSxcbiAgICBhamF4OiB1cmwsXG4gICAgY29sdW1uczogW1xuICAgICAgICB7IGRhdGE6IFwiZGVhbGVyX25hbWVcIiwgbmFtZTogXCJkZWFsZXIubmFtZVwiIH0sXG4gICAgICAgIHsgZGF0YTogXCJ1c2VyX25hbWVcIiwgbmFtZTogXCJ1c2VyLm5hbWVcIiB9LFxuICAgICAgICB7IGRhdGE6IFwib3BuYW1lX2RhdGVcIiwgbmFtZTogXCJvcG5hbWVfZGF0ZVwiIH0sXG4gICAgICAgIHsgZGF0YTogXCJhY3Rpb25cIiwgbmFtZTogXCJhY3Rpb25cIiwgb3JkZXJhYmxlOiBmYWxzZSwgc2VhcmNoYWJsZTogZmFsc2UgfSxcbiAgICBdLFxufSk7XG4kKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLmJ0bi1wcm9kdWN0LXN0b2NrLWRlYWxlcnNcIiwgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHByb2R1Y3RJZCA9ICQodGhpcykuZGF0YShcImlkXCIpO1xuICAgIGNvbnN0IHByb2R1Y3ROYW1lID0gJCh0aGlzKS5kYXRhKFwibmFtZVwiKTtcbiAgICBjb25zdCBhamF4VXJsID0gJCh0aGlzKS5kYXRhKFwidXJsXCIpO1xuXG4gICAgLy8gU2V0IHByb2R1Y3QgbmFtZSBpbiBtb2RhbCB0aXRsZVxuICAgICQoXCIjcHJvZHVjdC1uYW1lLXRpdGxlXCIpLnRleHQocHJvZHVjdE5hbWUpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBvciByZWxvYWQgRGF0YVRhYmxlIGluc2lkZSBtb2RhbFxuICAgICQoXCIjZGVhbGVyLXN0b2NrLXRhYmxlXCIpLkRhdGFUYWJsZSh7XG4gICAgICAgIGRlc3Ryb3k6IHRydWUsIC8vIHJlaW5pdCBpZiBleGlzdHNcbiAgICAgICAgcHJvY2Vzc2luZzogdHJ1ZSxcbiAgICAgICAgc2VydmVyU2lkZTogdHJ1ZSxcbiAgICAgICAgYWpheDoge1xuICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIHByb2R1Y3RfaWQ6IHByb2R1Y3RJZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGNvbHVtbnM6IFtcbiAgICAgICAgICAgIHsgZGF0YTogXCJkZWFsZXJfbmFtZVwiLCBuYW1lOiBcImRlYWxlcl9uYW1lXCIgfSxcbiAgICAgICAgICAgIHsgZGF0YTogXCJzeXN0ZW1fc3RvY2tcIiwgbmFtZTogXCJzeXN0ZW1fc3RvY2tcIiB9LFxuICAgICAgICAgICAgeyBkYXRhOiBcInBoeXNpY2FsX3N0b2NrXCIsIG5hbWU6IFwicGh5c2ljYWxfc3RvY2tcIiB9LFxuICAgICAgICAgICAgeyBkYXRhOiBcImRpZmZlcmVuY2VcIiwgbmFtZTogXCJkaWZmZXJlbmNlXCIgfSxcbiAgICAgICAgICAgIHsgZGF0YTogXCJvcG5hbWVfZGF0ZVwiLCBuYW1lOiBcIm9wbmFtZV9kYXRlXCIgfSxcbiAgICAgICAgXSxcbiAgICB9KTtcblxuICAgIC8vIFNob3cgdGhlIG1vZGFsXG4gICAgJChcIiNkZWFsZXJTdG9ja01vZGFsXCIpLm1vZGFsKFwic2hvd1wiKTtcbn0pO1xuIl0sIm1hcHBpbmdzIjoiQUFBQUEsQ0FBQyxDQUFDQyxTQUFGLENBQVk7RUFDUkMsT0FBTyxFQUFFO0lBQ0wsZ0JBQWdCRixDQUFDLENBQUMseUJBQUQsQ0FBRCxDQUE2QkcsSUFBN0IsQ0FBa0MsU0FBbEM7RUFEWDtBQURELENBQVo7QUFLQSxJQUFJQyxjQUFjLEdBQUdKLENBQUMsQ0FBQyxnQkFBRCxDQUF0QjtBQUNBLElBQUlLLEdBQUcsR0FBR0QsY0FBYyxDQUFDRSxJQUFmLENBQW9CLEtBQXBCLENBQVY7QUFDQSxJQUFJQyxLQUFLLEdBQUdQLENBQUMsQ0FBQyxnQkFBRCxDQUFELENBQW9CUSxTQUFwQixDQUE4QjtFQUN0Q0MsVUFBVSxFQUFFLElBRDBCO0VBRXRDQyxVQUFVLEVBQUUsSUFGMEI7RUFHdENDLElBQUksRUFBRU4sR0FIZ0M7RUFJdENPLE9BQU8sRUFBRSxDQUNMO0lBQUVOLElBQUksRUFBRSxhQUFSO0lBQXVCTyxJQUFJLEVBQUU7RUFBN0IsQ0FESyxFQUVMO0lBQUVQLElBQUksRUFBRSxXQUFSO0lBQXFCTyxJQUFJLEVBQUU7RUFBM0IsQ0FGSyxFQUdMO0lBQUVQLElBQUksRUFBRSxhQUFSO0lBQXVCTyxJQUFJLEVBQUU7RUFBN0IsQ0FISyxFQUlMO0lBQUVQLElBQUksRUFBRSxRQUFSO0lBQWtCTyxJQUFJLEVBQUUsUUFBeEI7SUFBa0NDLFNBQVMsRUFBRSxLQUE3QztJQUFvREMsVUFBVSxFQUFFO0VBQWhFLENBSks7QUFKNkIsQ0FBOUIsQ0FBWjtBQVdBZixDQUFDLENBQUNnQixRQUFELENBQUQsQ0FBWUMsRUFBWixDQUFlLE9BQWYsRUFBd0IsNEJBQXhCLEVBQXNELFlBQVk7RUFDOUQsSUFBTUMsU0FBUyxHQUFHbEIsQ0FBQyxDQUFDLElBQUQsQ0FBRCxDQUFRTSxJQUFSLENBQWEsSUFBYixDQUFsQjtFQUNBLElBQU1hLFdBQVcsR0FBR25CLENBQUMsQ0FBQyxJQUFELENBQUQsQ0FBUU0sSUFBUixDQUFhLE1BQWIsQ0FBcEI7RUFDQSxJQUFNYyxPQUFPLEdBQUdwQixDQUFDLENBQUMsSUFBRCxDQUFELENBQVFNLElBQVIsQ0FBYSxLQUFiLENBQWhCLENBSDhELENBSzlEOztFQUNBTixDQUFDLENBQUMscUJBQUQsQ0FBRCxDQUF5QnFCLElBQXpCLENBQThCRixXQUE5QixFQU44RCxDQVE5RDs7RUFDQW5CLENBQUMsQ0FBQyxxQkFBRCxDQUFELENBQXlCUSxTQUF6QixDQUFtQztJQUMvQmMsT0FBTyxFQUFFLElBRHNCO0lBQ2hCO0lBQ2ZiLFVBQVUsRUFBRSxJQUZtQjtJQUcvQkMsVUFBVSxFQUFFLElBSG1CO0lBSS9CQyxJQUFJLEVBQUU7TUFDRk4sR0FBRyxFQUFFZSxPQURIO01BRUZkLElBQUksRUFBRTtRQUNGaUIsVUFBVSxFQUFFTDtNQURWO0lBRkosQ0FKeUI7SUFVL0JOLE9BQU8sRUFBRSxDQUNMO01BQUVOLElBQUksRUFBRSxhQUFSO01BQXVCTyxJQUFJLEVBQUU7SUFBN0IsQ0FESyxFQUVMO01BQUVQLElBQUksRUFBRSxjQUFSO01BQXdCTyxJQUFJLEVBQUU7SUFBOUIsQ0FGSyxFQUdMO01BQUVQLElBQUksRUFBRSxnQkFBUjtNQUEwQk8sSUFBSSxFQUFFO0lBQWhDLENBSEssRUFJTDtNQUFFUCxJQUFJLEVBQUUsWUFBUjtNQUFzQk8sSUFBSSxFQUFFO0lBQTVCLENBSkssRUFLTDtNQUFFUCxJQUFJLEVBQUUsYUFBUjtNQUF1Qk8sSUFBSSxFQUFFO0lBQTdCLENBTEs7RUFWc0IsQ0FBbkMsRUFUOEQsQ0E0QjlEOztFQUNBYixDQUFDLENBQUMsbUJBQUQsQ0FBRCxDQUF1QndCLEtBQXZCLENBQTZCLE1BQTdCO0FBQ0gsQ0E5QkQifQ==\n//# sourceURL=webpack-internal:///./resources/js/warehouse_management/opnames/index.js\n"); /***/ }) diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 5267aa1..bc8e6b0 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -5,5 +5,6 @@ "/js/warehouse_management/products/create.js": "/js/warehouse_management/products/create.js", "/js/warehouse_management/products/edit.js": "/js/warehouse_management/products/edit.js", "/js/warehouse_management/opnames/index.js": "/js/warehouse_management/opnames/index.js", + "/js/warehouse_management/opnames/create.js": "/js/warehouse_management/opnames/create.js", "/css/app.css": "/css/app.css" } diff --git a/resources/js/warehouse_management/opnames/create.js b/resources/js/warehouse_management/opnames/create.js new file mode 100644 index 0000000..d186f6d --- /dev/null +++ b/resources/js/warehouse_management/opnames/create.js @@ -0,0 +1,60 @@ +const productUrl = $("#product-container").data("url"); + +function createProductSelectOptions(callback) { + $.ajax({ + url: productUrl, + method: "GET", + success: function (data) { + let options = ''; + data.forEach((product) => { + options += ``; + }); + callback(options); + }, + error: function () { + alert("Gagal memuat produk."); + }, + }); +} + +$(document).ready(function () { + // Initial load only for the first row + createProductSelectOptions((options) => { + $(".product-select").first().html(options); + }); + + // When adding a new row + $(document).on("click", ".btn-add-row", function () { + const row = ` +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ `; + + const $newRow = $(row); + $("#product-container").append($newRow); + + // Load options only for the new select + createProductSelectOptions((options) => { + $newRow.find(".product-select").html(options); + }); + }); + + // Remove row + $(document).on("click", ".btn-remove-row", function () { + $(this).closest(".product-row").remove(); + }); +}); diff --git a/resources/js/warehouse_management/opnames/index.js b/resources/js/warehouse_management/opnames/index.js index e46f378..7633649 100644 --- a/resources/js/warehouse_management/opnames/index.js +++ b/resources/js/warehouse_management/opnames/index.js @@ -16,3 +16,34 @@ let table = $("#opnames-table").DataTable({ { data: "action", name: "action", orderable: false, searchable: false }, ], }); +$(document).on("click", ".btn-product-stock-dealers", function () { + const productId = $(this).data("id"); + const productName = $(this).data("name"); + const ajaxUrl = $(this).data("url"); + + // Set product name in modal title + $("#product-name-title").text(productName); + + // Initialize or reload DataTable inside modal + $("#dealer-stock-table").DataTable({ + destroy: true, // reinit if exists + processing: true, + serverSide: true, + ajax: { + url: ajaxUrl, + data: { + product_id: productId, + }, + }, + columns: [ + { data: "dealer_name", name: "dealer_name" }, + { data: "system_stock", name: "system_stock" }, + { data: "physical_stock", name: "physical_stock" }, + { data: "difference", name: "difference" }, + { data: "opname_date", name: "opname_date" }, + ], + }); + + // Show the modal + $("#dealerStockModal").modal("show"); +}); diff --git a/resources/views/layouts/partials/header.blade.php b/resources/views/layouts/partials/header.blade.php index 782cf23..25903bd 100644 --- a/resources/views/layouts/partials/header.blade.php +++ b/resources/views/layouts/partials/header.blade.php @@ -19,7 +19,7 @@
Hi, - John Doe + {{ Auth::user()->name ?? '' }}
@@ -27,7 +27,7 @@
- John Doe + {{ Auth::user()->name ?? '' }}
diff --git a/resources/views/warehouse_management/opnames/create.blade.php b/resources/views/warehouse_management/opnames/create.blade.php index e69de29..0653b61 100644 --- a/resources/views/warehouse_management/opnames/create.blade.php +++ b/resources/views/warehouse_management/opnames/create.blade.php @@ -0,0 +1,59 @@ +@extends('layouts.backapp') + +@section('content') +
+
+
+ + + +

Tambah Opnames

+
+
+ +
+
+ @csrf +
+ + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+ +
+ +
+
+
+
+@endsection + +@section('javascripts') + +@endsection diff --git a/resources/views/warehouse_management/opnames/index.blade.php b/resources/views/warehouse_management/opnames/index.blade.php index 6518c3c..9a817a7 100644 --- a/resources/views/warehouse_management/opnames/index.blade.php +++ b/resources/views/warehouse_management/opnames/index.blade.php @@ -39,6 +39,34 @@ + + + @endsection @section('javascripts') diff --git a/routes/web.php b/routes/web.php index bc319cd..1957073 100644 --- a/routes/web.php +++ b/routes/web.php @@ -211,6 +211,8 @@ Route::group(['middleware' => 'auth'], function() { Route::get('/', 'index')->name('products.index'); Route::get('create', 'create')->name('products.create'); Route::post('/', 'store')->name('products.store'); + Route::get('all','all_products')->name('products.all'); + Route::get('dealers-stock')->name('products.dealers_stock'); Route::get('{product}', 'show')->name('products.show'); Route::get('{product}/edit', 'edit')->name('products.edit'); Route::put('{product}', 'update')->name('products.update'); @@ -233,6 +235,7 @@ Route::group(['middleware' => 'auth'], function() { Route::prefix('opnames')->controller(OpnamesController::class)->group(function (){ Route::get('/','index')->name('opnames.index'); Route::get('create','create')->name('opnames.create'); + Route::post('/','store')->name('opnames.store'); }); }); }); diff --git a/webpack.mix.js b/webpack.mix.js index b58f527..c627e4b 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -33,6 +33,10 @@ mix.js("resources/js/app.js", "public/js") "resources/js/warehouse_management/opnames/index.js", "public/js/warehouse_management/opnames" ) + .js( + "resources/js/warehouse_management/opnames/create.js", + "public/js/warehouse_management/opnames" + ) .sourceMaps(); mix.browserSync({