user() ?? Auth::guard('receptionist')->user(); if (!$user) return response()->json(['message' => 'Unauthenticated'], 401); $branchId = $user->isReceptionist() ? $user->branch_id : $request->query('branch_id'); $startDate = $request->query('start_date'); $endDate = $request->query('end_date'); $paymentMethod = $request->query('payment_method'); $query = Collection::with(['branch', 'type', 'items.product']); if ($branchId) { $query->where('branch_id', $branchId); } if ($startDate) { $query->where('date', '>=', $startDate); } if ($endDate) { $query->where('date', '<=', $endDate); } if ($paymentMethod) { $query->where('payment_method', $paymentMethod); } return response()->json($query->orderBy('date', 'desc')->get()->map(function($c) { $originalAmount = $c->items->sum('subtotal'); $c->is_adjusted = $originalAmount > 0 && abs($c->amount - $originalAmount) > 0.01; $c->original_amount = $originalAmount; return $c; })); } public function store(Request $request) { $user = Auth::guard('web')->user() ?? Auth::guard('receptionist')->user(); if (!$user) return response()->json(['message' => 'Unauthenticated'], 401); $data = $request->all(); if ($user->isReceptionist()) { $data['branch_id'] = $user->branch_id; } $validated = \Illuminate\Support\Facades\Validator::make($data, [ 'date' => 'required|date', 'branch_id' => 'required|exists:branches,id', 'collection_type_id' => 'required|exists:collection_types,id', 'payment_method' => 'required|string', 'amount' => 'required|numeric|min:0', 'remarks' => 'nullable|string', 'items' => 'nullable|array', 'items.*.product_id' => 'required_with:items|exists:products,id', 'items.*.quantity' => 'required_with:items|integer|min:1', 'items.*.unit_price' => 'required_with:items|numeric|min:0', ])->validate(); return DB::transaction(function () use ($validated) { $count = Collection::count() + 1; $transactionId = "COL-" . (1000 + $count); $collection = Collection::create([ 'date' => $validated['date'], 'branch_id' => $validated['branch_id'], 'collection_type_id' => $validated['collection_type_id'], 'payment_method' => $validated['payment_method'], 'amount' => $validated['amount'], 'remarks' => $validated['remarks'], 'transaction_id' => $transactionId ]); $type = CollectionType::find($validated['collection_type_id']); if (isset($validated['items']) && !empty($validated['items'])) { foreach ($validated['items'] as $item) { CollectionItem::create([ 'collection_id' => $collection->id, 'product_id' => $item['product_id'], 'quantity' => $item['quantity'], 'unit_price' => $item['unit_price'], 'subtotal' => $item['quantity'] * $item['unit_price'] ]); // If it's a "Product sale" type, we should also track inventory // Checking if the type name is "Product sale" if (strtolower($type->name) === 'product sale' || strtolower($type->name) === 'product saled') { $product = Product::find($item['product_id']); $newStock = $product->current_stock - $item['quantity']; $status = 'In Stock'; if ($newStock <= 0) $status = 'Out of Stock'; else if ($newStock <= $product->reorder_level) $status = 'Low Stock'; $product->update([ 'current_stock' => $newStock, 'status' => $status ]); StockAdjustment::create([ 'product_id' => $product->id, 'adjustment_qty' => -$item['quantity'], 'new_stock' => $newStock, 'adjustment_date' => $validated['date'], 'reason' => 'Sale', 'remarks' => "Collection #{$transactionId}" ]); } } } // Record to Ledger Account::create([ 'date' => $validated['date'], 'time' => Carbon::parse($validated['date'])->isToday() ? Carbon::now()->toTimeString() : '00:00:00', 'credit' => $validated['amount'], 'debit' => 0, 'type' => 'income', 'branch_id' => $validated['branch_id'], 'accountable_id' => $collection->id, 'accountable_type' => Collection::class, 'description' => "Collection [{$type->name}] #{$transactionId}" ]); return response()->json($collection->load(['branch', 'type', 'items.product']), 201); }); } public function show($id) { $collection = Collection::with(['branch', 'type', 'items.product'])->findOrFail($id); $user = Auth::guard('web')->user() ?? Auth::guard('receptionist')->user(); if ($user && $user->isReceptionist() && $collection->branch_id != $user->branch_id) { return response()->json(['message' => 'Unauthorized'], 403); } return response()->json($collection); } }