partial update create mutations workflow

This commit is contained in:
2025-06-12 15:10:51 +07:00
parent a5e1348436
commit 1a01efb1b5
33 changed files with 560 additions and 12994 deletions

View File

@@ -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>&nbsp;<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)