partial update transaction work with stock product
This commit is contained in:
247
app/Http/Controllers/WorkProductController.php
Normal file
247
app/Http/Controllers/WorkProductController.php
Normal file
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Work;
|
||||
use App\Models\Product;
|
||||
use App\Models\WorkProduct;
|
||||
use App\Models\Menu;
|
||||
use App\Services\StockService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Yajra\DataTables\DataTables;
|
||||
|
||||
class WorkProductController extends Controller
|
||||
{
|
||||
protected $stockService;
|
||||
|
||||
public function __construct(StockService $stockService)
|
||||
{
|
||||
$this->stockService = $stockService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display work products for a specific work
|
||||
*/
|
||||
public function index(Request $request, $workId)
|
||||
{
|
||||
$menu = Menu::where('link', 'work.index')->first();
|
||||
abort_if(Gate::denies('view', $menu), 403, 'Unauthorized User');
|
||||
|
||||
$work = Work::with('category')->findOrFail($workId);
|
||||
|
||||
if ($request->ajax()) {
|
||||
Log::info('Work products index AJAX request for work ID: ' . $workId);
|
||||
|
||||
$workProducts = WorkProduct::with(['product', 'product.category'])
|
||||
->where('work_id', $workId)
|
||||
->get();
|
||||
|
||||
Log::info('Found ' . $workProducts->count() . ' work products');
|
||||
|
||||
return DataTables::of($workProducts)
|
||||
->addIndexColumn()
|
||||
->addColumn('product_name', function($row) {
|
||||
return $row->product->name;
|
||||
})
|
||||
->addColumn('product_code', function($row) {
|
||||
return $row->product->code;
|
||||
})
|
||||
->addColumn('product_category', function($row) {
|
||||
return $row->product->category ? $row->product->category->name : '-';
|
||||
})
|
||||
->addColumn('unit', function($row) {
|
||||
return $row->product->unit;
|
||||
})
|
||||
->addColumn('quantity_required', function($row) {
|
||||
return number_format($row->quantity_required, 2);
|
||||
})
|
||||
->addColumn('action', function($row) use ($menu) {
|
||||
$btn = '<div class="d-flex flex-row gap-1">';
|
||||
|
||||
if(Gate::allows('update', $menu)) {
|
||||
$btn .= '<button class="btn btn-warning btn-sm btn-edit-work-product" data-id="'.$row->id.'">
|
||||
Edit
|
||||
</button>';
|
||||
}
|
||||
|
||||
if(Gate::allows('delete', $menu)) {
|
||||
$btn .= '<button class="btn btn-danger btn-sm btn-delete-work-product" data-id="'.$row->id.'">
|
||||
Hapus
|
||||
</button>';
|
||||
}
|
||||
|
||||
$btn .= '</div>';
|
||||
return $btn;
|
||||
})
|
||||
->rawColumns(['action'])
|
||||
->make(true);
|
||||
}
|
||||
|
||||
$products = Product::where('active', true)->with('category')->get();
|
||||
|
||||
return view('back.master.work-products', compact('work', 'products'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store work product relationship
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$menu = Menu::where('link', 'work.index')->first();
|
||||
abort_if(Gate::denies('create', $menu), 403, 'Unauthorized User');
|
||||
|
||||
$request->validate([
|
||||
'work_id' => 'required|exists:works,id',
|
||||
'product_id' => 'required|exists:products,id',
|
||||
'quantity_required' => 'required|numeric|min:0.01',
|
||||
'notes' => 'nullable|string'
|
||||
]);
|
||||
|
||||
// Check if combination already exists
|
||||
$exists = WorkProduct::where('work_id', $request->work_id)
|
||||
->where('product_id', $request->product_id)
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
return response()->json([
|
||||
'status' => 422,
|
||||
'message' => 'Produk sudah ditambahkan ke pekerjaan ini'
|
||||
], 422);
|
||||
}
|
||||
|
||||
WorkProduct::create($request->all());
|
||||
|
||||
return response()->json([
|
||||
'status' => 200,
|
||||
'message' => 'Produk berhasil ditambahkan ke pekerjaan'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show work product for editing
|
||||
*/
|
||||
public function show($workId, $workProductId)
|
||||
{
|
||||
$menu = Menu::where('link', 'work.index')->first();
|
||||
abort_if(Gate::denies('view', $menu), 403, 'Unauthorized User');
|
||||
|
||||
try {
|
||||
$workProduct = WorkProduct::with(['work', 'product', 'product.category'])
|
||||
->where('work_id', $workId)
|
||||
->where('id', $workProductId)
|
||||
->firstOrFail();
|
||||
|
||||
return response()->json([
|
||||
'status' => 200,
|
||||
'data' => $workProduct
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error fetching work product: ' . $e->getMessage());
|
||||
return response()->json([
|
||||
'status' => 404,
|
||||
'message' => 'Work product tidak ditemukan'
|
||||
], 404);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update work product relationship
|
||||
*/
|
||||
public function update(Request $request, $workId, $workProductId)
|
||||
{
|
||||
$menu = Menu::where('link', 'work.index')->first();
|
||||
abort_if(Gate::denies('update', $menu), 403, 'Unauthorized User');
|
||||
|
||||
$request->validate([
|
||||
'quantity_required' => 'required|numeric|min:0.01',
|
||||
'notes' => 'nullable|string'
|
||||
]);
|
||||
|
||||
try {
|
||||
$workProduct = WorkProduct::where('work_id', $workId)
|
||||
->where('id', $workProductId)
|
||||
->firstOrFail();
|
||||
|
||||
$workProduct->update($request->only(['quantity_required', 'notes']));
|
||||
|
||||
return response()->json([
|
||||
'status' => 200,
|
||||
'message' => 'Data produk pekerjaan berhasil diupdate'
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error updating work product: ' . $e->getMessage());
|
||||
return response()->json([
|
||||
'status' => 404,
|
||||
'message' => 'Work product tidak ditemukan'
|
||||
], 404);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove work product relationship
|
||||
*/
|
||||
public function destroy($workId, $workProductId)
|
||||
{
|
||||
$menu = Menu::where('link', 'work.index')->first();
|
||||
abort_if(Gate::denies('delete', $menu), 403, 'Unauthorized User');
|
||||
|
||||
try {
|
||||
$workProduct = WorkProduct::where('work_id', $workId)
|
||||
->where('id', $workProductId)
|
||||
->firstOrFail();
|
||||
|
||||
$workProduct->delete();
|
||||
|
||||
return response()->json([
|
||||
'status' => 200,
|
||||
'message' => 'Produk berhasil dihapus dari pekerjaan'
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error deleting work product: ' . $e->getMessage());
|
||||
return response()->json([
|
||||
'status' => 404,
|
||||
'message' => 'Work product tidak ditemukan'
|
||||
], 404);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stock prediction for work
|
||||
*/
|
||||
public function stockPrediction(Request $request, $workId)
|
||||
{
|
||||
$quantity = $request->get('quantity', 1);
|
||||
$prediction = $this->stockService->getStockUsagePrediction($workId, $quantity);
|
||||
|
||||
return response()->json([
|
||||
'status' => 200,
|
||||
'data' => $prediction
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check stock availability for work at specific dealer
|
||||
*/
|
||||
public function checkStock(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'work_id' => 'required|exists:works,id',
|
||||
'dealer_id' => 'required|exists:dealers,id',
|
||||
'quantity' => 'required|integer|min:1'
|
||||
]);
|
||||
|
||||
$availability = $this->stockService->checkStockAvailability(
|
||||
$request->work_id,
|
||||
$request->dealer_id,
|
||||
$request->quantity
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'status' => 200,
|
||||
'data' => $availability
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user