51 lines
2.4 KiB
PHP
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];
|
|
}
|
|
}
|