154 lines
6.2 KiB
PHP
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);
|
|
}
|
|
}
|