. */ declare(strict_types=1); namespace FireflyIII\Api\V1\Requests\Models\Bill; use FireflyIII\Rules\IsBoolean; use FireflyIII\Rules\IsValidPositiveAmount; use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ConvertsDataTypes; use Illuminate\Contracts\Validation\Validator; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Support\Facades\Log; use TypeError; use ValueError; /** * Class StoreRequest */ class StoreRequest extends FormRequest { use ChecksLogin; use ConvertsDataTypes; protected array $acceptedRoles = []; /** * Get all data from the request. */ public function getAll(): array { Log::debug('Raw fields in Bill StoreRequest', $this->all()); $fields = [ 'name' => ['name', 'convertString'], 'amount_min' => ['amount_min', 'convertString'], 'amount_max' => ['amount_max', 'convertString'], 'currency_id' => ['currency_id', 'convertInteger'], 'currency_code' => ['currency_code', 'convertString'], 'date' => ['date', 'date'], 'end_date' => ['end_date', 'date'], 'extension_date' => ['extension_date', 'date'], 'repeat_freq' => ['repeat_freq', 'convertString'], 'skip' => ['skip', 'convertInteger'], 'active' => ['active', 'boolean'], 'order' => ['order', 'convertInteger'], 'notes' => ['notes', 'stringWithNewlines'], 'object_group_id' => ['object_group_id', 'convertInteger'], 'object_group_title' => ['object_group_title', 'convertString'], ]; return $this->getAllData($fields); } /** * The rules that the incoming request must be matched against. */ public function rules(): array { return [ 'name' => ['min:1', 'max:255', 'uniqueObjectForUser:bills,name'], 'amount_min' => ['required', new IsValidPositiveAmount()], 'amount_max' => ['required', new IsValidPositiveAmount()], 'currency_id' => ['numeric', 'exists:transaction_currencies,id'], 'currency_code' => ['min:3', 'max:51', 'exists:transaction_currencies,code'], 'date' => ['date', 'required', 'after:1970-01-02', 'before:2038-01-17'], 'end_date' => ['nullable', 'date', 'after:date', 'after:1970-01-02', 'before:2038-01-17'], 'extension_date' => ['nullable', 'date', 'after:date', 'after:1970-01-02', 'before:2038-01-17'], 'repeat_freq' => ['in:weekly,monthly,quarterly,half-year,yearly', 'required'], 'skip' => ['min:0', 'max:31', 'numeric'], 'active' => [new IsBoolean()], 'notes' => ['nullable', 'min:1', 'max:32768'], ]; } /** * Configure the validator instance. */ public function withValidator(Validator $validator): void { $validator->after(static function (Validator $validator): void { $data = $validator->getData(); $min = $data['amount_min'] ?? '0'; $max = $data['amount_max'] ?? '0'; if (is_array($min) || is_array($max)) { $validator->errors()->add('amount_min', (string) trans('validation.generic_invalid')); $validator->errors()->add('amount_max', (string) trans('validation.generic_invalid')); $min = '0'; $max = '0'; } $result = false; try { $result = bccomp($min, $max); } catch (ValueError $e) { Log::error($e->getMessage()); $validator->errors()->add('amount_min', (string) trans('validation.generic_invalid')); $validator->errors()->add('amount_max', (string) trans('validation.generic_invalid')); } if (1 === $result) { $validator->errors()->add('amount_min', (string) trans('validation.amount_min_over_max')); } }); $failed = false; try { $failed = $validator->fails(); } catch (TypeError $e) { Log::error($e->getMessage()); } if ($failed) { Log::channel('audit')->error(sprintf('Validation errors in %s', self::class), $validator->errors()->toArray()); } } }