112 lines
4.3 KiB
PHP
112 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Reports;
|
|
|
|
use App\Enums\ExpenseCategory;
|
|
use App\Enums\FundingSource;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Reports\StoreMedicationExpenseValuesRequest;
|
|
use App\Models\Department;
|
|
use App\Models\MedicationExpenseRow;
|
|
use App\Models\MedicationExpenseValue;
|
|
use App\Models\ReportPeriod;
|
|
use App\Models\Team;
|
|
use App\Services\Reports\MedicationExpenseService;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class MedicationExpenseController extends Controller
|
|
{
|
|
/**
|
|
* Display the medication expense page.
|
|
*/
|
|
public function index(Request $request, Team $current_team, MedicationExpenseService $medicationExpenseService): Response
|
|
{
|
|
$periods = ReportPeriod::query()
|
|
->whereBelongsTo($current_team)
|
|
->orderByDesc('year')
|
|
->orderByDesc('month')
|
|
->get();
|
|
|
|
$departments = Department::query()
|
|
->where('is_active', true)
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
/** @var ReportPeriod|null $selectedPeriod */
|
|
$selectedPeriod = $periods->firstWhere('id', $request->integer('period', $periods->first()?->id));
|
|
/** @var Department|null $selectedDepartment */
|
|
$selectedDepartment = $departments->firstWhere('id', $request->integer('department', $departments->first()?->id));
|
|
|
|
$expense = $selectedPeriod && $selectedDepartment
|
|
? $medicationExpenseService->calculateForDepartmentPeriod($selectedPeriod, $selectedDepartment)
|
|
: ['matrix' => [], 'totals' => []];
|
|
|
|
return Inertia::render('reports/medication-expenses/Index', [
|
|
'periods' => $periods->map(fn (ReportPeriod $period) => [
|
|
'id' => $period->id,
|
|
'label' => $period->label(),
|
|
'status' => $period->status->value,
|
|
'statusLabel' => $period->status->label(),
|
|
'isEditable' => $period->isEditable(),
|
|
])->values(),
|
|
'departments' => $departments->map(fn (Department $department) => [
|
|
'id' => $department->id,
|
|
'name' => $department->name,
|
|
])->values(),
|
|
'selectedPeriodId' => $selectedPeriod?->id,
|
|
'selectedDepartmentId' => $selectedDepartment?->id,
|
|
'fundingSources' => collect(FundingSource::cases())->map(fn (FundingSource $source) => [
|
|
'value' => $source->value,
|
|
'label' => $source->label(),
|
|
])->all(),
|
|
'expenseCategories' => collect(ExpenseCategory::cases())->map(fn (ExpenseCategory $category) => [
|
|
'value' => $category->value,
|
|
'label' => $category->label(),
|
|
])->all(),
|
|
'values' => $expense['matrix'],
|
|
'totals' => $expense['totals'],
|
|
'canEdit' => $selectedPeriod?->isEditable() ?? false,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Store medication expense values for a department and period.
|
|
*/
|
|
public function storeValues(StoreMedicationExpenseValuesRequest $request, Team $current_team): RedirectResponse
|
|
{
|
|
$period = ReportPeriod::query()
|
|
->whereBelongsTo($current_team)
|
|
->findOrFail($request->integer('report_period_id'));
|
|
|
|
abort_unless($period->isEditable(), 422);
|
|
|
|
$department = Department::query()->findOrFail($request->integer('department_id'));
|
|
|
|
$row = MedicationExpenseRow::query()->firstOrCreate([
|
|
'report_period_id' => $period->id,
|
|
'department_id' => $department->id,
|
|
]);
|
|
|
|
foreach (FundingSource::cases() as $fundingSource) {
|
|
foreach (ExpenseCategory::cases() as $expenseCategory) {
|
|
MedicationExpenseValue::updateOrCreate([
|
|
'medication_expense_row_id' => $row->id,
|
|
'funding_source' => $fundingSource,
|
|
'expense_category' => $expenseCategory,
|
|
], [
|
|
'amount' => (float) ($request->input("values.{$fundingSource->value}.{$expenseCategory->value}") ?? 0),
|
|
]);
|
|
}
|
|
}
|
|
|
|
return to_route('reports.medication-expenses.index', [
|
|
'current_team' => $current_team,
|
|
'period' => $period->id,
|
|
'department' => $department->id,
|
|
]);
|
|
}
|
|
}
|