add more seeder product and product category and fix daterangepicker

This commit is contained in:
2025-06-25 16:29:34 +07:00
parent e96ca0a83c
commit e5daafc8f0
17 changed files with 334 additions and 319 deletions

View File

@@ -440,23 +440,26 @@ class ReportController extends Controller
$data->orderBy('date', 'DESC'); $data->orderBy('date', 'DESC');
return DataTables::of($data)->addIndexColumn() return DataTables::of($data)->addIndexColumn()
->addColumn('action', function($row) use ($menu) { ->addColumn('action', function($row) use ($menu) {
$btn = ''; $btn = '<div class="d-flex justify-content-center">';
if($row->status == 1) { if($row->status == 1) {
if(Auth::user()->can('delete', $menu)) { if(Gate::allows('delete', $menu)) {
$btn .= ' <button class="btn btn-danger btn-sm btn-bold" data-action="'. route('report.transaction.destroy', $row->id) .'" id="destroyTransaction'. $row->id .'" onclick="destroyTransaction('. $row->id .')"> Hapus </button>'; $btn .= ' <button class="btn btn-danger btn-sm btn-bold mr-2" data-action="'. route('report.transaction.destroy', $row->id) .'" id="destroyTransaction'. $row->id .'" onclick="destroyTransaction('. $row->id .')"> Hapus </button>';
} }
$btn .= '<span class="badge badge-success">Closed</span>'; $btn .= '<span class="badge badge-success">Closed</span>';
}else{ }else{
if(Auth::user()->can('delete', $menu)) { if(Gate::allows('delete', $menu)) {
$btn .= '<button class="btn btn-danger btn-sm btn-bold" data-action="'. route('report.transaction.destroy', $row->id) .'" id="destroyTransaction'. $row->id .'" onclick="destroyTransaction('. $row->id .')"> Hapus </button>'; $btn .= '<button class="btn btn-danger btn-sm btn-bold mr-2" data-action="'. route('report.transaction.destroy', $row->id) .'" id="destroyTransaction'. $row->id .'" onclick="destroyTransaction('. $row->id .')"> Hapus </button>';
} }
if(Auth::user()->can('update', $menu)) { if(Gate::allows('update', $menu)) {
$btn .= '<button class="btn btn-info btn-sm btn-bold" data-url="'. route('report.transaction.edit', $row->id) .'" data-action="'. route('report.transaction.update', $row->id) .'" onclick="editTransaction('. $row->id .')" id="editTransaction'. $row->id .'"> Edit </button> $btn .= '<button class="btn btn-info btn-sm btn-bold mr-2" data-url="'. route('report.transaction.edit', $row->id) .'" data-action="'. route('report.transaction.update', $row->id) .'" onclick="editTransaction('. $row->id .')" id="editTransaction'. $row->id .'"> Edit </button>
<button class="btn btn-warning btn-sm btn-bold" id="closeTransaction'. $row->id .'" data-url="'. route('report.transaction.close', $row->id) .'" onclick="closeTransaction('. $row->id .')"> Close </button>'; <button class="btn btn-warning btn-sm btn-bold" id="closeTransaction'. $row->id .'" data-url="'. route('report.transaction.close', $row->id) .'" onclick="closeTransaction('. $row->id .')"> Close </button>';
} }
} }
$btn .= '</div>';
return $btn; return $btn;
}) })
->rawColumns(['action']) ->rawColumns(['action'])

View File

