render('adjustment::index'); } public function create() { abort_if(Gate::denies('create_adjustments'), 403); return view('adjustment::create'); } public function store(Request $request) { abort_if(Gate::denies('create_adjustments'), 403); $request->validate([ 'reference' => 'required|string|max:255', 'date' => 'required|date', 'note' => 'nullable|string|max:1000', 'product_batch_ids' => 'required', 'quantities' => 'required', 'types' => 'required' ]); DB::transaction(function () use ($request) { $adjustment = Adjustment::create([ 'branches_id' => session('branch_id'), 'date' => $request->date, 'note' => $request->note ]); foreach ($request->product_ids as $key => $id) { AdjustedProduct::create([ 'adjustment_id' => $adjustment->id, 'product_id' => $id, 'product_batch_id' => $request->product_batch_ids[$key], 'quantity' => $request->quantities[$key], 'type' => $request->types[$key] ]); $batchId = $request->product_batch_ids[$key]; // batch yang dipilih oleh user $batch = DB::table('product_batches')->where('id', $batchId)->lockForUpdate()->first(); if ($batch) { if ($request->types[$key] == 'add') { DB::table('product_batches')->where('id', $batchId)->update([ 'qty' => $batch->qty + $request->quantities[$key] ]); } elseif ($request->types[$key] == 'sub') { $newQty = $batch->qty - $request->quantities[$key]; if ($newQty < 0) { throw new \Exception("Stock untuk batch {$batch->batch_code} tidak mencukupi."); } DB::table('product_batches')->where('id', $batchId)->update([ 'qty' => $newQty ]); } } else { throw new \Exception("Batch tidak ditemukan."); } } }); toast('Adjustment Created!', 'success'); return redirect()->route('adjustments.index'); } public function show(Adjustment $adjustment) { abort_if(Gate::denies('show_adjustments'), 403); return view('adjustment::show', compact('adjustment')); } public function edit(Adjustment $adjustment) { abort_if(Gate::denies('edit_adjustments'), 403); return view('adjustment::edit', compact('adjustment')); } public function update(Request $request, Adjustment $adjustment) { abort_if(Gate::denies('edit_adjustments'), 403); $request->validate([ 'reference' => 'required|string|max:255', 'date' => 'required|date', 'note' => 'nullable|string|max:1000', 'product_ids' => 'required', 'quantities' => 'required', 'types' => 'required' ]); DB::transaction(function () use ($request, $adjustment) { $adjustment->update([ 'reference' => $request->reference, 'date' => $request->date, 'note' => $request->note ]); foreach ($adjustment->adjustedProducts as $adjustedProduct) { $product = Product::findOrFail($adjustedProduct->product->id); if ($adjustedProduct->type == 'add') { $product->update([ 'product_quantity' => $product->product_quantity - $adjustedProduct->quantity ]); } elseif ($adjustedProduct->type == 'sub') { $product->update([ 'product_quantity' => $product->product_quantity + $adjustedProduct->quantity ]); } $adjustedProduct->delete(); } foreach ($request->product_ids as $key => $id) { AdjustedProduct::create([ 'adjustment_id' => $adjustment->id, 'product_id' => $id, 'product_batch_id' => $request->batch_ids[$key], 'quantity' => $request->quantities[$key], 'type' => $request->types[$key] ]); $product = Product::findOrFail($id); if ($request->types[$key] == 'add') { $product->update([ 'product_quantity' => $product->product_quantity + $request->quantities[$key] ]); } elseif ($request->types[$key] == 'sub') { $product->update([ 'product_quantity' => $product->product_quantity - $request->quantities[$key] ]); } } }); toast('Adjustment Updated!', 'info'); return redirect()->route('adjustments.index'); } public function destroy(Adjustment $adjustment) { abort_if(Gate::denies('delete_adjustments'), 403); $adjustment->delete(); toast('Adjustment Deleted!', 'warning'); return redirect()->route('adjustments.index'); } }