96 lines
5.4 KiB
PHP
96 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\ConflictDeclaration;
|
|
use App\Models\Requisition;
|
|
use App\Models\Supplier;
|
|
use App\Services\ConflictGuard;
|
|
use App\Services\RequisitionWorkflow;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\Rule;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class ConflictDeclarationController extends Controller
|
|
{
|
|
public function index(Request $request): Response
|
|
{
|
|
return Inertia::render('conflicts/index', [
|
|
'declarations' => ConflictDeclaration::query()->visibleTo($request->user())
|
|
->with(['author:id,name', 'supplier:id,name', 'requisition:id,number', 'successor:id,previous_id'])
|
|
->latest('id')->paginate(15),
|
|
// These minimal choices allow personal declarations without granting supplier-management access.
|
|
'suppliers' => Supplier::query()->orderBy('name')->get(['id', 'name']),
|
|
'requisitions' => Requisition::query()->visibleTo($request->user())->latest()->get(['id', 'number']),
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request, ConflictGuard $guard, RequisitionWorkflow $workflow): RedirectResponse
|
|
{
|
|
$data = $request->validate([
|
|
'scope' => ['required', Rule::in(['supplier', 'process', 'process_supplier'])],
|
|
'supplier_id' => ['nullable', 'required_if:scope,supplier,process_supplier', 'prohibited_if:scope,process', 'integer', Rule::exists('suppliers', 'id')->where('tenant_id', $request->user()->tenant_id)],
|
|
'requisition_id' => ['nullable', 'required_if:scope,process,process_supplier', 'prohibited_if:scope,supplier', 'integer', Rule::exists('requisitions', 'id')->where('tenant_id', $request->user()->tenant_id)],
|
|
'has_conflict' => 'required|boolean', 'known_since' => 'required|date_format:Y-m-d|before_or_equal:today',
|
|
'reason' => 'required|string|min:10|max:5000',
|
|
'user_id' => 'prohibited', 'tenant_id' => 'prohibited', 'declared_at' => 'prohibited',
|
|
'root_id' => 'prohibited', 'previous_id' => 'prohibited',
|
|
]);
|
|
DB::transaction(function () use ($request, $guard, $workflow, $data) {
|
|
$guard->lockCompany($request->user());
|
|
if (! empty($data['requisition_id'])) {
|
|
Requisition::query()->visibleTo($request->user())->findOrFail($data['requisition_id']);
|
|
}
|
|
$declaration = ConflictDeclaration::query()->create([
|
|
'tenant_id' => $request->user()->tenant_id, 'user_id' => $request->user()->id,
|
|
'supplier_id' => $data['supplier_id'] ?? null, 'requisition_id' => $data['requisition_id'] ?? null,
|
|
'has_conflict' => $data['has_conflict'], 'known_since' => $data['known_since'],
|
|
'reason' => $data['reason'], 'declared_at' => now(),
|
|
]);
|
|
$workflow->audit($request->user(), 'conflict.declared', null, null, $declaration->toArray());
|
|
});
|
|
|
|
return to_route('conflicts.index');
|
|
}
|
|
|
|
public function show(Request $request, ConflictDeclaration $declaration): Response
|
|
{
|
|
ConflictDeclaration::query()->visibleTo($request->user())->findOrFail($declaration->id);
|
|
$rootId = $declaration->root_id ?? $declaration->id;
|
|
$history = ConflictDeclaration::query()->where(fn ($query) => $query->whereKey($rootId)->orWhere('root_id', $rootId))
|
|
->with(['author:id,name', 'supplier:id,name', 'requisition:id,number'])->orderBy('id')->get();
|
|
$latest = $history->last();
|
|
|
|
return Inertia::render('conflicts/show', ['history' => $history, 'canCorrect' => $latest?->user_id === $request->user()->id]);
|
|
}
|
|
|
|
public function update(Request $request, ConflictDeclaration $declaration, ConflictGuard $guard, RequisitionWorkflow $workflow): RedirectResponse
|
|
{
|
|
abort_unless($declaration->user_id === $request->user()->id, 403);
|
|
$data = $request->validate([
|
|
'known_since' => 'required|date_format:Y-m-d|before_or_equal:today', 'reason' => 'required|string|min:10|max:5000',
|
|
'has_conflict' => 'prohibited', 'supplier_id' => 'prohibited', 'requisition_id' => 'prohibited',
|
|
'user_id' => 'prohibited', 'tenant_id' => 'prohibited', 'declared_at' => 'prohibited',
|
|
'root_id' => 'prohibited', 'previous_id' => 'prohibited',
|
|
]);
|
|
DB::transaction(function () use ($request, $guard, $workflow, $declaration, $data) {
|
|
$guard->lockCompany($request->user());
|
|
$declaration = ConflictDeclaration::query()->lockForUpdate()->findOrFail($declaration->id);
|
|
if ($declaration->successor()->exists()) {
|
|
throw ValidationException::withMessages(['history' => 'Já existe uma correcção mais recente. Reabra o histórico antes de corrigir.']);
|
|
}
|
|
$revision = ConflictDeclaration::query()->create([
|
|
...$declaration->only(['tenant_id', 'user_id', 'supplier_id', 'requisition_id', 'has_conflict']),
|
|
...$data, 'declared_at' => now(), 'root_id' => $declaration->root_id ?? $declaration->id, 'previous_id' => $declaration->id,
|
|
]);
|
|
$workflow->audit($request->user(), 'conflict.corrected', null, $declaration->toArray(), $revision->toArray());
|
|
});
|
|
|
|
return to_route('conflicts.show', $declaration);
|
|
}
|
|
}
|