florida_gym/app/Http/Controllers/CollectionController.php
2026-03-11 11:03:12 +05:30

154 lines
6.2 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Collection;
use App\Models\CollectionItem;
use App\Models\CollectionType;
use App\Models\Product;
use App\Models\StockAdjustment;
use App\Models\Account;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
class CollectionController extends Controller
{
public function index(Request $request)
{
$user = Auth::guard('web')->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);
}
}