135 lines
4.6 KiB
PHP
135 lines
4.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Expense;
|
|
use App\Models\Account;
|
|
use App\Models\ExpenseCategory;
|
|
use App\Models\Branch;
|
|
use Illuminate\Http\Request;
|
|
use Carbon\Carbon;
|
|
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
class ExpenseController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
$user = Auth::guard('web')->user() ?? Auth::guard('receptionist')->user();
|
|
if (!$user) return response()->json(['message' => 'Unauthenticated'], 401);
|
|
|
|
$query = Expense::with(['branch', 'category']);
|
|
$branchId = $user->isReceptionist() ? $user->branch_id : $request->query('branch_id');
|
|
$startDate = $request->query('start_date');
|
|
$endDate = $request->query('end_date');
|
|
|
|
if ($branchId) {
|
|
$query->where('branch_id', $branchId);
|
|
}
|
|
if ($startDate) {
|
|
$query->where('date', '>=', $startDate);
|
|
}
|
|
if ($endDate) {
|
|
$query->where('date', '<=', $endDate);
|
|
}
|
|
|
|
return response()->json($query->orderBy('date', 'desc')->get());
|
|
}
|
|
|
|
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',
|
|
'expense_category_id' => 'required|exists:expense_categories,id',
|
|
'expense_type' => 'required|string|in:Account,Petty Cash',
|
|
'amount' => 'required|numeric|min:0',
|
|
'remarks' => 'nullable|string'
|
|
])->validate();
|
|
|
|
// Security check for branch_id if receptionist
|
|
if ($user->isReceptionist() && $validated['branch_id'] != $user->branch_id) {
|
|
return response()->json(['message' => 'Unauthorized branch assignment'], 403);
|
|
}
|
|
|
|
$expense = Expense::create($validated);
|
|
|
|
// Auto-ledgering: Debit from Accounts
|
|
Account::create([
|
|
'date' => $expense->date,
|
|
'time' => Carbon::now()->toTimeString(),
|
|
'credit' => 0,
|
|
'debit' => $expense->amount,
|
|
'type' => 'expense',
|
|
'branch_id' => $expense->branch_id,
|
|
'accountable_id' => $expense->id,
|
|
'accountable_type' => Expense::class,
|
|
'description' => "Expense: {$expense->category->name} - {$expense->remarks}"
|
|
]);
|
|
|
|
return response()->json($expense->load(['branch', 'category']), 201);
|
|
}
|
|
|
|
public function getCategories()
|
|
{
|
|
return response()->json(ExpenseCategory::where('status', 'Active')->get());
|
|
}
|
|
|
|
public function getBranches()
|
|
{
|
|
$user = Auth::guard('web')->user() ?? Auth::guard('receptionist')->user();
|
|
$query = Branch::where('status', 'Active');
|
|
if ($user && $user->isReceptionist()) {
|
|
$query->where('id', $user->branch_id);
|
|
}
|
|
return response()->json($query->get());
|
|
}
|
|
|
|
public function getSalaryHistory(Request $request)
|
|
{
|
|
$user = Auth::guard('web')->user() ?? Auth::guard('receptionist')->user();
|
|
if (!$user) return response()->json(['message' => 'Unauthenticated'], 401);
|
|
|
|
$salaryCategory = ExpenseCategory::where('name', 'Salary')->first();
|
|
if (!$salaryCategory) return response()->json([]);
|
|
|
|
$query = Expense::with(['branch'])
|
|
->where('expense_category_id', $salaryCategory->id);
|
|
|
|
if ($user->isReceptionist()) {
|
|
$query->where('branch_id', $user->branch_id);
|
|
}
|
|
|
|
$expenses = $query->orderBy('date', 'desc')->get();
|
|
|
|
// Group by batch_id
|
|
$grouped = $expenses->groupBy(function ($item) {
|
|
return $item->batch_id ?? 'INDIVIDUAL-' . $item->id;
|
|
})->map(function ($items, $batchId) {
|
|
$first = $items->first();
|
|
$isBulk = strpos($batchId, 'BATCH-') === 0;
|
|
|
|
return [
|
|
'batch_id' => $isBulk ? $batchId : null,
|
|
'is_bulk' => $isBulk,
|
|
'date' => $first->date,
|
|
'branch' => $first->branch?->name ?? 'Mixed',
|
|
'amount' => $items->sum('amount'),
|
|
'remarks' => $isBulk ? "Bulk Salary Release" : $first->remarks,
|
|
'count' => $items->count(),
|
|
'items' => $items // Optional: for detail view
|
|
];
|
|
})->values();
|
|
|
|
return response()->json($grouped);
|
|
}
|
|
}
|