ldc-boutique-cnc/app/Http/Requests/Bo/ResolveOrderRequest.php
2023-04-26 10:28:35 +02:00

131 lines
4.3 KiB
PHP

<?php
namespace App\Http\Requests\Bo;
use App\Models\Payment\Transaction;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\ValidationException;
class ResolveOrderRequest extends FormRequest
{
/**
* Order baskter items
*
* @var \Illuminate\Support\Collection<object>
*/
private $basketItems;
/**
* Order baskter items keyed by id
*
* @var \App\Models\Payment\Transaction|null
*/
private $transactionModel;
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize(): bool
{
return \auth('backend')->check();
}
/**
* Prepare the data for validation.
*
* @return void
*/
public function prepareForValidation(): void
{
$this->transactionModel = $this->transaction_id ? Transaction::query()
->where('id', $this->transaction_id)
->whereHas('order', function (Builder $q) {
$q->where('id', $this->order->id);
})->first() : null;
$this->basketItems = \collect(\optional(\optional($this->transactionModel)->order)->basket);
$this->collect('items')->pluck('index')->each(function (string $index) {
if (!$this->basketItems->where('id', $index)->count()) {
$message = trans("L'item :item n'existe pas dans les items de la transaction :reference", [
'item' => $index,
'reference' => $this->transactionModel->reference,
]);
\report(new \RuntimeException($message));
throw ValidationException::withMessages([
'error' => $message
]);
}
});
$this->merge([
'transaction' => $this->transactionModel,
'items' => $this->items ?? [],
'amountToRefund' => \intval($this->collect('items')
->pluck('quantity', 'index')->filter()->map(function ($quantity, $index) {
return $this->basketItems->where('id', $index)->first()->options->price_ttc * \intval($quantity);
})->sum() ?? 0)
]);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
* @throws \Illuminate\Validation\ValidationException If the refund amount is above transaction amount.
*/
public function rules()
{
if (
$this->transactionModel and $this->amountToRefund and
\intval($this->transactionModel->amount->getAmount()) < $this->amountToRefund
) {
throw ValidationException::withMessages([
'error' => trans(
'Le montant des objets devant être remboursé est supérieur au montant de la transaction'
)
]);
}
return [
'reason' => 'required|string|min:3|max:80',
'transaction' => 'required',
'amountToRefund' => 'required|numeric|min:0',
'items' => 'present',
'items.*' => 'array',
'items.*.index' => [
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
'required', function ($attribute, $inputValue, $fail) {
if (!$this->transactionModel) {
return;
}
if (!$this->basketItems->where('id', $inputValue)->count()) {
$fail(\trans(':attribute :value ne fait pas partie de cette commande', [
'value' => $inputValue
]));
return;
}
}
],
'items.*.disabled' => 'required|boolean',
'items.*.quantity' => 'required|integer|min:1',
];
}
/**
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes(): array
{
return [
'items' => trans('produits'),
'items.*' => trans('produit'),
'items.*.quantity' => trans('quantité du produit'),
'items.*.index' => trans('index panier du produit'),
'items.*.disabled' => trans('prendre en compte le produit'),
];
}
}