partial update create mutations workflow
This commit is contained in:
@@ -19,7 +19,7 @@ class MutationsController extends Controller
|
||||
$menu = Menu::where('link','mutations.index')->first();
|
||||
|
||||
if ($request->ajax()) {
|
||||
$data = Mutation::with(['fromDealer', 'toDealer', 'requestedBy', 'approvedBy', 'receivedBy'])
|
||||
$data = Mutation::with(['fromDealer', 'toDealer', 'requestedBy.role', 'approvedBy.role', 'receivedBy.role'])
|
||||
->select('mutations.*');
|
||||
|
||||
// Filter berdasarkan dealer jika user bukan admin
|
||||
@@ -47,7 +47,19 @@ class MutationsController extends Controller
|
||||
->addColumn('status', function($row) {
|
||||
$statusColor = $row->status_color;
|
||||
$statusLabel = $row->status_label;
|
||||
return "<span class=\"kt-badge kt-badge--{$statusColor} kt-badge--dot\"></span> <span class=\"kt-font-bold kt-font-{$statusColor}\">{$statusLabel}</span>";
|
||||
|
||||
$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>";
|
||||
})
|
||||
->addColumn('total_items', function($row) {
|
||||
return number_format($row->total_items, 0);
|
||||
@@ -79,7 +91,6 @@ class MutationsController extends Controller
|
||||
$request->validate([
|
||||
'from_dealer_id' => 'required|exists:dealers,id',
|
||||
'to_dealer_id' => 'required|exists:dealers,id|different:from_dealer_id',
|
||||
'notes' => 'nullable|string',
|
||||
'products' => 'required|array|min:1',
|
||||
'products.*.product_id' => 'required|exists:products,id',
|
||||
'products.*.quantity_requested' => 'required|numeric|min:0.01'
|
||||
@@ -92,8 +103,7 @@ class MutationsController extends Controller
|
||||
'from_dealer_id' => $request->from_dealer_id,
|
||||
'to_dealer_id' => $request->to_dealer_id,
|
||||
'status' => 'sent',
|
||||
'requested_by' => auth()->id(),
|
||||
'notes' => $request->notes
|
||||
'requested_by' => auth()->id()
|
||||
]);
|
||||
|
||||
// Buat mutation details
|
||||
@@ -101,8 +111,7 @@ class MutationsController extends Controller
|
||||
MutationDetail::create([
|
||||
'mutation_id' => $mutation->id,
|
||||
'product_id' => $productData['product_id'],
|
||||
'quantity_requested' => $productData['quantity_requested'],
|
||||
'notes' => $productData['notes'] ?? null
|
||||
'quantity_requested' => $productData['quantity_requested']
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -118,24 +127,63 @@ class MutationsController extends Controller
|
||||
|
||||
public function show(Mutation $mutation)
|
||||
{
|
||||
$mutation->load(['fromDealer', 'toDealer', 'requestedBy', 'approvedBy', 'receivedBy', 'mutationDetails.product']);
|
||||
$mutation->load(['fromDealer', 'toDealer', 'requestedBy.role', 'approvedBy.role', 'receivedBy.role', 'mutationDetails.product']);
|
||||
|
||||
return view('warehouse_management.mutations.show', compact('mutation'));
|
||||
}
|
||||
|
||||
public function receive(Mutation $mutation)
|
||||
public function receive(Request $request, Mutation $mutation)
|
||||
{
|
||||
$request->validate([
|
||||
'notes' => 'nullable|string',
|
||||
'products' => 'required|array',
|
||||
'products.*.quantity_approved' => 'required|numeric|min:0',
|
||||
'products.*.notes' => 'nullable|string'
|
||||
]);
|
||||
|
||||
if (!$mutation->canBeReceived()) {
|
||||
return back()->withErrors(['error' => 'Mutasi tidak dapat diterima dalam status saat ini']);
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// Update mutation notes jika ada
|
||||
if ($request->notes) {
|
||||
$mutation->update(['notes' => $request->notes]);
|
||||
}
|
||||
|
||||
// Update product details dengan quantity_approved dan notes
|
||||
if ($request->products) {
|
||||
foreach ($request->products as $detailId => $productData) {
|
||||
$updateData = [];
|
||||
|
||||
// Set quantity_approved
|
||||
if (isset($productData['quantity_approved'])) {
|
||||
$updateData['quantity_approved'] = $productData['quantity_approved'];
|
||||
}
|
||||
|
||||
// Set notes jika ada
|
||||
if (isset($productData['notes']) && !empty($productData['notes'])) {
|
||||
$updateData['notes'] = $productData['notes'];
|
||||
}
|
||||
|
||||
if (!empty($updateData)) {
|
||||
MutationDetail::where('id', $detailId)
|
||||
->where('mutation_id', $mutation->id)
|
||||
->update($updateData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Receive mutation
|
||||
$mutation->receive(auth()->id());
|
||||
|
||||
DB::commit();
|
||||
return redirect()->route('mutations.index')
|
||||
->with('success', 'Mutasi berhasil diterima dan menunggu persetujuan pengirim');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollback();
|
||||
return back()->withErrors(['error' => 'Gagal menerima mutasi: ' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
@@ -143,34 +191,21 @@ class MutationsController extends Controller
|
||||
public function approve(Request $request, Mutation $mutation)
|
||||
{
|
||||
$request->validate([
|
||||
'notes' => 'nullable|string',
|
||||
'details' => 'required|array',
|
||||
'details.*.quantity_approved' => 'required|numeric|min:0'
|
||||
'notes' => 'nullable|string'
|
||||
]);
|
||||
|
||||
if (!$mutation->canBeApproved()) {
|
||||
return back()->withErrors(['error' => 'Mutasi tidak dapat disetujui dalam status saat ini']);
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// Update mutation details dengan quantity approved
|
||||
foreach ($request->details as $detailId => $detailData) {
|
||||
$mutationDetail = MutationDetail::findOrFail($detailId);
|
||||
$mutationDetail->update([
|
||||
'quantity_approved' => $detailData['quantity_approved']
|
||||
]);
|
||||
}
|
||||
|
||||
// Approve mutation
|
||||
// Approve mutation (quantity_approved sudah diisi saat receive)
|
||||
$mutation->approve(auth()->id(), $request->notes);
|
||||
|
||||
DB::commit();
|
||||
return redirect()->route('mutations.index')
|
||||
->with('success', 'Mutasi berhasil disetujui');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollback();
|
||||
return back()->withErrors(['error' => 'Gagal menyetujui mutasi: ' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
@@ -230,36 +265,7 @@ class MutationsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
// API untuk mendapatkan detail mutasi untuk approval
|
||||
public function getDetails(Mutation $mutation)
|
||||
{
|
||||
$mutation->load(['mutationDetails.product', 'fromDealer']);
|
||||
|
||||
$details = $mutation->mutationDetails->map(function($detail) use ($mutation) {
|
||||
$availableStock = $detail->product->getStockByDealer($mutation->from_dealer_id);
|
||||
|
||||
return [
|
||||
'id' => $detail->id,
|
||||
'product' => [
|
||||
'id' => $detail->product->id,
|
||||
'name' => $detail->product->name
|
||||
],
|
||||
'quantity_requested' => $detail->quantity_requested,
|
||||
'quantity_approved' => $detail->quantity_approved,
|
||||
'available_stock' => $availableStock
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'mutation' => [
|
||||
'id' => $mutation->id,
|
||||
'mutation_number' => $mutation->mutation_number,
|
||||
'from_dealer' => $mutation->fromDealer->name,
|
||||
'to_dealer' => $mutation->toDealer->name
|
||||
],
|
||||
'details' => $details
|
||||
]);
|
||||
}
|
||||
|
||||
// API untuk mendapatkan stock produk di dealer tertentu
|
||||
public function getProductStock(Request $request)
|
||||
|
||||
@@ -39,14 +39,25 @@ class OpnamesController extends Controller
|
||||
return Carbon::parse($row->created_at)->format('d M Y H:i');
|
||||
})
|
||||
->editColumn('status', function ($row) {
|
||||
$statusClass = [
|
||||
$statusColor = [
|
||||
'draft' => 'warning',
|
||||
'pending' => 'info',
|
||||
'approved' => 'success',
|
||||
'rejected' => 'danger'
|
||||
][$row->status] ?? 'secondary';
|
||||
|
||||
return '<span class="badge badge-' . $statusClass . '">' . ucfirst($row->status) . '</span>';
|
||||
$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}\">" . ucfirst($row->status) . "</span>";
|
||||
})
|
||||
->addColumn('action', function ($row) use ($menu) {
|
||||
$btn = '<div class="d-flex">';
|
||||
|
||||
Reference in New Issue
Block a user