66 lines
3.0 KiB
PHP
66 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Enums\PurchasingRole;
|
|
use App\Models\Budget;
|
|
use App\Models\BudgetReinforcement;
|
|
use App\Models\CostCenter;
|
|
use App\Services\CommonBudget;
|
|
use App\Services\ConflictGuard;
|
|
use App\Services\CurrentActor;
|
|
use Brick\Math\BigDecimal;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\Rule;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class BudgetController extends Controller
|
|
{
|
|
private function access(Request $request): void
|
|
{
|
|
abort_unless(in_array($request->user()->purchasing_role, [PurchasingRole::Admin, PurchasingRole::Finance]), 403);
|
|
}
|
|
|
|
public function index(Request $request): Response
|
|
{
|
|
$this->access($request);
|
|
|
|
return Inertia::render('budgets/index', ['centers' => CostCenter::query()->orderBy('code')->get(), 'budgets' => Budget::query()->latest('id')->get()->map(function (Budget $budget) use ($request) {
|
|
$adapter = app(CommonBudget::class);
|
|
|
|
return [...$budget->toArray(), ...$adapter->execute(fn () => $adapter->for($request->user())->balance($budget->id))];
|
|
}), 'reinforcements' => BudgetReinforcement::query()->latest('id')->paginate(20)]);
|
|
}
|
|
|
|
public function store(Request $request): RedirectResponse
|
|
{
|
|
$this->access($request);
|
|
$data = $request->validate(['cost_center_id' => ['required', 'integer', Rule::exists('cost_centers', 'id')->where('tenant_id', $request->user()->tenant_id)], 'year' => 'required|integer|min:2026|max:2100', 'includes_tax' => 'required|boolean', 'amount' => ['required', 'regex:/^\d{1,12}(\.\d{1,2})?$/'], 'reason' => 'required|string|max:4000']);
|
|
$kind = $request->validate(['kind' => ['sometimes', Rule::in(['operating', 'investment'])]])['kind'] ?? 'operating';
|
|
DB::transaction(function () use ($request, $data, $kind) {
|
|
app(ConflictGuard::class)->lockCompany($request->user());
|
|
app(CurrentActor::class)->lock($request->user(), [PurchasingRole::Admin, PurchasingRole::Finance]);
|
|
$adapter = app(CommonBudget::class);
|
|
$adapter->execute(fn () => $adapter->for($request->user())->create(['cost_center_id' => (int) $data['cost_center_id'], 'year' => (int) $data['year'], 'kind' => $kind, 'includes_tax' => (bool) $data['includes_tax'], 'amount_minor' => BigDecimal::of($data['amount'])->multipliedBy(100)->toInt(), 'reason' => $data['reason']]));
|
|
});
|
|
|
|
return back();
|
|
}
|
|
|
|
public function approve(Request $request, Budget $budget): RedirectResponse
|
|
{
|
|
$this->access($request);
|
|
DB::transaction(function () use ($request, $budget) {
|
|
app(ConflictGuard::class)->lockCompany($request->user());
|
|
app(CurrentActor::class)->lock($request->user(), [PurchasingRole::Admin, PurchasingRole::Finance]);
|
|
$adapter = app(CommonBudget::class);
|
|
$adapter->execute(fn () => $adapter->for($request->user())->approve($budget->id));
|
|
});
|
|
|
|
return back();
|
|
}
|
|
}
|