tenant_id; $query = InventoryTransaction::when($tenantId, function($q) use ($tenantId) { $q->where('tenant_id', $tenantId); })->with(['item', 'warehouse', 'project', 'currency', 'createdBy']); if ($request->filled('type')) { $query->where('type', $request->type); } if ($request->filled('item_id')) { $query->where('item_id', $request->item_id); } if ($request->filled('warehouse_id')) { $query->where('warehouse_id', $request->warehouse_id); } if ($request->filled('project_id')) { $query->where('project_id', $request->project_id); } if ($request->filled('from_date')) { $query->where('date', '>=', $request->from_date); } if ($request->filled('to_date')) { $query->where('date', '<=', $request->to_date); } $transactions = $query->orderBy('date', 'desc')->orderBy('created_at', 'desc')->paginate(20)->appends($request->query()); $items = Item::when($tenantId, function($q) use ($tenantId) { $q->where('tenant_id', $tenantId); })->orderBy('name')->get(); $warehouses = Warehouse::when($tenantId, function($q) use ($tenantId) { $q->where('tenant_id', $tenantId); })->where('is_active', true)->orderBy('name')->get(); $projects = Project::when($tenantId, function($q) use ($tenantId) { $q->where('tenant_id', $tenantId); })->whereIn('status', ['planning', 'in_progress'])->get(); $types = ['in', 'out', 'return', 'adjustment']; return view('inventory-transactions.index', compact('transactions', 'items', 'warehouses', 'projects', 'types')); } public function create() { $tenantId = tenant_id() ?? Auth::user()?->tenant_id; $warehouses = Warehouse::when($tenantId, function($q) use ($tenantId) { $q->where('tenant_id', $tenantId); })->orderBy('name')->get(); $warehouses = Warehouse::when($tenantId, function($q) use ($tenantId) { $q->where('tenant_id', $tenantId); })->where('is_active', true)->orderBy('name')->get(); $projects = Project::when($tenantId, function($q) use ($tenantId) { $q->where('tenant_id', $tenantId); })->whereIn('status', ['planning', 'in_progress'])->get(); $currencies = Currency::all(); $types = ['in' => 'in', 'out' => 'out', 'return' => 'return', 'adjustment' => 'adjustment']; return view('inventory-transactions.form', compact('items', 'warehouses', 'projects', 'currencies', 'types')); } public function store(Request $request) { $tenantId = tenant_id() ?? Auth::user()?->tenant_id; $validated = $request->validate([ 'type' => 'required|in:in,out,return,adjustment', 'item_id' => 'required|exists:items,id', 'warehouse_id' => 'required|exists:warehouses,id', 'project_id' => 'nullable|exists:projects,id', 'quantity' => 'required|numeric|min:0.01', 'unit_price' => 'nullable|numeric|min:0', 'currency_id' => 'nullable|exists:currencies,id', 'date' => 'required|date', 'reference' => 'nullable|string|max:100', 'description' => 'nullable|string', ]); // بررسی موجودی برای خروج if ($validated['type'] === 'out') { $currentStock = $this->getCurrentStock($validated['item_id'], $validated['warehouse_id']); if ($currentStock < $validated['quantity']) { return back()->withErrors(['quantity' => __('inventory.insufficient_stock')]) ->withInput(); } } $validated['tenant_id'] = $tenantId; $validated['created_by'] = Auth::id(); if (!empty($validated['unit_price']) && !empty($validated['quantity'])) { $validated['total_price'] = $validated['unit_price'] * $validated['quantity']; } InventoryTransaction::create($validated); return redirect() ->route('inventory-transactions.index') ->with('success', __('inventory.transaction_created_successfully')); } public function show(InventoryTransaction $inventoryTransaction) { $inventoryTransaction->load(['item', 'warehouse', 'project', 'currency', 'createdBy']); return view('inventory-transactions.show', compact('inventoryTransaction')); } public function destroy(InventoryTransaction $inventoryTransaction) { $inventoryTransaction->delete(); return redirect() ->route('inventory-transactions.index') ->with('success', __('inventory.transaction_deleted_successfully')); } public function currentStock(Request $request) { $request->validate([ 'item_id' => 'required|exists:items,id', 'warehouse_id' => 'required|exists:warehouses,id', ]); $stock = $this->getCurrentStock($request->item_id, $request->warehouse_id); return response()->json([ 'current_stock' => $stock, ]); } private function getCurrentStock(int $itemId, int $warehouseId): float { $totalIn = InventoryTransaction::where('item_id', $itemId) ->where('warehouse_id', $warehouseId) ->whereIn('type', ['in', 'return']) ->sum('quantity'); $totalOut = InventoryTransaction::where('item_id', $itemId) ->where('warehouse_id', $warehouseId) ->where('type', 'out') ->sum('quantity'); $adjustments = InventoryTransaction::where('item_id', $itemId) ->where('warehouse_id', $warehouseId) ->where('type', 'adjustment') ->sum('quantity'); return (float) ($totalIn - $totalOut + $adjustments); } }