';
+ })
->addColumn('action', function ($row) use ($menu) {
$btn = '
';
@@ -86,7 +126,7 @@ class OpnamesController extends Controller
return $btn;
})
- ->rawColumns(['action', 'status'])
+ ->rawColumns(['action', 'status', 'stock_info'])
->make(true);
}
@@ -124,7 +164,7 @@ class OpnamesController extends Controller
$isTransactionForm = $request->has('form') && $request->form === 'opname';
if ($isTransactionForm) {
- // Custom validation for transaction form
+ // Simplified validation for transaction form
$request->validate([
'dealer_id' => 'required|exists:dealers,id',
'user_id' => 'required|exists:users,id',
@@ -140,7 +180,7 @@ class OpnamesController extends Controller
'system_stock' => 'required|array',
'system_stock.*' => 'required|numeric|min:0',
'physical_stock' => 'required|array',
- 'physical_stock.*' => 'required|numeric|min:0'
+ 'physical_stock.*' => 'nullable|numeric|min:0'
]);
// Process transaction form data with proper date parsing
@@ -199,19 +239,11 @@ class OpnamesController extends Controller
$physicalStocks = $request->physical_quantity;
}
- // 2. Validasi minimal ada produk yang diisi (termasuk nilai 0)
+ // 2. Simplified validation - all products are valid, set defaults for empty physical stocks
$validProductIds = array_filter($productIds);
- $validSystemStocks = array_filter($systemStocks, function($value) { return $value !== null && $value !== ''; });
- $validPhysicalStocks = array_filter($physicalStocks, function($value) {
- return $value !== null && $value !== '' && is_numeric($value);
- });
if (empty($validProductIds) || count($validProductIds) === 0) {
- throw new \Exception('Minimal harus ada satu produk yang diisi untuk opname.');
- }
-
- if (count($validPhysicalStocks) === 0) {
- throw new \Exception('Minimal harus ada satu stock fisik yang diisi (termasuk nilai 0).');
+ throw new \Exception('Minimal harus ada satu produk untuk opname.');
}
// 3. Validasi duplikasi produk
@@ -283,19 +315,14 @@ class OpnamesController extends Controller
foreach ($productIds as $index => $productId) {
if (!$productId) continue;
- // Skip only if physical stock is truly not provided (empty string or null)
- // Accept 0 as valid input
- if (!isset($physicalStocks[$index]) || $physicalStocks[$index] === '' || $physicalStocks[$index] === null) {
- continue;
- }
-
- // Validate that physical stock is numeric (including 0)
- if (!is_numeric($physicalStocks[$index])) {
- continue;
+ // Set default value to 0 if physical stock is empty or invalid
+ $physicalStockValue = $physicalStocks[$index] ?? null;
+ if ($physicalStockValue === '' || $physicalStockValue === null || !is_numeric($physicalStockValue)) {
+ $physicalStockValue = 0;
}
$systemStock = floatval($systemStocks[$index] ?? 0);
- $physicalStock = floatval($physicalStocks[$index]);
+ $physicalStock = floatval($physicalStockValue);
$difference = $physicalStock - $systemStock;
$processedCount++;
@@ -337,7 +364,7 @@ class OpnamesController extends Controller
// Validate we have at least one detail to insert
if (empty($details)) {
- throw new \Exception('Tidak ada data stock fisik yang valid untuk diproses.');
+ throw new \Exception('Tidak ada data produk yang valid untuk diproses.');
}
// Bulk insert untuk performa lebih baik
@@ -371,13 +398,13 @@ class OpnamesController extends Controller
// Redirect back to transaction page with success message and tab indicator
return redirect()
->route('transaction')
- ->with('success', "Opname berhasil disimpan dan disetujui. {$processedCount} produk telah diproses.")
+ ->with('success', "Opname berhasil disimpan. {$processedCount} produk telah diproses.")
->with('active_tab', 'opname');
} else {
// Redirect to opname index for regular form
return redirect()
->route('opnames.index')
- ->with('success', "Opname berhasil disimpan dan disetujui. {$processedCount} produk telah diproses.");
+ ->with('success', "Opname berhasil disimpan. {$processedCount} produk telah diproses.");
}
} catch (\Illuminate\Validation\ValidationException $e) {
diff --git a/public/js/warehouse_management/opnames/index.js b/public/js/warehouse_management/opnames/index.js
index a8c1f6a..3101d66 100755
--- a/public/js/warehouse_management/opnames/index.js
+++ b/public/js/warehouse_management/opnames/index.js
@@ -1,2 +1,2 @@
-(()=>{function e(){$("#date_to").datepicker({format:"yyyy-mm-dd",autoclose:!0,todayHighlight:!0,orientation:"bottom left",templates:{leftArrow:'',rightArrow:''},endDate:new Date,clearBtn:!0}).on("changeDate",(function(e){console.log("End date selected:",e.format())})).on("clearDate",(function(e){console.log("End date cleared")}))}function a(){$("#date_to").datepicker("remove"),$("#date_to").val(""),e(),$("#date_to").prop("disabled",!0),console.log("End date picker reset and disabled")}$(document).ready((function(){console.log("Opnames index.js loaded"),void 0!==$.fn.DataTable?(console.log("Initializing Select2..."),void 0!==$.fn.select2?$("#dealer_filter").select2({placeholder:"Pilih...",allowClear:!0,width:"100%"}):console.warn("Select2 not available, using regular select"),function(){if(console.log("Initializing datepickers..."),void 0===$.fn.datepicker)return void console.error("Bootstrap Datepicker not available!");$("#date_from").datepicker({format:"yyyy-mm-dd",autoclose:!0,todayHighlight:!0,orientation:"bottom left",templates:{leftArrow:'',rightArrow:''},endDate:new Date,clearBtn:!0}).on("changeDate",(function(e){var a;console.log("Start date selected:",e.format()),a=e.format(),console.log("Enabling end date picker with min date:",a),$("#date_to").prop("disabled",!1),$("#date_to").datepicker("remove"),$("#date_to").datepicker({format:"yyyy-mm-dd",autoclose:!0,todayHighlight:!0,orientation:"bottom left",templates:{leftArrow:'',rightArrow:''},startDate:a,endDate:new Date,clearBtn:!0}).on("changeDate",(function(e){console.log("End date selected:",e.format())})).on("clearDate",(function(e){console.log("End date cleared")})),console.log("End date picker enabled with startDate:",a)})).on("clearDate",(function(e){console.log("Start date cleared"),a()})),e(),$("#date_to").prop("disabled",!0)}(),setTimeout((function(){!function(){console.log("Initializing DataTable..."),$.fn.DataTable.isDataTable("#opnames-table")&&$("#opnames-table").DataTable().destroy();var e=$("#opnames-table").DataTable({processing:!0,serverSide:!0,destroy:!0,ajax:{url:$("#opnames-table").data("url"),type:"GET",data:function(e){return e.dealer_filter=$("#dealer_filter").val(),e.date_from=$("#date_from").val(),e.date_to=$("#date_to").val(),console.log("AJAX data being sent:",{dealer_filter:e.dealer_filter,date_from:e.date_from,date_to:e.date_to}),e},error:function(e,a,t){console.error("DataTables AJAX error:",a,t),console.error("Response:",e.responseText)}},columnDefs:[{targets:0,width:"15%"},{targets:5,width:"15%",className:"text-center"}],columns:[{data:"created_at",name:"created_at",orderable:!0},{data:"opname_date",name:"opname_date",orderable:!0},{data:"dealer_name",name:"dealer.name",orderable:!0},{data:"user_name",name:"user.name",orderable:!0},{data:"status",name:"status",orderable:!0},{data:"action",name:"action",orderable:!1,searchable:!1}],order:[[4,"desc"]],pageLength:10,responsive:!0,ordering:!0,orderMulti:!1});(function(e){$("#kt_search").on("click",(function(){console.log("Filter button clicked");var a=$("#dealer_filter").val(),t=$("#date_from").val(),o=$("#date_to").val();console.log("Filtering with:",{dealer:a,dateFrom:t,dateTo:o}),e.ajax.reload()})),$("#kt_reset").on("click",(function(){console.log("Reset button clicked"),$("#dealer_filter").val(null).trigger("change.select2"),$("#date_from").datepicker("clearDates"),$("#date_to").datepicker("clearDates"),a(),e.ajax.reload()})),$("#date_from, #date_to").on("keypress",(function(e){13===e.which&&$("#kt_search").click()})),$("#dealer_filter").on("change",(function(){console.log("Dealer filter changed:",$(this).val())}))})(e),function(e){e.on("order.dt",(function(){console.log("Order changed:",e.order())})),e.on("processing.dt",(function(e,a,t){t?console.log("DataTable processing started"):console.log("DataTable processing finished")}))}(e)}()}),100)):console.error("DataTables not available!")}))})();
+(()=>{function e(){$("#date_to").datepicker({format:"yyyy-mm-dd",autoclose:!0,todayHighlight:!0,orientation:"bottom left",templates:{leftArrow:'',rightArrow:''},endDate:new Date,clearBtn:!0}).on("changeDate",(function(e){console.log("End date selected:",e.format())})).on("clearDate",(function(e){console.log("End date cleared")}))}function a(){$("#date_to").datepicker("remove"),$("#date_to").val(""),e(),$("#date_to").prop("disabled",!0),console.log("End date picker reset and disabled")}$(document).ready((function(){console.log("Opnames index.js loaded"),void 0!==$.fn.DataTable?(console.log("Initializing Select2..."),void 0!==$.fn.select2?$("#dealer_filter").select2({placeholder:"Pilih...",allowClear:!0,width:"100%"}):console.warn("Select2 not available, using regular select"),function(){if(console.log("Initializing datepickers..."),void 0===$.fn.datepicker)return void console.error("Bootstrap Datepicker not available!");$("#date_from").datepicker({format:"yyyy-mm-dd",autoclose:!0,todayHighlight:!0,orientation:"bottom left",templates:{leftArrow:'',rightArrow:''},endDate:new Date,clearBtn:!0}).on("changeDate",(function(e){var a;console.log("Start date selected:",e.format()),a=e.format(),console.log("Enabling end date picker with min date:",a),$("#date_to").prop("disabled",!1),$("#date_to").datepicker("remove"),$("#date_to").datepicker({format:"yyyy-mm-dd",autoclose:!0,todayHighlight:!0,orientation:"bottom left",templates:{leftArrow:'',rightArrow:''},startDate:a,endDate:new Date,clearBtn:!0}).on("changeDate",(function(e){console.log("End date selected:",e.format())})).on("clearDate",(function(e){console.log("End date cleared")})),console.log("End date picker enabled with startDate:",a)})).on("clearDate",(function(e){console.log("Start date cleared"),a()})),e(),$("#date_to").prop("disabled",!0)}(),setTimeout((function(){!function(){console.log("Initializing DataTable..."),$.fn.DataTable.isDataTable("#opnames-table")&&$("#opnames-table").DataTable().destroy();var e=$("#opnames-table").DataTable({processing:!0,serverSide:!0,destroy:!0,ajax:{url:$("#opnames-table").data("url"),type:"GET",data:function(e){return e.dealer_filter=$("#dealer_filter").val(),e.date_from=$("#date_from").val(),e.date_to=$("#date_to").val(),console.log("AJAX data being sent:",{dealer_filter:e.dealer_filter,date_from:e.date_from,date_to:e.date_to}),e},error:function(e,a,t){console.error("DataTables AJAX error:",a,t),console.error("Response:",e.responseText)}},columnDefs:[{targets:0,width:"15%"},{targets:1,width:"12%"},{targets:2,width:"15%"},{targets:3,width:"12%"},{targets:4,width:"10%"},{targets:5,width:"15%",className:"text-center"},{targets:6,width:"15%",className:"text-center"}],columns:[{data:"created_at",name:"created_at",orderable:!0},{data:"opname_date",name:"opname_date",orderable:!0},{data:"dealer_name",name:"dealer.name",orderable:!0},{data:"user_name",name:"user.name",orderable:!0},{data:"status",name:"status",orderable:!0},{data:"stock_info",name:"stock_info",orderable:!1,searchable:!1},{data:"action",name:"action",orderable:!1,searchable:!1}],order:[[0,"desc"]],pageLength:10,responsive:!0,ordering:!0,orderMulti:!1});(function(e){$("#kt_search").on("click",(function(){console.log("Filter button clicked");var a=$("#dealer_filter").val(),t=$("#date_from").val(),o=$("#date_to").val();console.log("Filtering with:",{dealer:a,dateFrom:t,dateTo:o}),e.ajax.reload()})),$("#kt_reset").on("click",(function(){console.log("Reset button clicked"),$("#dealer_filter").val(null).trigger("change.select2"),$("#date_from").datepicker("clearDates"),$("#date_to").datepicker("clearDates"),a(),e.ajax.reload()})),$("#date_from, #date_to").on("keypress",(function(e){13===e.which&&$("#kt_search").click()})),$("#dealer_filter").on("change",(function(){console.log("Dealer filter changed:",$(this).val())}))})(e),function(e){e.on("order.dt",(function(){console.log("Order changed:",e.order())})),e.on("processing.dt",(function(e,a,t){t?console.log("DataTable processing started"):console.log("DataTable processing finished")}))}(e)}()}),100)):console.error("DataTables not available!")}))})();
//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/public/js/warehouse_management/opnames/index.js.map b/public/js/warehouse_management/opnames/index.js.map
index ec30f05..b4af9a0 100755
--- a/public/js/warehouse_management/opnames/index.js.map
+++ b/public/js/warehouse_management/opnames/index.js.map
@@ -1 +1 @@
-{"version":3,"file":"/js/warehouse_management/opnames/index.js","mappings":"MAsHA,SAASA,IACLC,EAAE,YACGC,WAAW,CACRC,OAAQ,aACRC,WAAW,EACXC,gBAAgB,EAChBC,YAAa,cACbC,UAAW,CACPC,UAAW,mCACXC,WAAY,qCAEhBC,QAAS,IAAIC,KACbC,UAAU,IAEbC,GAAG,cAAc,SAAUC,GACxBC,QAAQC,IAAI,qBAAsBF,EAAEX,SACvC,IACAU,GAAG,aAAa,SAAUC,GACvBC,QAAQC,IAAI,mBACf,GACR,CAKD,SAASC,IAELhB,EAAE,YAAYC,WAAW,UAGzBD,EAAE,YAAYiB,IAAI,IAGlBlB,IAGAC,EAAE,YAAYkB,KAAK,YAAY,GAE/BJ,QAAQC,IAAI,qCACf,CA7JDf,EAAEmB,UAAUC,OAAM,WACdN,QAAQC,IAAI,gCAGkB,IAAnBf,EAAEqB,GAAGC,WAmBhBR,QAAQC,IAAI,gCAEgB,IAAjBf,EAAEqB,GAAGE,QACZvB,EAAE,kBAAkBuB,QAAQ,CACxBC,YAAa,WACbC,YAAY,EACZC,MAAO,SAGXZ,QAAQa,KAAK,+CAOrB,WAII,GAHAb,QAAQC,IAAI,oCAGmB,IAApBf,EAAEqB,GAAGpB,WAEZ,YADAa,QAAQc,MAAM,uCAKlB5B,EAAE,cACGC,WAAW,CACRC,OAAQ,aACRC,WAAW,EACXC,gBAAgB,EAChBC,YAAa,cACbC,UAAW,CACPC,UAAW,mCACXC,WAAY,qCAEhBC,QAAS,IAAIC,KACbC,UAAU,IAEbC,GAAG,cAAc,SAAUC,GAmBpC,IAA6BgB,EAlBjBf,QAAQC,IAAI,uBAAwBF,EAAEX,UAkBrB2B,EAjBGhB,EAAEX,SAkB9BY,QAAQC,IAAI,0CAA2Cc,GAGvD7B,EAAE,YAAYkB,KAAK,YAAY,GAG/BlB,EAAE,YAAYC,WAAW,UAGzBD,EAAE,YACGC,WAAW,CACRC,OAAQ,aACRC,WAAW,EACXC,gBAAgB,EAChBC,YAAa,cACbC,UAAW,CACPC,UAAW,mCACXC,WAAY,qCAEhBqB,UAAWA,EACXpB,QAAS,IAAIC,KACbC,UAAU,IAEbC,GAAG,cAAc,SAAUC,GACxBC,QAAQC,IAAI,qBAAsBF,EAAEX,SACvC,IACAU,GAAG,aAAa,SAAUC,GACvBC,QAAQC,IAAI,mBACf,IAELD,QAAQC,IAAI,0CAA2Cc,EA/ClD,IACAjB,GAAG,aAAa,SAAUC,GACvBC,QAAQC,IAAI,sBACZC,GACH,IAGLjB,IAGAC,EAAE,YAAYkB,KAAK,YAAY,EAClC,CAjEGY,GAGAC,YAAW,YAoJf,WACIjB,QAAQC,IAAI,6BAGRf,EAAEqB,GAAGC,UAAUU,YAAY,mBAC3BhC,EAAE,kBAAkBsB,YAAYW,UAIpC,IAAMC,EAAQlC,EAAE,kBAAkBsB,UAAU,CACxCa,YAAY,EACZC,YAAY,EACZH,SAAS,EACTI,KAAM,CACFC,IAAKtC,EAAE,kBAAkBuC,KAAK,OAC9BC,KAAM,MACND,KAAM,SAAUE,GAYZ,OAVAA,EAAEC,cAAgB1C,EAAE,kBAAkBiB,MACtCwB,EAAEE,UAAY3C,EAAE,cAAciB,MAC9BwB,EAAEG,QAAU5C,EAAE,YAAYiB,MAE1BH,QAAQC,IAAI,wBAAyB,CACjC2B,cAAeD,EAAEC,cACjBC,UAAWF,EAAEE,UACbC,QAASH,EAAEG,UAGRH,CACV,EACDb,MAAO,SAAUiB,EAAKjB,EAAOkB,GACzBhC,QAAQc,MAAM,yBAA0BA,EAAOkB,GAC/ChC,QAAQc,MAAM,YAAaiB,EAAIE,aAClC,GAELC,WAAY,CACR,CAAEC,QAAS,EAAGvB,MAAO,OACrB,CAAEuB,QAAS,EAAGvB,MAAO,MAAOwB,UAAW,gBAE3CC,QAAS,CACL,CACIZ,KAAM,aACNa,KAAM,aACNC,WAAW,GAEf,CACId,KAAM,cACNa,KAAM,cACNC,WAAW,GAEf,CACId,KAAM,cACNa,KAAM,cACNC,WAAW,GAEf,CACId,KAAM,YACNa,KAAM,YACNC,WAAW,GAEf,CACId,KAAM,SACNa,KAAM,SACNC,WAAW,GAEf,CACId,KAAM,SACNa,KAAM,SACNC,WAAW,EACXC,YAAY,IAGpBC,MAAO,CAAC,CAAC,EAAG,SACZC,WAAY,GACZC,YAAY,EACZC,UAAU,EACVC,YAAY,KAapB,SAA6BzB,GAEzBlC,EAAE,cAAcY,GAAG,SAAS,WACxBE,QAAQC,IAAI,yBAEZ,IAAM6C,EAAe5D,EAAE,kBAAkBiB,MACnC4C,EAAW7D,EAAE,cAAciB,MAC3B6C,EAAS9D,EAAE,YAAYiB,MAE7BH,QAAQC,IAAI,kBAAmB,CAC3BgD,OAAQH,EACRC,SAAUA,EACVC,OAAQA,IAGZ5B,EAAMG,KAAK2B,QACd,IAGDhE,EAAE,aAAaY,GAAG,SAAS,WACvBE,QAAQC,IAAI,wBAGZf,EAAE,kBAAkBiB,IAAI,MAAMgD,QAAQ,kBAGtCjE,EAAE,cAAcC,WAAW,cAC3BD,EAAE,YAAYC,WAAW,cAGzBe,IAGAkB,EAAMG,KAAK2B,QACd,IAGDhE,EAAE,wBAAwBY,GAAG,YAAY,SAAUC,GAC/B,KAAZA,EAAEqD,OAEFlE,EAAE,cAAcmE,OAEvB,IAGDnE,EAAE,kBAAkBY,GAAG,UAAU,WAC7BE,QAAQC,IAAI,yBAA0Bf,EAAEoE,MAAMnD,MAGjD,GACJ,EA3DGoD,CAAoBnC,GAgExB,SAAiCA,GAE7BA,EAAMtB,GAAG,YAAY,WACjBE,QAAQC,IAAI,iBAAkBmB,EAAMqB,QACvC,IAGDrB,EAAMtB,GAAG,iBAAiB,SAAUC,EAAGyD,EAAUnC,GACzCA,EACArB,QAAQC,IAAI,gCAEZD,QAAQC,IAAI,gCAEnB,GAIJ,CA9EGwD,CAAwBrC,EAC3B,CAvOOsC,EACH,GAAE,MAXC1D,QAAQc,MAAM,4BAYrB,G","sources":["webpack:///./resources/js/warehouse_management/opnames/index.js"],"sourcesContent":["$(document).ready(function () {\n console.log(\"Opnames index.js loaded\");\n\n // Check if required libraries are available\n if (typeof $.fn.DataTable === \"undefined\") {\n console.error(\"DataTables not available!\");\n return;\n }\n\n // Initialize components\n initializeSelect2();\n initializeDatepickers();\n\n // Wait for DOM to be fully ready before initializing DataTable\n setTimeout(function () {\n initializeDataTable();\n }, 100);\n});\n\n/**\n * Initialize Select2 for dealer filter - same as stock audit\n */\nfunction initializeSelect2() {\n console.log(\"Initializing Select2...\");\n\n if (typeof $.fn.select2 !== \"undefined\") {\n $(\"#dealer_filter\").select2({\n placeholder: \"Pilih...\",\n allowClear: true,\n width: \"100%\",\n });\n } else {\n console.warn(\"Select2 not available, using regular select\");\n }\n}\n\n/**\n * Initialize date pickers with bootstrap datepicker - same as transaction view\n */\nfunction initializeDatepickers() {\n console.log(\"Initializing datepickers...\");\n\n // Check if bootstrap datepicker is available\n if (typeof $.fn.datepicker === \"undefined\") {\n console.error(\"Bootstrap Datepicker not available!\");\n return;\n }\n\n // Initialize start date picker\n $(\"#date_from\")\n .datepicker({\n format: \"yyyy-mm-dd\",\n autoclose: true,\n todayHighlight: true,\n orientation: \"bottom left\",\n templates: {\n leftArrow: '',\n rightArrow: '',\n },\n endDate: new Date(), // Don't allow future dates\n clearBtn: true,\n })\n .on(\"changeDate\", function (e) {\n console.log(\"Start date selected:\", e.format());\n enableEndDatePicker(e.format());\n })\n .on(\"clearDate\", function (e) {\n console.log(\"Start date cleared\");\n resetEndDatePicker();\n });\n\n // Initialize end date picker\n initializeEndDatePicker();\n\n // Initially disable end date input\n $(\"#date_to\").prop(\"disabled\", true);\n}\n\n/**\n * Enable end date picker with minimum date constraint\n */\nfunction enableEndDatePicker(startDate) {\n console.log(\"Enabling end date picker with min date:\", startDate);\n\n // Enable the input\n $(\"#date_to\").prop(\"disabled\", false);\n\n // Remove existing datepicker\n $(\"#date_to\").datepicker(\"remove\");\n\n // Re-initialize with new startDate constraint\n $(\"#date_to\")\n .datepicker({\n format: \"yyyy-mm-dd\",\n autoclose: true,\n todayHighlight: true,\n orientation: \"bottom left\",\n templates: {\n leftArrow: '',\n rightArrow: '',\n },\n startDate: startDate, // Set minimum date to selected start date\n endDate: new Date(), // Don't allow future dates\n clearBtn: true,\n })\n .on(\"changeDate\", function (e) {\n console.log(\"End date selected:\", e.format());\n })\n .on(\"clearDate\", function (e) {\n console.log(\"End date cleared\");\n });\n\n console.log(\"End date picker enabled with startDate:\", startDate);\n}\n\n/**\n * Initialize end date picker without constraints\n */\nfunction initializeEndDatePicker() {\n $(\"#date_to\")\n .datepicker({\n format: \"yyyy-mm-dd\",\n autoclose: true,\n todayHighlight: true,\n orientation: \"bottom left\",\n templates: {\n leftArrow: '',\n rightArrow: '',\n },\n endDate: new Date(), // Don't allow future dates\n clearBtn: true,\n })\n .on(\"changeDate\", function (e) {\n console.log(\"End date selected:\", e.format());\n })\n .on(\"clearDate\", function (e) {\n console.log(\"End date cleared\");\n });\n}\n\n/**\n * Reset end date picker to initial state\n */\nfunction resetEndDatePicker() {\n // Remove existing datepicker\n $(\"#date_to\").datepicker(\"remove\");\n\n // Clear the input value\n $(\"#date_to\").val(\"\");\n\n // Re-initialize without startDate constraint\n initializeEndDatePicker();\n\n // Disable the input\n $(\"#date_to\").prop(\"disabled\", true);\n\n console.log(\"End date picker reset and disabled\");\n}\n\n/**\n * Initialize DataTable with server-side processing and filtering\n */\nfunction initializeDataTable() {\n console.log(\"Initializing DataTable...\");\n\n // Destroy existing table if any\n if ($.fn.DataTable.isDataTable(\"#opnames-table\")) {\n $(\"#opnames-table\").DataTable().destroy();\n }\n\n // Initialize DataTable\n const table = $(\"#opnames-table\").DataTable({\n processing: true,\n serverSide: true,\n destroy: true,\n ajax: {\n url: $(\"#opnames-table\").data(\"url\"),\n type: \"GET\",\n data: function (d) {\n // Add filter parameters\n d.dealer_filter = $(\"#dealer_filter\").val();\n d.date_from = $(\"#date_from\").val();\n d.date_to = $(\"#date_to\").val();\n\n console.log(\"AJAX data being sent:\", {\n dealer_filter: d.dealer_filter,\n date_from: d.date_from,\n date_to: d.date_to,\n });\n\n return d;\n },\n error: function (xhr, error, code) {\n console.error(\"DataTables AJAX error:\", error, code);\n console.error(\"Response:\", xhr.responseText);\n },\n },\n columnDefs: [\n { targets: 0, width: \"15%\" }, // Opname Date column\n { targets: 5, width: \"15%\", className: \"text-center\" }, // Action column\n ],\n columns: [\n {\n data: \"created_at\",\n name: \"created_at\",\n orderable: true,\n },\n {\n data: \"opname_date\",\n name: \"opname_date\",\n orderable: true,\n },\n {\n data: \"dealer_name\",\n name: \"dealer.name\",\n orderable: true,\n },\n {\n data: \"user_name\",\n name: \"user.name\",\n orderable: true,\n },\n {\n data: \"status\",\n name: \"status\",\n orderable: true,\n },\n {\n data: \"action\",\n name: \"action\",\n orderable: false,\n searchable: false,\n },\n ],\n order: [[4, \"desc\"]], // Order by created_at desc\n pageLength: 10,\n responsive: true,\n ordering: true,\n orderMulti: false,\n });\n\n // Setup filter button handlers\n setupFilterHandlers(table);\n\n // Setup other event handlers\n setupTableEventHandlers(table);\n}\n\n/**\n * Setup filter and reset button handlers\n */\nfunction setupFilterHandlers(table) {\n // Handle Filter Search Button\n $(\"#kt_search\").on(\"click\", function () {\n console.log(\"Filter button clicked\");\n\n const dealerFilter = $(\"#dealer_filter\").val();\n const dateFrom = $(\"#date_from\").val();\n const dateTo = $(\"#date_to\").val();\n\n console.log(\"Filtering with:\", {\n dealer: dealerFilter,\n dateFrom: dateFrom,\n dateTo: dateTo,\n });\n\n table.ajax.reload();\n });\n\n // Handle Filter Reset Button\n $(\"#kt_reset\").on(\"click\", function () {\n console.log(\"Reset button clicked\");\n\n // Reset select2 elements properly - same as stock audit\n $(\"#dealer_filter\").val(null).trigger(\"change.select2\");\n\n // Clear datepicker values using bootstrap datepicker method\n $(\"#date_from\").datepicker(\"clearDates\");\n $(\"#date_to\").datepicker(\"clearDates\");\n\n // Reset end date picker and disable it\n resetEndDatePicker();\n\n // Reload table\n table.ajax.reload();\n });\n\n // Handle Enter key on date inputs\n $(\"#date_from, #date_to\").on(\"keypress\", function (e) {\n if (e.which === 13) {\n // Enter key\n $(\"#kt_search\").click();\n }\n });\n\n // Optional: Auto-filter when dealer selection changes\n $(\"#dealer_filter\").on(\"change\", function () {\n console.log(\"Dealer filter changed:\", $(this).val());\n // Uncomment the line below if you want auto-filter on dealer change\n // table.ajax.reload();\n });\n}\n\n/**\n * Setup additional table event handlers\n */\nfunction setupTableEventHandlers(table) {\n // Debug ordering events\n table.on(\"order.dt\", function () {\n console.log(\"Order changed:\", table.order());\n });\n\n // Add loading indicator for processing\n table.on(\"processing.dt\", function (e, settings, processing) {\n if (processing) {\n console.log(\"DataTable processing started\");\n } else {\n console.log(\"DataTable processing finished\");\n }\n });\n\n // Handle any custom button clicks here if needed\n // Example: $(document).on('click', '.custom-btn', function() { ... });\n}\n"],"names":["initializeEndDatePicker","$","datepicker","format","autoclose","todayHighlight","orientation","templates","leftArrow","rightArrow","endDate","Date","clearBtn","on","e","console","log","resetEndDatePicker","val","prop","document","ready","fn","DataTable","select2","placeholder","allowClear","width","warn","error","startDate","initializeDatepickers","setTimeout","isDataTable","destroy","table","processing","serverSide","ajax","url","data","type","d","dealer_filter","date_from","date_to","xhr","code","responseText","columnDefs","targets","className","columns","name","orderable","searchable","order","pageLength","responsive","ordering","orderMulti","dealerFilter","dateFrom","dateTo","dealer","reload","trigger","which","click","this","setupFilterHandlers","settings","setupTableEventHandlers","initializeDataTable"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"file":"/js/warehouse_management/opnames/index.js","mappings":"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","sources":["webpack:///./resources/js/warehouse_management/opnames/index.js"],"sourcesContent":["$(document).ready(function () {\n console.log(\"Opnames index.js loaded\");\n\n // Check if required libraries are available\n if (typeof $.fn.DataTable === \"undefined\") {\n console.error(\"DataTables not available!\");\n return;\n }\n\n // Initialize components\n initializeSelect2();\n initializeDatepickers();\n\n // Wait for DOM to be fully ready before initializing DataTable\n setTimeout(function () {\n initializeDataTable();\n }, 100);\n});\n\n/**\n * Initialize Select2 for dealer filter - same as stock audit\n */\nfunction initializeSelect2() {\n console.log(\"Initializing Select2...\");\n\n if (typeof $.fn.select2 !== \"undefined\") {\n $(\"#dealer_filter\").select2({\n placeholder: \"Pilih...\",\n allowClear: true,\n width: \"100%\",\n });\n } else {\n console.warn(\"Select2 not available, using regular select\");\n }\n}\n\n/**\n * Initialize date pickers with bootstrap datepicker - same as transaction view\n */\nfunction initializeDatepickers() {\n console.log(\"Initializing datepickers...\");\n\n // Check if bootstrap datepicker is available\n if (typeof $.fn.datepicker === \"undefined\") {\n console.error(\"Bootstrap Datepicker not available!\");\n return;\n }\n\n // Initialize start date picker\n $(\"#date_from\")\n .datepicker({\n format: \"yyyy-mm-dd\",\n autoclose: true,\n todayHighlight: true,\n orientation: \"bottom left\",\n templates: {\n leftArrow: '',\n rightArrow: '',\n },\n endDate: new Date(), // Don't allow future dates\n clearBtn: true,\n })\n .on(\"changeDate\", function (e) {\n console.log(\"Start date selected:\", e.format());\n enableEndDatePicker(e.format());\n })\n .on(\"clearDate\", function (e) {\n console.log(\"Start date cleared\");\n resetEndDatePicker();\n });\n\n // Initialize end date picker\n initializeEndDatePicker();\n\n // Initially disable end date input\n $(\"#date_to\").prop(\"disabled\", true);\n}\n\n/**\n * Enable end date picker with minimum date constraint\n */\nfunction enableEndDatePicker(startDate) {\n console.log(\"Enabling end date picker with min date:\", startDate);\n\n // Enable the input\n $(\"#date_to\").prop(\"disabled\", false);\n\n // Remove existing datepicker\n $(\"#date_to\").datepicker(\"remove\");\n\n // Re-initialize with new startDate constraint\n $(\"#date_to\")\n .datepicker({\n format: \"yyyy-mm-dd\",\n autoclose: true,\n todayHighlight: true,\n orientation: \"bottom left\",\n templates: {\n leftArrow: '',\n rightArrow: '',\n },\n startDate: startDate, // Set minimum date to selected start date\n endDate: new Date(), // Don't allow future dates\n clearBtn: true,\n })\n .on(\"changeDate\", function (e) {\n console.log(\"End date selected:\", e.format());\n })\n .on(\"clearDate\", function (e) {\n console.log(\"End date cleared\");\n });\n\n console.log(\"End date picker enabled with startDate:\", startDate);\n}\n\n/**\n * Initialize end date picker without constraints\n */\nfunction initializeEndDatePicker() {\n $(\"#date_to\")\n .datepicker({\n format: \"yyyy-mm-dd\",\n autoclose: true,\n todayHighlight: true,\n orientation: \"bottom left\",\n templates: {\n leftArrow: '',\n rightArrow: '',\n },\n endDate: new Date(), // Don't allow future dates\n clearBtn: true,\n })\n .on(\"changeDate\", function (e) {\n console.log(\"End date selected:\", e.format());\n })\n .on(\"clearDate\", function (e) {\n console.log(\"End date cleared\");\n });\n}\n\n/**\n * Reset end date picker to initial state\n */\nfunction resetEndDatePicker() {\n // Remove existing datepicker\n $(\"#date_to\").datepicker(\"remove\");\n\n // Clear the input value\n $(\"#date_to\").val(\"\");\n\n // Re-initialize without startDate constraint\n initializeEndDatePicker();\n\n // Disable the input\n $(\"#date_to\").prop(\"disabled\", true);\n\n console.log(\"End date picker reset and disabled\");\n}\n\n/**\n * Initialize DataTable with server-side processing and filtering\n */\nfunction initializeDataTable() {\n console.log(\"Initializing DataTable...\");\n\n // Destroy existing table if any\n if ($.fn.DataTable.isDataTable(\"#opnames-table\")) {\n $(\"#opnames-table\").DataTable().destroy();\n }\n\n // Initialize DataTable\n const table = $(\"#opnames-table\").DataTable({\n processing: true,\n serverSide: true,\n destroy: true,\n ajax: {\n url: $(\"#opnames-table\").data(\"url\"),\n type: \"GET\",\n data: function (d) {\n // Add filter parameters\n d.dealer_filter = $(\"#dealer_filter\").val();\n d.date_from = $(\"#date_from\").val();\n d.date_to = $(\"#date_to\").val();\n\n console.log(\"AJAX data being sent:\", {\n dealer_filter: d.dealer_filter,\n date_from: d.date_from,\n date_to: d.date_to,\n });\n\n return d;\n },\n error: function (xhr, error, code) {\n console.error(\"DataTables AJAX error:\", error, code);\n console.error(\"Response:\", xhr.responseText);\n },\n },\n columnDefs: [\n { targets: 0, width: \"15%\" }, // Created At column\n { targets: 1, width: \"12%\" }, // Opname Date column\n { targets: 2, width: \"15%\" }, // Dealer column\n { targets: 3, width: \"12%\" }, // User column\n { targets: 4, width: \"10%\" }, // Status column\n { targets: 5, width: \"15%\", className: \"text-center\" }, // Stock Info column\n { targets: 6, width: \"15%\", className: \"text-center\" }, // Action column\n ],\n columns: [\n {\n data: \"created_at\",\n name: \"created_at\",\n orderable: true,\n },\n {\n data: \"opname_date\",\n name: \"opname_date\",\n orderable: true,\n },\n {\n data: \"dealer_name\",\n name: \"dealer.name\",\n orderable: true,\n },\n {\n data: \"user_name\",\n name: \"user.name\",\n orderable: true,\n },\n {\n data: \"status\",\n name: \"status\",\n orderable: true,\n },\n {\n data: \"stock_info\",\n name: \"stock_info\",\n orderable: false,\n searchable: false,\n },\n {\n data: \"action\",\n name: \"action\",\n orderable: false,\n searchable: false,\n },\n ],\n order: [[0, \"desc\"]], // Order by created_at desc\n pageLength: 10,\n responsive: true,\n ordering: true,\n orderMulti: false,\n });\n\n // Setup filter button handlers\n setupFilterHandlers(table);\n\n // Setup other event handlers\n setupTableEventHandlers(table);\n}\n\n/**\n * Setup filter and reset button handlers\n */\nfunction setupFilterHandlers(table) {\n // Handle Filter Search Button\n $(\"#kt_search\").on(\"click\", function () {\n console.log(\"Filter button clicked\");\n\n const dealerFilter = $(\"#dealer_filter\").val();\n const dateFrom = $(\"#date_from\").val();\n const dateTo = $(\"#date_to\").val();\n\n console.log(\"Filtering with:\", {\n dealer: dealerFilter,\n dateFrom: dateFrom,\n dateTo: dateTo,\n });\n\n table.ajax.reload();\n });\n\n // Handle Filter Reset Button\n $(\"#kt_reset\").on(\"click\", function () {\n console.log(\"Reset button clicked\");\n\n // Reset select2 elements properly - same as stock audit\n $(\"#dealer_filter\").val(null).trigger(\"change.select2\");\n\n // Clear datepicker values using bootstrap datepicker method\n $(\"#date_from\").datepicker(\"clearDates\");\n $(\"#date_to\").datepicker(\"clearDates\");\n\n // Reset end date picker and disable it\n resetEndDatePicker();\n\n // Reload table\n table.ajax.reload();\n });\n\n // Handle Enter key on date inputs\n $(\"#date_from, #date_to\").on(\"keypress\", function (e) {\n if (e.which === 13) {\n // Enter key\n $(\"#kt_search\").click();\n }\n });\n\n // Optional: Auto-filter when dealer selection changes\n $(\"#dealer_filter\").on(\"change\", function () {\n console.log(\"Dealer filter changed:\", $(this).val());\n // Uncomment the line below if you want auto-filter on dealer change\n // table.ajax.reload();\n });\n}\n\n/**\n * Setup additional table event handlers\n */\nfunction setupTableEventHandlers(table) {\n // Debug ordering events\n table.on(\"order.dt\", function () {\n console.log(\"Order changed:\", table.order());\n });\n\n // Add loading indicator for processing\n table.on(\"processing.dt\", function (e, settings, processing) {\n if (processing) {\n console.log(\"DataTable processing started\");\n } else {\n console.log(\"DataTable processing finished\");\n }\n });\n\n // Handle any custom button clicks here if needed\n // Example: $(document).on('click', '.custom-btn', function() { ... });\n}\n"],"names":["initializeEndDatePicker","$","datepicker","format","autoclose","todayHighlight","orientation","templates","leftArrow","rightArrow","endDate","Date","clearBtn","on","e","console","log","resetEndDatePicker","val","prop","document","ready","fn","DataTable","select2","placeholder","allowClear","width","warn","error","startDate","initializeDatepickers","setTimeout","isDataTable","destroy","table","processing","serverSide","ajax","url","data","type","d","dealer_filter","date_from","date_to","xhr","code","responseText","columnDefs","targets","className","columns","name","orderable","searchable","order","pageLength","responsive","ordering","orderMulti","dealerFilter","dateFrom","dateTo","dealer","reload","trigger","which","click","this","setupFilterHandlers","settings","setupTableEventHandlers","initializeDataTable"],"sourceRoot":""}
\ No newline at end of file
diff --git a/resources/js/warehouse_management/opnames/index.js b/resources/js/warehouse_management/opnames/index.js
index 2cf7cff..038604f 100755
--- a/resources/js/warehouse_management/opnames/index.js
+++ b/resources/js/warehouse_management/opnames/index.js
@@ -196,8 +196,13 @@ function initializeDataTable() {
},
},
columnDefs: [
- { targets: 0, width: "15%" }, // Opname Date column
- { targets: 5, width: "15%", className: "text-center" }, // Action column
+ { targets: 0, width: "15%" }, // Created At column
+ { targets: 1, width: "12%" }, // Opname Date column
+ { targets: 2, width: "15%" }, // Dealer column
+ { targets: 3, width: "12%" }, // User column
+ { targets: 4, width: "10%" }, // Status column
+ { targets: 5, width: "15%", className: "text-center" }, // Stock Info column
+ { targets: 6, width: "15%", className: "text-center" }, // Action column
],
columns: [
{
@@ -225,6 +230,12 @@ function initializeDataTable() {
name: "status",
orderable: true,
},
+ {
+ data: "stock_info",
+ name: "stock_info",
+ orderable: false,
+ searchable: false,
+ },
{
data: "action",
name: "action",
@@ -232,7 +243,7 @@ function initializeDataTable() {
searchable: false,
},
],
- order: [[4, "desc"]], // Order by created_at desc
+ order: [[0, "desc"]], // Order by created_at desc
pageLength: 10,
responsive: true,
ordering: true,
diff --git a/resources/views/transaction/index.blade.php b/resources/views/transaction/index.blade.php
index 21aa96d..3fc6922 100755
--- a/resources/views/transaction/index.blade.php
+++ b/resources/views/transaction/index.blade.php
@@ -739,22 +739,12 @@ use Illuminate\Support\Facades\Auth;
-
- @error('opname_date')
-
- {{ $message }}
-
- @enderror
+
-
-
- @error('description')
-
- {{ $message }}
-
- @enderror
+
+
@@ -764,9 +754,7 @@ use Illuminate\Support\Facades\Auth;
Produk
Dealer
-
Stock Sistem
Stock Fisik
-
Selisih
@@ -779,22 +767,11 @@ use Illuminate\Support\Facades\Auth;
{{ $product->name }}
{{ $mechanic->dealer_name }}
-
- {{ number_format($currentStock, 2) }}
+
-
-
-
- @error('physical_stock.'.$loop->index)
-
- {{ $message }}
-
- @enderror
-
-
- 0.00
+
@endforeach
@@ -806,6 +783,10 @@ use Illuminate\Support\Facades\Auth;
+
+
+ Stock fisik yang kosong akan otomatis diisi dengan 0
+
@@ -1353,49 +1334,39 @@ use Illuminate\Support\Facades\Auth;
// Save current tab to localStorage
localStorage.setItem('activeTab', '#opname');
- // Validate form
+ // Set default values for empty fields and validate
var hasValidStock = false;
- var invalidRows = [];
$('.physical-stock').each(function(index) {
var value = $(this).val();
- var row = $(this).closest('tr');
- var productName = row.find('td:first').text().trim();
- // Check if value is valid (including 0)
- if (value !== '' && value !== null && value !== undefined) {
- var numValue = parseFloat(value);
- if (!isNaN(numValue) && numValue >= 0) {
- hasValidStock = true;
- // Ensure the value is properly formatted
- $(this).val(numValue.toFixed(2));
- } else {
- invalidRows.push(productName + ' (nilai tidak valid)');
- }
+ // Set default value to 0 if empty
+ if (value === '' || value === null || value === undefined) {
+ $(this).val('0.00');
+ value = '0.00';
+ }
+
+ // Validate and format the value
+ var numValue = parseFloat(value);
+ if (!isNaN(numValue) && numValue >= 0) {
+ hasValidStock = true;
+ // Ensure the value is properly formatted
+ $(this).val(numValue.toFixed(2));
+ } else {
+ // If invalid, set to 0
+ $(this).val('0.00');
+ hasValidStock = true; // Still consider valid since we set default
}
- // Don't remove elements here - let them stay for re-editing
});
- // Show error if no valid stock entries
+ // Always allow submission since we set defaults
if (!hasValidStock) {
+ // This should never happen now, but just in case
resetSubmitButton();
- highlightInvalidFields();
Swal.fire({
icon: 'warning',
title: 'Peringatan',
- text: 'Minimal harus ada satu produk dengan stock fisik yang diisi dengan benar!'
- });
- return false;
- }
-
- // Show error if there are invalid entries
- if (invalidRows.length > 0) {
- resetSubmitButton();
- highlightInvalidFields();
- Swal.fire({
- icon: 'warning',
- title: 'Data Tidak Valid',
- text: 'Perbaiki data berikut: ' + invalidRows.join(', ')
+ text: 'Terjadi kesalahan dalam validasi data. Silakan coba lagi.'
});
return false;
}
@@ -1457,21 +1428,6 @@ use Illuminate\Support\Facades\Auth;
// Date format is already YYYY-MM-DD, no conversion needed
- // Clean up empty rows before submit (remove hidden inputs for truly empty fields only)
- $('.physical-stock').each(function() {
- var value = $(this).val();
- var row = $(this).closest('tr');
-
- // Only remove hidden inputs if physical stock is truly empty (not 0)
- // Keep 0 values as they are valid input
- if (value === '' || value === null || value === undefined) {
- row.find('input[name="product_id[]"]').remove();
- row.find('input[name="dealer_id_stock[]"]').remove();
- row.find('input[name="system_stock[]"]').remove();
- // But keep the physical_stock input so it can be re-edited if form fails
- }
- });
-
// Submit form
this.submit();
})
@@ -1690,31 +1646,34 @@ use Illuminate\Support\Facades\Auth;
// Function to update product counter
function updateProductCounter() {
- var filledProducts = 0;
var totalProducts = $('.physical-stock').length;
- $('.physical-stock').each(function() {
- var value = $(this).val();
- // Count as filled if it's a valid number (including 0)
- if (value !== '' && value !== null && value !== undefined && !isNaN(parseFloat(value)) && parseFloat(value) >= 0) {
- filledProducts++;
- }
- });
-
- // Update button text to show progress
+ // Update button text to show total products
var buttonText = 'Simpan Opname';
- if (filledProducts > 0) {
- buttonText += ` (${filledProducts}/${totalProducts} produk)`;
- }
+ buttonText += ` (${totalProducts} produk)`;
if (!$('#btn-save-opname').hasClass('disabled')) {
$('#btn-save-opname').html(buttonText);
}
}
- // Handle when input loses focus - don't auto-fill, let user decide
+ // Initialize default values for physical stock inputs
+ $(document).ready(function() {
+ $('.physical-stock').each(function() {
+ var value = $(this).val();
+ if (value === '' || value === null || value === undefined) {
+ $(this).val('0.00');
+ }
+ });
+ });
+
+ // Handle when input loses focus - set default if empty
$(document).on('blur', '.physical-stock', function() {
- // Trigger calculation even for empty values
+ var value = $(this).val();
+ if (value === '' || value === null || value === undefined) {
+ $(this).val('0.00');
+ }
+ // Trigger calculation
$(this).trigger('input');
});
@@ -1725,28 +1684,12 @@ use Illuminate\Support\Facades\Auth;
updateProductCounter(); // Update with current counter
}
- // Function to show field error highlighting
- function highlightInvalidFields() {
- $('.physical-stock').each(function() {
- var value = $(this).val();
- var $input = $(this);
-
- if (value !== '' && value !== null && value !== undefined) {
- var numValue = parseFloat(value);
- if (isNaN(numValue) || numValue < 0) {
- $input.addClass('is-invalid');
- } else {
- $input.removeClass('is-invalid');
- }
- } else {
- $input.removeClass('is-invalid');
- }
- });
- }
-
- // Remove error styling when user starts typing
- $(document).on('input', '.physical-stock', function() {
- $(this).removeClass('is-invalid');
+ // Set default values when user leaves field empty
+ $(document).on('blur', '.physical-stock', function() {
+ var value = $(this).val();
+ if (value === '' || value === null || value === undefined) {
+ $(this).val('0.00');
+ }
});
// Remove invalid styling when user starts typing in required fields
@@ -1779,6 +1722,9 @@ use Illuminate\Support\Facades\Auth;
$('#date-opname').val(today);
}
+ // Initialize opname form
+ updateProductCounter();
+
// Initialize mutasi form
updateRemoveButtonsMutasi();
@@ -1935,7 +1881,10 @@ use Illuminate\Support\Facades\Auth;
} else if (successMessage.toLowerCase().includes('opname') || activeTab === 'opname') {
// Reset opname form after success
$('#opnameForm')[0].reset();
- $('.physical-stock').val('').removeClass('is-invalid');
+ // Set default values for physical stock inputs
+ $('.physical-stock').each(function() {
+ $(this).val('0.00');
+ });
$('.difference').text('0.00').removeClass('text-success text-danger');
$("#btn-save-opname").attr("disabled", false);
$("#btn-save-opname").removeClass("disabled");
@@ -1963,6 +1912,12 @@ use Illuminate\Support\Facades\Auth;
$("#btn-save-opname").attr("disabled", false);
$("#btn-save-opname").removeClass("disabled");
$("#btn-save-opname").html('Simpan Opname');
+ // Set default values for physical stock inputs
+ $('.physical-stock').each(function() {
+ if ($(this).val() === '' || $(this).val() === null || $(this).val() === undefined) {
+ $(this).val('0.00');
+ }
+ });
} else if (activeTab === 'mutasi') {
// Reset button states for mutasi form
$("#btn-save-mutasi").attr("disabled", false);
diff --git a/resources/views/warehouse_management/mutations/print.blade.php b/resources/views/warehouse_management/mutations/print.blade.php
index 9d9c9c1..60c28d3 100644
--- a/resources/views/warehouse_management/mutations/print.blade.php
+++ b/resources/views/warehouse_management/mutations/print.blade.php
@@ -327,7 +327,7 @@