localize library cdn, remove approve button from transaction page, fix all fitur running datatable as well, fixing sortable datatable using new cdn, fix modal approve, add note to receiver mutations

This commit is contained in:
2025-06-16 15:01:08 +07:00
parent 9cfb566aee
commit 567e4aa5fc
45 changed files with 16202 additions and 365 deletions

View File

@@ -19,8 +19,13 @@ class MutationsController extends Controller
$menu = Menu::where('link','mutations.index')->first();
if ($request->ajax()) {
$data = Mutation::with(['fromDealer', 'toDealer', 'requestedBy.role', 'approvedBy.role', 'receivedBy.role'])
->select('mutations.*');
// Use a more specific query to avoid join conflicts
$data = Mutation::query()
->with(['fromDealer', 'toDealer', 'requestedBy.role', 'approvedBy.role', 'receivedBy.role'])
->select([
'mutations.*'
])
->orderBy('mutations.id', 'desc'); // Default order by ID desc
// Filter berdasarkan dealer jika user bukan admin
if (auth()->user()->dealer_id) {
@@ -60,6 +65,65 @@ class MutationsController extends Controller
->addColumn('action', function($row) {
return view('warehouse_management.mutations._action', compact('row'))->render();
})
// Enhanced filtering
->filterColumn('mutation_number', function($query, $keyword) {
$query->where('mutations.mutation_number', 'like', "%{$keyword}%");
})
->filterColumn('from_dealer', function($query, $keyword) {
$query->whereHas('fromDealer', function($q) use ($keyword) {
$q->where('name', 'like', "%{$keyword}%");
});
})
->filterColumn('to_dealer', function($query, $keyword) {
$query->whereHas('toDealer', function($q) use ($keyword) {
$q->where('name', 'like', "%{$keyword}%");
});
})
->filterColumn('requested_by', function($query, $keyword) {
$query->whereHas('requestedBy', function($q) use ($keyword) {
$q->where('name', 'like', "%{$keyword}%");
});
})
->filterColumn('status', function($query, $keyword) {
$query->where('mutations.status', 'like', "%{$keyword}%");
})
->filterColumn('created_at', function($query, $keyword) {
$query->whereDate('mutations.created_at', 'like', "%{$keyword}%");
})
// Enhanced ordering - avoid join conflicts by using subqueries
->orderColumn('mutation_number', function($query, $order) {
$query->orderBy('mutations.mutation_number', $order);
})
->orderColumn('from_dealer', function($query, $order) {
$query->orderBy(
DB::raw('(SELECT name FROM dealers WHERE dealers.id = mutations.from_dealer_id)'),
$order
);
})
->orderColumn('to_dealer', function($query, $order) {
$query->orderBy(
DB::raw('(SELECT name FROM dealers WHERE dealers.id = mutations.to_dealer_id)'),
$order
);
})
->orderColumn('requested_by', function($query, $order) {
$query->orderBy(
DB::raw('(SELECT name FROM users WHERE users.id = mutations.requested_by)'),
$order
);
})
->orderColumn('total_items', function($query, $order) {
$query->orderBy(
DB::raw('(SELECT SUM(quantity_requested) FROM mutation_details WHERE mutation_details.mutation_id = mutations.id)'),
$order
);
})
->orderColumn('status', function($query, $order) {
$query->orderBy('mutations.status', $order);
})
->orderColumn('created_at', function($query, $order) {
$query->orderBy('mutations.created_at', $order);
})
->rawColumns(['status', 'action'])
->make(true);
}
@@ -319,19 +383,26 @@ class MutationsController extends Controller
// Get mutations that need action from this dealer:
// 1. 'sent' status where this dealer is the recipient (need to receive)
// 2. 'received' status where this dealer is the recipient (need to approve) - CORRECTED LOGIC
// 2. 'received' status where this dealer is the recipient (show as waiting for admin approval)
// 3. 'approved' status where this dealer is the recipient (show as completed)
// 4. 'rejected' status where this dealer is the recipient (show as rejected)
$data = Mutation::with(['fromDealer', 'toDealer', 'requestedBy.role'])
->where(function($query) use ($dealerId) {
// Mutations sent to this dealer that need to be received
$query->where('to_dealer_id', $dealerId)
->where('status', 'sent');
// OR mutations received by this dealer that need approval from recipient
// OR mutations received by this dealer (waiting for admin approval)
$query->orWhere(function($subQuery) use ($dealerId) {
$subQuery->where('to_dealer_id', $dealerId)
->where('status', 'received');
});
// OR mutations approved/rejected for this dealer (historical data)
$query->orWhere(function($subQuery) use ($dealerId) {
$subQuery->where('to_dealer_id', $dealerId)
->whereIn('status', ['approved', 'rejected']);
});
})
->select('mutations.*');
->orderBy('mutations.id', 'desc'); // Default order by ID desc
return DataTables::of($data)
->addIndexColumn()
@@ -345,21 +416,11 @@ class MutationsController extends Controller
return $row->toDealer->name ?? '-';
})
->addColumn('status', function($row) {
$statusColor = $row->status_color;
$statusLabel = $row->status_label;
$status = $row->status instanceof MutationStatus ? $row->status : MutationStatus::from($row->status);
$textColorClass = $status->textColorClass();
$label = $status->label();
$textColorClass = match($statusColor) {
'success' => 'text-success',
'warning' => 'text-warning',
'danger' => 'text-danger',
'info' => 'text-info',
'primary' => 'text-primary',
'brand' => 'text-primary',
'secondary' => 'text-muted',
default => 'text-dark'
};
return "<span class=\"font-weight-bold {$textColorClass}\">{$statusLabel}</span>";
return "<span class=\"font-weight-bold {$textColorClass}\">{$label}</span>";
})
->addColumn('total_items', function($row) {
return number_format($row->total_items, 0);
@@ -376,16 +437,23 @@ class MutationsController extends Controller
Detail & Terima
</button>';
} elseif ($row->status->value === 'received' && $row->to_dealer_id == $dealerId) {
// For received mutations where current dealer is recipient - show approve/reject buttons
$buttons .= '<button type="button" class="btn btn-info btn-sm btn-detail mr-1" onclick="showMutationDetail('.$row->id.')">
// For received mutations where current dealer is recipient - only show detail (approval is admin only)
$buttons .= '<button type="button" class="btn btn-info btn-sm btn-detail" onclick="showMutationDetail('.$row->id.')">
Detail
</button>';
$buttons .= '<button type="button" class="btn btn-success btn-sm btn-approve-mutation mr-1" data-id="'.$row->id.'">
Setujui
$buttons .= '<div class="mt-1"><small class="text-muted">Menunggu persetujuan admin</small></div>';
} elseif ($row->status->value === 'approved' && $row->to_dealer_id == $dealerId) {
// For approved mutations - show detail only
$buttons .= '<button type="button" class="btn btn-info btn-sm btn-detail" onclick="showMutationDetail('.$row->id.')">
Detail
</button>';
$buttons .= '<button type="button" class="btn btn-danger btn-sm btn-reject-mutation" data-id="'.$row->id.'">
Tolak
$buttons .= '<div class="mt-1"><small class="text-success">Disetujui admin</small></div>';
} elseif ($row->status->value === 'rejected' && $row->to_dealer_id == $dealerId) {
// For rejected mutations - show detail only
$buttons .= '<button type="button" class="btn btn-info btn-sm btn-detail" onclick="showMutationDetail('.$row->id.')">
Detail
</button>';
$buttons .= '<div class="mt-1"><small class="text-danger">Ditolak admin</small></div>';
}
return $buttons;

View File

@@ -26,8 +26,10 @@ class ProductsController extends Controller
{
$menu = Menu::where('link','products.index')->first();
if($request->ajax()){
$data = Product::with(['category', 'stocks'])
->orderBy('id', 'desc');
$data = Product::with(['category'])
->select('products.*')
->leftJoin('product_categories', 'products.product_category_id', '=', 'product_categories.id');
return DataTables::of($data)
->addIndexColumn()
->addColumn('category_name', function ($row) {
@@ -55,6 +57,12 @@ class ProductsController extends Controller
return $btn;
})
->filterColumn('category_name', function($query, $keyword) {
$query->where('product_categories.name', 'like', "%{$keyword}%");
})
->orderColumn('category_name', function ($query, $order) {
$query->orderBy('product_categories.name', $order);
})
->rawColumns(['action'])
->make(true);
}
@@ -196,7 +204,7 @@ class ProductsController extends Controller
public function all_products(){
try{
$products = Product::where('is_active', true)->select('id','name')->get();
$products = Product::where('active', true)->select('id','name')->get();
return response()->json($products);
}catch(\Exception $ex){
Log::error($ex->getMessage());