buckets/app/Http/Requests/UpdateStreamRequest.php

110 lines
3.7 KiB
PHP

<?php
namespace App\Http\Requests;
use App\Models\Stream;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class UpdateStreamRequest extends FormRequest
{
public function authorize(): bool
{
// In production, check if user owns the stream/scenario
// For now, allow all requests
return true;
}
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'type' => ['required', Rule::in([Stream::TYPE_INCOME, Stream::TYPE_EXPENSE])],
'amount' => ['required', 'numeric', 'min:0.01', 'max:999999999.99'],
'frequency' => [
'required',
Rule::in([
Stream::FREQUENCY_ONCE,
Stream::FREQUENCY_WEEKLY,
Stream::FREQUENCY_BIWEEKLY,
Stream::FREQUENCY_MONTHLY,
Stream::FREQUENCY_QUARTERLY,
Stream::FREQUENCY_YEARLY,
]),
],
'start_date' => ['required', 'date', 'date_format:Y-m-d'],
'end_date' => ['nullable', 'date', 'date_format:Y-m-d', 'after_or_equal:start_date'],
'bucket_id' => ['nullable', 'exists:buckets,uuid'],
'description' => ['nullable', 'string', 'max:1000'],
'is_active' => ['boolean'],
];
}
public function messages(): array
{
return [
'type.in' => 'The type must be either income or expense.',
'frequency.in' => 'Invalid frequency selected.',
'amount.min' => 'The amount must be greater than zero.',
'amount.max' => 'The amount is too large.',
'end_date.after_or_equal' => 'The end date must be after or equal to the start date.',
'bucket_id.exists' => 'The selected bucket does not exist.',
];
}
public function withValidator($validator): void
{
$validator->after(function ($validator) {
/** @var Stream $stream */
$stream = $this->route('stream');
// Validate that the bucket belongs to the stream's scenario
if ($this->bucket_id) {
$bucketBelongsToScenario = $stream->scenario->buckets()
->where('uuid', $this->bucket_id)
->exists();
if (! $bucketBelongsToScenario) {
$validator->errors()->add('bucket_id', 'The selected bucket does not belong to this scenario.');
}
}
// For expense streams, bucket is required
if ($this->type === Stream::TYPE_EXPENSE && ! $this->bucket_id) {
$validator->errors()->add('bucket_id', 'A bucket must be selected for expense streams.');
}
});
}
protected function prepareForValidation(): void
{
// Ensure dates are in the correct format
if ($this->has('start_date') && ! empty($this->start_date)) {
$this->merge([
'start_date' => date('Y-m-d', strtotime($this->start_date)),
]);
}
if ($this->has('end_date') && ! empty($this->end_date)) {
$this->merge([
'end_date' => date('Y-m-d', strtotime($this->end_date)),
]);
}
// Convert amount to float
if ($this->has('amount')) {
$this->merge([
'amount' => (float) $this->amount,
]);
}
// Default is_active to current value if not provided
if (! $this->has('is_active')) {
/** @var Stream $stream */
$stream = $this->route('stream');
$this->merge([
'is_active' => $stream->is_active,
]);
}
}
}