Files
compras/app/Services/ComparisonPolicy.php
nala c6373365bf
tests / ci (push) Canceled after 0s
commit9
2026-10-30 20:02:30 +02:00

51 lines
2.4 KiB
PHP

<?php
namespace App\Services;
use App\Models\Requisition;
use App\Models\Tenant;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
class ComparisonPolicy
{
public const DEFAULTS = ['revision' => 0, 'configured' => false, 'minimum_proposals' => 3, 'minimum_evaluators' => 2,
'weights' => ['price' => 40, 'quality' => 20, 'delivery' => 15, 'history' => 15, 'payment' => 10]];
/** @return array{revision: int, configured: bool, minimum_proposals: int, minimum_evaluators: int, weights: array<string,int>} */
public function company(Tenant $tenant): array
{
return $tenant->comparison_policy === null ? self::DEFAULTS : $this->checked($tenant->comparison_policy);
}
/** @return array{revision: int, configured: bool, minimum_proposals: int, minimum_evaluators: int, weights: array<string,int>} */
public function forRequest(Requisition $request): array
{
return $request->comparison_policy === null ? self::DEFAULTS : $this->checked($request->comparison_policy);
}
/** @param array<string,mixed> $data
* @return array{revision: int, configured: bool, minimum_proposals: int, minimum_evaluators: int, weights: array<string,int>}
*/
public function checked(array $data): array
{
$rules = ['revision' => 'required|integer|min:0', 'configured' => 'required|boolean',
'minimum_proposals' => 'required|integer|between:1,100', 'minimum_evaluators' => 'required|integer|between:1,100',
'weights' => 'required|array:price,quality,delivery,history,payment'];
foreach (array_keys(self::DEFAULTS['weights']) as $key) {
$rules['weights.'.$key] = 'required|integer|between:0,100';
}
$valid = Validator::make($data, $rules)->validate();
$weights = [];
foreach (array_keys(self::DEFAULTS['weights']) as $key) {
$weights[$key] = (int) $valid['weights'][$key];
}
if (array_sum($weights) !== 100) {
throw ValidationException::withMessages(['weights' => 'A soma das ponderações deve ser exactamente 100%.']);
}
return ['revision' => (int) $valid['revision'], 'configured' => (bool) $valid['configured'],
'minimum_proposals' => (int) $valid['minimum_proposals'], 'minimum_evaluators' => (int) $valid['minimum_evaluators'], 'weights' => $weights];
}
}