@@ -12,12 +12,14 @@ use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Yajra\DataTables\DataTables; use Yajra\DataTables\DataTables;
use Illuminate\Support\Facades\Gate;
class MutationsController extends Controller class MutationsController extends Controller
{ {
public function index(Request $request) public function index(Request $request)
{ {
$menu = Menu::where('link','mutations.index')->first(); $menu = Menu::where('link','mutations.index')->first();
abort_if(!Gate::allows('view', $menu), 403);
$dealers = Dealer::all(); $dealers = Dealer::all();
if ($request->ajax()) { if ($request->ajax()) {

View File

@@ -17,11 +17,13 @@ use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Yajra\DataTables\Facades\DataTables; use Yajra\DataTables\Facades\DataTables;
use Illuminate\Support\Facades\Gate;
class OpnamesController extends Controller class OpnamesController extends Controller
{ {
public function index(Request $request){ public function index(Request $request){
$menu = Menu::where('link','opnames.index')->first(); $menu = Menu::where('link','opnames.index')->first();
abort_if(!Gate::allows('view', $menu), 403);
$dealers = Dealer::all(); $dealers = Dealer::all();
if($request->ajax()){ if($request->ajax()){
$data = Opname::query() $data = Opname::query()

View File

@@ -9,6 +9,7 @@ use Carbon\Carbon;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Yajra\DataTables\Facades\DataTables; use Yajra\DataTables\Facades\DataTables;
use Illuminate\Support\Facades\Gate;
class ProductCategoriesController extends Controller class ProductCategoriesController extends Controller
{ {
@@ -20,6 +21,7 @@ class ProductCategoriesController extends Controller
public function index(Request $request) public function index(Request $request)
{ {
$menu = Menu::where('link','product_categories.index')->first(); $menu = Menu::where('link','product_categories.index')->first();
abort_if(!Gate::allows('view', $menu), 403);
if($request->ajax()){ if($request->ajax()){
$data = ProductCategory::query(); $data = ProductCategory::query();
return DataTables::of($data) return DataTables::of($data)
@@ -30,11 +32,11 @@ class ProductCategoriesController extends Controller
->addColumn('action', function ($row) use ($menu) { ->addColumn('action', function ($row) use ($menu) {
$btn = ''; $btn = '';
if (Auth::user()->can('delete', $menu)) { if (Gate::allows('delete', $menu)) {
$btn .= '<button style="margin-right: 8px;" class="btn btn-danger btn-sm btn-destroy-product-category" data-action="' . route('product_categories.destroy', $row->id) . '" data-id="' . $row->id . '">Hapus</button>'; $btn .= '<button style="margin-right: 8px;" class="btn btn-danger btn-sm btn-destroy-product-category" data-action="' . route('product_categories.destroy', $row->id) . '" data-id="' . $row->id . '">Hapus</button>';
} }
if (Auth::user()->can('update', $menu)) { if (Gate::allows('update', $menu)) {
$btn .= '<button class="btn btn-warning btn-sm btn-edit-product-category" data-url="' . route('product_categories.edit', $row->id) . '" data-action="' . route('product_categories.update', $row->id) . '" data-id="' . $row->id . '">Edit</button>'; $btn .= '<button class="btn btn-warning btn-sm btn-edit-product-category" data-url="' . route('product_categories.edit', $row->id) . '" data-action="' . route('product_categories.update', $row->id) . '" data-id="' . $row->id . '">Edit</button>';
} }

View File

@@ -28,6 +28,7 @@ class ProductsController extends Controller
public function index(Request $request) public function index(Request $request)
{ {
$menu = Menu::where('link','products.index')->first(); $menu = Menu::where('link','products.index')->first();
abort_if(!Gate::allows('view', $menu), 403);
if($request->ajax()){ if($request->ajax()){
Log::info('Products DataTables request received'); Log::info('Products DataTables request received');
Log::info('Request parameters:', $request->all()); Log::info('Request parameters:', $request->all());

View File

@@ -10,12 +10,14 @@ use App\Models\Product;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Yajra\DataTables\DataTables; use Yajra\DataTables\DataTables;
use Illuminate\Support\Facades\Gate;
class StockAuditController extends Controller class StockAuditController extends Controller
{ {
public function index(Request $request) public function index(Request $request)
{ {
$menu = Menu::where('link', 'stock-audit.index')->first(); $menu = Menu::where('link', 'stock-audit.index')->first();
abort_if(!Gate::allows('view', $menu), 403);
$dealers = Dealer::all(); $dealers = Dealer::all();
$products = Product::all(); $products = Product::all();

View File

@@ -16,17 +16,42 @@ class ProductAndCategorySeeder extends Seeder
public function run() public function run()
{ {
$categories = [ $categories = [
// Oli & Pelumas
'Oli & Pelumas' => [ 'Oli & Pelumas' => [
['code' => 'OLI001', 'name' => 'Oli Mesin 10W-40', 'subcategory' => 'Oli Mesin'], ['code' => 'OLI001', 'name' => 'Oli Mesin 10W-40', 'subcategory' => 'Oli Mesin', 'unit' => 'liter'],
['code' => 'OLI002', 'name' => 'Oli Gardan', 'subcategory' => 'Oli Gardan'], ['code' => 'OLI002', 'name' => 'Oli Mesin 20W-50', 'subcategory' => 'Oli Mesin', 'unit' => 'liter'],
['code' => 'OLI003', 'name' => 'Oli Gardan SAE 90', 'subcategory' => 'Oli Gardan', 'unit' => 'liter'],
['code' => 'OLI004', 'name' => 'Minyak Rem DOT 3', 'subcategory' => 'Minyak Rem', 'unit' => 'ml'],
['code' => 'OLI005', 'name' => 'Grease Serbaguna', 'subcategory' => 'Pelumas Lain', 'unit' => 'gram'],
], ],
// Aki & Kelistrikan
'Aki & Kelistrikan' => [ 'Aki & Kelistrikan' => [
['code' => 'AKI001', 'name' => 'Aki Kering 12V', 'subcategory' => 'Aki'], ['code' => 'AKI001', 'name' => 'Aki Kering 12V 5Ah', 'subcategory' => 'Aki', 'unit' => 'pcs'],
['code' => 'AKI002', 'name' => 'Regulator Rectifier', 'subcategory' => 'Kelistrikan'], ['code' => 'AKI002', 'name' => 'Aki Basah 12V 7Ah', 'subcategory' => 'Aki', 'unit' => 'pcs'],
['code' => 'AKI003', 'name' => 'Lampu LED Headlight', 'subcategory' => 'Lampu', 'unit' => 'pcs'],
['code' => 'AKI004', 'name' => 'Sekring 10A', 'subcategory' => 'Kelistrikan', 'unit' => 'pcs'],
['code' => 'AKI005', 'name' => 'Regulator Rectifier', 'subcategory' => 'Kelistrikan', 'unit' => 'pcs'],
], ],
// Rem
'Rem' => [ 'Rem' => [
['code' => 'REM001', 'name' => 'Kampas Rem Belakang', 'subcategory' => 'Kampas Rem'], ['code' => 'REM001', 'name' => 'Kampas Rem Depan Motor', 'subcategory' => 'Kampas Rem', 'unit' => 'set'],
['code' => 'REM002', 'name' => 'Cakram Depan', 'subcategory' => 'Cakram'], ['code' => 'REM002', 'name' => 'Kampas Rem Belakang Motor', 'subcategory' => 'Kampas Rem', 'unit' => 'set'],
['code' => 'REM003', 'name' => 'Cakram Rem Depan Mobil', 'subcategory' => 'Cakram', 'unit' => 'pcs'],
['code' => 'REM004', 'name' => 'Minyak Rem DOT 4', 'subcategory' => 'Minyak Rem', 'unit' => 'ml'],
['code' => 'REM005', 'name' => 'Master Rem Depan', 'subcategory' => 'Master Rem', 'unit' => 'pcs'],
],
// Cuci Kendaraan & Perawatan
'Cuci Kendaraan' => [
['code' => 'CUCI001', 'name' => 'Shampoo Mobil PH Netral', 'subcategory' => 'Shampoo', 'unit' => 'liter'],
['code' => 'CUCI002', 'name' => 'Sabun Cuci Motor Anti Karat', 'subcategory' => 'Shampoo', 'unit' => 'liter'],
['code' => 'CUCI006', 'name' => 'Semir Ban Botol 500ml', 'subcategory' => 'Perawatan Eksterior', 'unit' => 'ml'],
['code' => 'CUCI007', 'name' => 'Snow Foam Cuci Mobil', 'subcategory' => 'Shampoo', 'unit' => 'liter'],
['code' => 'CUCI008', 'name' => 'Pembersih Interior Dashboard', 'subcategory' => 'Perawatan Interior', 'unit' => 'ml'],
['code' => 'CUCI009', 'name' => 'Wax Body Mobil', 'subcategory' => 'Perawatan Eksterior', 'unit' => 'ml'],
['code' => 'CUCI010', 'name' => 'Pembersih Kaca Anti Jamur', 'subcategory' => 'Perawatan Kaca', 'unit' => 'ml'],
], ],
]; ];
@@ -50,7 +75,8 @@ class ProductAndCategorySeeder extends Seeder
[ [
'name' => $product['name'], 'name' => $product['name'],
'description' => $product['name'], 'description' => $product['name'],
'product_category_id' => $child->id 'product_category_id' => $child->id,
'unit' => $product['unit'],
] ]
); );
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +1,2 @@
(()=>{function e(e){console.log("Enabling end date picker with min date:",e),$("#date_to").prop("disabled",!1),$("#date_to").datepicker("remove"),$("#date_to").datepicker({format:"yyyy-mm-dd",autoclose:!0,todayHighlight:!0,orientation:"bottom auto",language:"id",clearBtn:!0,container:"body",startDate:e,endDate:new Date}).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:",e)}function a(){$("#date_to").datepicker({format:"yyyy-mm-dd",autoclose:!0,todayHighlight:!0,orientation:"bottom auto",language:"id",clearBtn:!0,container:"body",endDate:new Date}).on("changeDate",(function(e){console.log("End date selected:",e.format())})).on("clearDate",(function(e){console.log("End date cleared")}))}function t(){$("#date_to").datepicker("remove"),$("#date_to").val(""),a(),$("#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"),console.log("Initializing datepickers..."),$("#date_from").datepicker({format:"yyyy-mm-dd",autoclose:!0,todayHighlight:!0,orientation:"bottom auto",language:"id",clearBtn:!0,container:"body",endDate:new Date}).on("changeDate",(function(a){console.log("Start date selected:",a.format()),e(a.format())})).on("clearDate",(function(e){console.log("Start date cleared"),t()})),a(),$("#date_to").prop("disabled",!0),$("#date_from").on("change",(function(){var a=$(this).val();a?(console.log("Start date change event:",a),e(a)):(console.log("Start date cleared via change event"),t())})),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"),t(),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:'<i class="la la-angle-left"></i>',rightArrow:'<i class="la la-angle-right"></i>'},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:'<i class="la la-angle-left"></i>',rightArrow:'<i class="la la-angle-right"></i>'},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:'<i class="la la-angle-left"></i>',rightArrow:'<i class="la la-angle-right"></i>'},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!")}))})();
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -35,17 +35,25 @@ function initializeSelect2() {
function initializeDatepickers() { function initializeDatepickers() {
console.log("Initializing datepickers..."); console.log("Initializing datepickers...");
// Initialize start date picker with bootstrap datepicker // Check if bootstrap datepicker is available
if (typeof $.fn.datepicker === "undefined") {
console.error("Bootstrap Datepicker not available!");
return;
}
// Initialize start date picker
$("#date_from") $("#date_from")
.datepicker({ .datepicker({
format: "yyyy-mm-dd", format: "yyyy-mm-dd",
autoclose: true, autoclose: true,
todayHighlight: true, todayHighlight: true,
orientation: "bottom auto", orientation: "bottom left",
language: "id", templates: {
clearBtn: true, leftArrow: '<i class="la la-angle-left"></i>',
container: "body", rightArrow: '<i class="la la-angle-right"></i>',
},
endDate: new Date(), // Don't allow future dates endDate: new Date(), // Don't allow future dates
clearBtn: true,
}) })
.on("changeDate", function (e) { .on("changeDate", function (e) {
console.log("Start date selected:", e.format()); console.log("Start date selected:", e.format());
@@ -56,14 +64,11 @@ function initializeDatepickers() {
resetEndDatePicker(); resetEndDatePicker();
}); });
// Initialize end date picker with bootstrap datepicker // Initialize end date picker
initializeEndDatePicker(); initializeEndDatePicker();
// Initially disable end date input // Initially disable end date input
$("#date_to").prop("disabled", true); $("#date_to").prop("disabled", true);
// Setup change event handlers
setupChangeEventHandlers();
} }
function enableEndDatePicker(startDate) { function enableEndDatePicker(startDate) {
@@ -72,21 +77,23 @@ function enableEndDatePicker(startDate) {
// Enable the input // Enable the input
$("#date_to").prop("disabled", false); $("#date_to").prop("disabled", false);
// Destroy existing datepicker // Remove existing datepicker
$("#date_to").datepicker("remove"); $("#date_to").datepicker("remove");
// Re-initialize with new startDate constraint using bootstrap datepicker // Re-initialize with new startDate constraint
$("#date_to") $("#date_to")
.datepicker({ .datepicker({
format: "yyyy-mm-dd", format: "yyyy-mm-dd",
autoclose: true, autoclose: true,
todayHighlight: true, todayHighlight: true,
orientation: "bottom auto", orientation: "bottom left",
language: "id", templates: {
clearBtn: true, leftArrow: '<i class="la la-angle-left"></i>',
container: "body", rightArrow: '<i class="la la-angle-right"></i>',
},
startDate: startDate, // Set minimum date to selected start date startDate: startDate, // Set minimum date to selected start date
endDate: new Date(), // Don't allow future dates endDate: new Date(), // Don't allow future dates
clearBtn: true,
}) })
.on("changeDate", function (e) { .on("changeDate", function (e) {
console.log("End date selected:", e.format()); console.log("End date selected:", e.format());
@@ -104,11 +111,13 @@ function initializeEndDatePicker() {
format: "yyyy-mm-dd", format: "yyyy-mm-dd",
autoclose: true, autoclose: true,
todayHighlight: true, todayHighlight: true,
orientation: "bottom auto", orientation: "bottom left",
language: "id", templates: {
clearBtn: true, leftArrow: '<i class="la la-angle-left"></i>',
container: "body", rightArrow: '<i class="la la-angle-right"></i>',
},
endDate: new Date(), // Don't allow future dates endDate: new Date(), // Don't allow future dates
clearBtn: true,
}) })
.on("changeDate", function (e) { .on("changeDate", function (e) {
console.log("End date selected:", e.format()); console.log("End date selected:", e.format());
@@ -120,21 +129,6 @@ function initializeEndDatePicker() {
// Calendar icons and click handlers removed since bootstrap datepicker handles these automatically // Calendar icons and click handlers removed since bootstrap datepicker handles these automatically
function setupChangeEventHandlers() {
// For bootstrap datepicker, we already handle events in the datepicker initialization
// But we can add additional handling if needed
$("#date_from").on("change", function () {
const selectedDate = $(this).val();
if (selectedDate) {
console.log("Start date change event:", selectedDate);
enableEndDatePicker(selectedDate);
} else {
console.log("Start date cleared via change event");
resetEndDatePicker();
}
});
}
function initializeDataTable() { function initializeDataTable() {
console.log("Initializing DataTable..."); console.log("Initializing DataTable...");

View File

@@ -35,22 +35,30 @@ function initializeSelect2() {
} }
/** /**
* Initialize date pickers with bootstrap datepicker - same as stock audit * Initialize date pickers with bootstrap datepicker - same as transaction view
*/ */
function initializeDatepickers() { function initializeDatepickers() {
console.log("Initializing datepickers..."); console.log("Initializing datepickers...");
// Initialize start date picker with bootstrap datepicker // Check if bootstrap datepicker is available
if (typeof $.fn.datepicker === "undefined") {
console.error("Bootstrap Datepicker not available!");
return;
}
// Initialize start date picker
$("#date_from") $("#date_from")
.datepicker({ .datepicker({
format: "yyyy-mm-dd", format: "yyyy-mm-dd",
autoclose: true, autoclose: true,
todayHighlight: true, todayHighlight: true,
orientation: "bottom auto", orientation: "bottom left",
language: "id", templates: {
clearBtn: true, leftArrow: '<i class="la la-angle-left"></i>',
container: "body", rightArrow: '<i class="la la-angle-right"></i>',
},
endDate: new Date(), // Don't allow future dates endDate: new Date(), // Don't allow future dates
clearBtn: true,
}) })
.on("changeDate", function (e) { .on("changeDate", function (e) {
console.log("Start date selected:", e.format()); console.log("Start date selected:", e.format());
@@ -61,18 +69,15 @@ function initializeDatepickers() {
resetEndDatePicker(); resetEndDatePicker();
}); });
// Initialize end date picker with bootstrap datepicker // Initialize end date picker
initializeEndDatePicker(); initializeEndDatePicker();
// Initially disable end date input // Initially disable end date input
$("#date_to").prop("disabled", true); $("#date_to").prop("disabled", true);
// Setup change event handlers as backup
setupChangeEventHandlers();
} }
/** /**
* Enable end date picker with minimum date constraint using bootstrap datepicker * Enable end date picker with minimum date constraint
*/ */
function enableEndDatePicker(startDate) { function enableEndDatePicker(startDate) {
console.log("Enabling end date picker with min date:", startDate); console.log("Enabling end date picker with min date:", startDate);
@@ -83,18 +88,20 @@ function enableEndDatePicker(startDate) {
// Remove existing datepicker // Remove existing datepicker
$("#date_to").datepicker("remove"); $("#date_to").datepicker("remove");
// Re-initialize with new startDate constraint using bootstrap datepicker // Re-initialize with new startDate constraint
$("#date_to") $("#date_to")
.datepicker({ .datepicker({
format: "yyyy-mm-dd", format: "yyyy-mm-dd",
autoclose: true, autoclose: true,
todayHighlight: true, todayHighlight: true,
orientation: "bottom auto", orientation: "bottom left",
language: "id", templates: {
clearBtn: true, leftArrow: '<i class="la la-angle-left"></i>',
container: "body", rightArrow: '<i class="la la-angle-right"></i>',
},
startDate: startDate, // Set minimum date to selected start date startDate: startDate, // Set minimum date to selected start date
endDate: new Date(), // Don't allow future dates endDate: new Date(), // Don't allow future dates
clearBtn: true,
}) })
.on("changeDate", function (e) { .on("changeDate", function (e) {
console.log("End date selected:", e.format()); console.log("End date selected:", e.format());
@@ -107,7 +114,7 @@ function enableEndDatePicker(startDate) {
} }
/** /**
* Initialize end date picker without constraints using bootstrap datepicker * Initialize end date picker without constraints
*/ */
function initializeEndDatePicker() { function initializeEndDatePicker() {
$("#date_to") $("#date_to")
@@ -115,11 +122,13 @@ function initializeEndDatePicker() {
format: "yyyy-mm-dd", format: "yyyy-mm-dd",
autoclose: true, autoclose: true,
todayHighlight: true, todayHighlight: true,
orientation: "bottom auto", orientation: "bottom left",
language: "id", templates: {
clearBtn: true, leftArrow: '<i class="la la-angle-left"></i>',
container: "body", rightArrow: '<i class="la la-angle-right"></i>',
},
endDate: new Date(), // Don't allow future dates endDate: new Date(), // Don't allow future dates
clearBtn: true,
}) })
.on("changeDate", function (e) { .on("changeDate", function (e) {
console.log("End date selected:", e.format()); console.log("End date selected:", e.format());
@@ -129,24 +138,23 @@ function initializeEndDatePicker() {
}); });
} }
// Calendar icons and click handlers removed since bootstrap datepicker handles these automatically
/** /**
* Setup change event handlers for date inputs * Reset end date picker to initial state
*/ */
function setupChangeEventHandlers() { function resetEndDatePicker() {
// For bootstrap datepicker, we already handle events in the datepicker initialization // Remove existing datepicker
// But we can add additional handling if needed $("#date_to").datepicker("remove");
$("#date_from").on("change", function () {
const selectedDate = $(this).val(); // Clear the input value
if (selectedDate) { $("#date_to").val("");
console.log("Start date change event:", selectedDate);
enableEndDatePicker(selectedDate); // Re-initialize without startDate constraint
} else { initializeEndDatePicker();
console.log("Start date cleared via change event");
resetEndDatePicker(); // Disable the input
} $("#date_to").prop("disabled", true);
});
console.log("End date picker reset and disabled");
} }
/** /**
@@ -293,25 +301,6 @@ function setupFilterHandlers(table) {
}); });
} }
/**
* Reset end date picker to initial state using bootstrap datepicker
*/
function resetEndDatePicker() {
// Remove existing datepicker
$("#date_to").datepicker("remove");
// Clear the input value
$("#date_to").val("");
// Re-initialize without startDate constraint
initializeEndDatePicker();
// Disable the input
$("#date_to").prop("disabled", true);
console.log("End date picker reset and disabled");
}
/** /**
* Setup additional table event handlers * Setup additional table event handlers
*/ */

View File

@@ -824,7 +824,7 @@ use Illuminate\Support\Facades\Auth;
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="to_dealer_id">Dealer Tujuan <span class="text-danger">*</span></label> <label for="to_dealer_id">Dealer Tujuan </label>
<select name="to_dealer_id" id="to_dealer_id" class="form-control" required> <select name="to_dealer_id" id="to_dealer_id" class="form-control" required>
<option value="">Pilih Dealer Tujuan</option> <option value="">Pilih Dealer Tujuan</option>
@php @php
@@ -838,7 +838,7 @@ use Illuminate\Support\Facades\Auth;
<div class="form-group"> <div class="form-group">
<div class="d-flex justify-content-between align-items-center mb-3"> <div class="d-flex justify-content-between align-items-center mb-3">
<label class="form-label mb-0">Detail Produk <span class="text-danger">*</span></label> <label class="form-label mb-0">Detail Produk</span></label>
<button type="button" class="btn btn-success btn-sm" id="add-product-mutasi"> <button type="button" class="btn btn-success btn-sm" id="add-product-mutasi">
<i class="fa fa-plus"></i> Tambah Produk <i class="fa fa-plus"></i> Tambah Produk
</button> </button>

View File

@@ -26,7 +26,7 @@
<div class="kt-portlet__body"> <div class="kt-portlet__body">
<!-- Filter Section --> <!-- Filter Section -->
<div class="row mb-3"> <div class="row">
<div class="col-md-3"> <div class="col-md-3">
<div class="form-group"> <div class="form-group">
<label class="form-label">Tanggal Awal</label> <label class="form-label">Tanggal Awal</label>
@@ -39,7 +39,7 @@
<input type="text" class="form-control datepicker" id="date_to" name="date_to" placeholder="Tanggal akhir" readonly> <input type="text" class="form-control datepicker" id="date_to" name="date_to" placeholder="Tanggal akhir" readonly>
</div> </div>
</div> </div>
<div class="col-md-3"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label class="form-label">Filter Dealer</label> <label class="form-label">Filter Dealer</label>
<select class="form-control select2" id="dealer_filter" name="dealer_filter"> <select class="form-control select2" id="dealer_filter" name="dealer_filter">
@@ -50,18 +50,15 @@
</select> </select>
</div> </div>
</div> </div>
<div class="col-md-3"> </div>
<div class="form-group"> <div class="row mb-3">
<label class="form-label">&nbsp;</label> <div class="col-md-12 filter-buttons">
<div class="filter-buttons"> <button type="button" class="btn btn-primary btn-sm" id="kt_search">
<button type="button" class="btn btn-primary btn-sm" id="kt_search"> Filter
Filter </button>
</button> <button type="button" class="btn btn-secondary btn-sm" id="kt_reset">
<button type="button" class="btn btn-secondary btn-sm" id="kt_reset"> Reset
Reset </button>
</button>
</div>
</div>
</div> </div>
</div> </div>

View File

@@ -1,57 +1,56 @@
@extends('layouts.backapp') @extends('layouts.backapp')
@section('content') @section('content')
<div class="kt-portlet kt-portlet--mobile" id="kt_blockui_datatable"> <div class="kt-portlet kt-portlet--mobile" id="kt_blockui_datatable">
<div class="kt-portlet__head kt-portlet__head--lg"> <div class="kt-portlet__head kt-portlet__head--lg">
<div class="kt-portlet__head-label"> <div class="kt-portlet__head-label">
<span class="kt-portlet__head-icon"> <span class="kt-portlet__head-icon">
<i class="kt-font-brand flaticon2-list-1"></i> <i class="kt-font-brand flaticon2-list-1"></i>
</span> </span>
<h3 class="kt-portlet__head-title"> <h3 class="kt-portlet__head-title">
Tabel Opname Tabel Opname
</h3> </h3>
</div> </div>
@can('create', $menus['opnames.index']) @can('create', $menus['opnames.index'])
<div class="kt-portlet__head-toolbar"> <div class="kt-portlet__head-toolbar">
<div class="kt-portlet__head-wrapper"> <div class="kt-portlet__head-wrapper">
<div class="kt-portlet__head-actions"> <div class="kt-portlet__head-actions">
<a href="{{ route('opnames.create') }}" class="btn btn-bold btn-label-brand btn--sm">Tambah</a> <a href="{{ route('opnames.create') }}" class="btn btn-bold btn-label-brand btn--sm">Tambah</a>
</div> </div>
</div> </div>
</div> </div>
@endcan @endcan
</div> </div>
<div class="kt-portlet__body"> <div class="kt-portlet__body">
<!-- Filter Section --> <!-- Filter Section -->
<div class="row mb-3"> <div class="row">
<div class="col-md-3"> <div class="col-md-3">
<div class="form-group"> <div class="form-group">
<label class="form-label">Tanggal Awal</label> <label class="form-label">Tanggal Awal</label>
<input type="text" class="form-control datepicker" id="date_from" name="date_from" placeholder="Tanggal awal" readonly> <input type="text" class="form-control datepicker" id="date_from" name="date_from" placeholder="Tanggal awal" readonly>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="form-label">Tanggal Akhir</label>
<input type="text" class="form-control datepicker" id="date_to" name="date_to" placeholder="Tanggal akhir" readonly>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="form-label">Filter Dealer</label>
<select class="form-control select2" id="dealer_filter" name="dealer_filter">
<option value="">Semua Dealer</option>
@foreach($dealers as $dealer)
<option value="{{ $dealer->id }}">{{ $dealer->name }}</option>
@endforeach
</select>
</div>
</div>
</div> </div>
</div> <div class="row mb-3">
<div class="col-md-3"> <div class="col-md-12 filter-buttons">
<div class="form-group">
<label class="form-label">Tanggal Akhir</label>
<input type="text" class="form-control datepicker" id="date_to" name="date_to" placeholder="Tanggal akhir" readonly>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="form-label">Filter Dealer</label>
<select class="form-control select2" id="dealer_filter" name="dealer_filter">
<option value="">Semua Dealer</option>
@foreach($dealers as $dealer)
<option value="{{ $dealer->id }}">{{ $dealer->name }}</option>
@endforeach
</select>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="form-label">&nbsp;</label>
<div class="filter-buttons">
<button type="button" class="btn btn-primary btn-sm" id="kt_search"> <button type="button" class="btn btn-primary btn-sm" id="kt_search">
Filter Filter
</button> </button>
@@ -60,68 +59,66 @@
</button> </button>
</div> </div>
</div> </div>
<div class="table-responsive">
<!--begin: Datatable -->
<table class="table table-striped table-bordered table-hover" id="opnames-table" data-url="{{ route('opnames.index') }}">
<thead>
<tr>
<th>Waktu Dibuat</th>
<th>Tanggal Opname</th>
<th>Dealer</th>
<th>Pengguna</th>
<th>Status</th>
<th>Aksi</th>
</tr>
</thead>
</table>
<!--end: Datatable -->
</div>
</div> </div>
</div> </div>
<div class="table-responsive">
<!--begin: Datatable -->
<table class="table table-striped table-bordered table-hover" id="opnames-table" data-url="{{ route('opnames.index') }}">
<thead>
<tr>
<th>Waktu Dibuat</th>
<th>Tanggal Opname</th>
<th>Dealer</th>
<th>Pengguna</th>
<th>Status</th>
<th>Aksi</th>
</tr>
</thead>
</table>
<!--end: Datatable -->
</div>
</div>
</div>
@endsection @endsection
@section('styles') @section('styles')
<style> <style>
.filter-buttons { .filter-buttons {
display: flex; display: flex;
gap: 10px; gap: 10px;
} }
.filter-buttons .btn { .filter-buttons .btn {
white-space: nowrap; white-space: nowrap;
} }
.datepicker {
width: 100% !important;
max-width: 100%;
}
.datepicker-dropdown {
width: auto !important;
min-width: 250px;
max-width: 300px;
}
/* Ensure input field follows parent width */
input.datepicker {
width: 100% !important;
box-sizing: border-box;
}
.form-label { /* Datepicker styling */
font-weight: 600; .datepicker {
color: #595d6e; width: 100% !important;
margin-bottom: 8px; max-width: 100%;
font-size: 13px; }
text-transform: none; .datepicker-dropdown {
letter-spacing: normal; width: auto !important;
display: block; min-width: 250px;
} max-width: 300px;
}
/* Select2 styling - same as stock audit (minimal) */ /* Ensure input field follows parent width */
.select2-container { input.datepicker {
width: 100% !important; width: 100% !important;
} box-sizing: border-box;
}
.form-label {
font-weight: 600;
color: #595d6e;
margin-bottom: 8px;
font-size: 13px;
text-transform: none;
letter-spacing: normal;
display: block;
}
/* Select2 styling - same as stock audit (minimal) */
.select2-container {
width: 100% !important;
}
</style> </style>
@endsection @endsection

View File

@@ -38,7 +38,7 @@ input.datepicker {
<div class="kt-portlet__body"> <div class="kt-portlet__body">
<!-- Filter Section --> <!-- Filter Section -->
<div class="ke-form row mb-3"> <div class="ke-form row">
<div class="form-group col-md-3"> <div class="form-group col-md-3">
<label class="form-label">Filter Dealer</label> <label class="form-label">Filter Dealer</label>
<select class="form-control select2" id="filter-dealer"> <select class="form-control select2" id="filter-dealer">
@@ -105,103 +105,103 @@ input.datepicker {
</thead> </thead>
</table> </table>
</div> </div>
</div>
</div>
<!-- Detail Modal --> <!-- Detail Modal -->
<div class="modal fade" id="auditDetailModal" tabindex="-1" role="dialog" aria-labelledby="auditDetailModalLabel" aria-hidden="true"> <div class="modal fade" id="auditDetailModal" tabindex="-1" role="dialog" aria-labelledby="auditDetailModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document"> <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="auditDetailModalLabel">Detail Audit Stock</h5> <h5 class="modal-title" id="auditDetailModalLabel">Detail Audit Stock</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="modal-close-btn"> <button type="button" class="close" data-dismiss="modal" aria-label="Close" id="modal-close-btn">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
</div>
<div class="modal-body" id="auditDetailContent">
<!-- Loading State -->
<div id="modal-loading" class="text-center">
<div class="spinner-border" role="status">
<span class="sr-only">Memuat...</span>
</div> </div>
<p class="mt-2">Memuat data audit...</p> <div class="modal-body" id="auditDetailContent">
</div> <!-- Loading State -->
<div id="modal-loading" class="text-center">
<!-- Error State --> <div class="spinner-border" role="status">
<div id="modal-error" class="alert alert-danger" style="display: none;"> <span class="sr-only">Memuat...</span>
<strong>Error:</strong> <span id="error-message">Gagal memuat detail audit</span>
</div>
<!-- Content Area -->
<div id="modal-content" style="display: none;">
<!-- Stock Information -->
<div class="row">
<div class="col-md-6">
<h6 class="font-weight-bold">Informasi Stock</h6>
<table class="table table-sm">
<tr>
<td><strong>Produk:</strong></td>
<td id="product-name">-</td>
</tr>
<tr>
<td><strong>Dealer:</strong></td>
<td id="dealer-name">-</td>
</tr>
<tr></tr>
<td><strong>Stock Sebelum:</strong></td>
<td id="previous-quantity">-</td>
</tr>
<tr>
<td><strong>Stock Sesudah:</strong></td>
<td id="new-quantity">-</td>
</tr>
<tr>
<td><strong>Perubahan:</strong></td>
<td id="quantity-change">-</td>
</tr>
<tr>
<td><strong>Jenis Perubahan:</strong></td>
<td id="change-type">-</td>
</tr>
</table>
</div>
<div class="col-md-6">
<h6 class="font-weight-bold">Informasi Sistem</h6>
<table class="table table-sm">
<tr>
<td><strong>User:</strong></td>
<td id="user-name">-</td>
</tr>
<tr>
<td><strong>Tanggal:</strong></td>
<td id="created-at">-</td>
</tr>
<tr>
<td><strong>Deskripsi:</strong></td>
<td id="description">-</td>
</tr>
</table>
</div>
</div>
<!-- Source Detail (will be shown/hidden based on data) -->
<div id="source-detail" style="display: none;">
<hr>
<h6 class="font-weight-bold">Detail Sumber Perubahan</h6>
<div class="card">
<div class="card-header">
<h6 class="mb-0" id="source-title">-</h6>
</div> </div>
<div class="card-body" id="source-content"> <p class="mt-2">Memuat data audit...</p>
<!-- Content will be populated by JavaScript --> </div>
<!-- Error State -->
<div id="modal-error" class="alert alert-danger" style="display: none;">
<strong>Error:</strong> <span id="error-message">Gagal memuat detail audit</span>
</div>
<!-- Content Area -->
<div id="modal-content" style="display: none;">
<!-- Stock Information -->
<div class="row">
<div class="col-md-6">
<h6 class="font-weight-bold">Informasi Stock</h6>
<table class="table table-sm">
<tr>
<td><strong>Produk:</strong></td>
<td id="product-name">-</td>
</tr>
<tr>
<td><strong>Dealer:</strong></td>
<td id="dealer-name">-</td>
</tr>
<tr></tr>
<td><strong>Stock Sebelum:</strong></td>
<td id="previous-quantity">-</td>
</tr>
<tr>
<td><strong>Stock Sesudah:</strong></td>
<td id="new-quantity">-</td>
</tr>
<tr>
<td><strong>Perubahan:</strong></td>
<td id="quantity-change">-</td>
</tr>
<tr>
<td><strong>Jenis Perubahan:</strong></td>
<td id="change-type">-</td>
</tr>
</table>
</div>
<div class="col-md-6">
<h6 class="font-weight-bold">Informasi Sistem</h6>
<table class="table table-sm">
<tr>
<td><strong>User:</strong></td>
<td id="user-name">-</td>
</tr>
<tr>
<td><strong>Tanggal:</strong></td>
<td id="created-at">-</td>
</tr>
<tr>
<td><strong>Deskripsi:</strong></td>
<td id="description">-</td>
</tr>
</table>
</div>
</div>
<!-- Source Detail (will be shown/hidden based on data) -->
<div id="source-detail" style="display: none;">
<hr>
<h6 class="font-weight-bold">Detail Sumber Perubahan</h6>
<div class="card">
<div class="card-header">
<h6 class="mb-0" id="source-title">-</h6>
</div>
<div class="card-body" id="source-content">
<!-- Content will be populated by JavaScript -->
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" id="modal-close-footer-btn">Tutup</button>
</div>
</div> </div>
</div> </div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" id="modal-close-footer-btn">Tutup</button>
</div>
</div> </div>
</div> </div>
</div> </div>