PHPStorm can order methods by alphabet, who knew.

This commit is contained in:
James Cole
2024-02-22 20:11:09 +01:00
parent f9d4a43e05
commit 68c9c4ec3c
221 changed files with 5840 additions and 5843 deletions

View File

@@ -77,7 +77,7 @@ class AccountController extends Controller
$query = $data['query'];
$date = $data['date'] ?? today(config('app.timezone'));
$return = [];
$result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
$result = $this->repository->searchAccount((string)$query, $types, $this->parameters->get('limit'));
// TODO this code is duplicated in the V2 Autocomplete controller, which means this code is due to be deprecated.
$defaultCurrency = app('amount')->getDefaultCurrency();
@@ -97,11 +97,11 @@ class AccountController extends Controller
}
$return[] = [
'id' => (string) $account->id,
'id' => (string)$account->id,
'name' => $account->name,
'name_with_balance' => $nameWithBalance,
'type' => $account->accountType->type,
'currency_id' => (string) $currency->id,
'currency_id' => (string)$currency->id,
'currency_name' => $currency->name,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
@@ -114,8 +114,8 @@ class AccountController extends Controller
$return,
static function (array $left, array $right) {
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
$posA = (int) array_search($left['type'], $order, true);
$posB = (int) array_search($right['type'], $order, true);
$posA = (int)array_search($left['type'], $order, true);
$posB = (int)array_search($right['type'], $order, true);
return $posA - $posB;
}

View File

@@ -66,7 +66,7 @@ class BillController extends Controller
$filtered = $result->map(
static function (Bill $item) {
return [
'id' => (string) $item->id,
'id' => (string)$item->id,
'name' => $item->name,
'active' => $item->active,
];

View File

@@ -66,7 +66,7 @@ class BudgetController extends Controller
$filtered = $result->map(
static function (Budget $item) {
return [
'id' => (string) $item->id,
'id' => (string)$item->id,
'name' => $item->name,
];
}

View File

@@ -66,7 +66,7 @@ class CategoryController extends Controller
$filtered = $result->map(
static function (Category $item) {
return [
'id' => (string) $item->id,
'id' => (string)$item->id,
'name' => $item->name,
];
}

View File

@@ -68,7 +68,7 @@ class CurrencyController extends Controller
/** @var TransactionCurrency $currency */
foreach ($collection as $currency) {
$result[] = [
'id' => (string) $currency->id,
'id' => (string)$currency->id,
'name' => $currency->name,
'code' => $currency->code,
'symbol' => $currency->symbol,
@@ -94,7 +94,7 @@ class CurrencyController extends Controller
/** @var TransactionCurrency $currency */
foreach ($collection as $currency) {
$result[] = [
'id' => (string) $currency->id,
'id' => (string)$currency->id,
'name' => sprintf('%s (%s)', $currency->name, $currency->code),
'code' => $currency->code,
'symbol' => $currency->symbol,

View File

@@ -68,7 +68,7 @@ class ObjectGroupController extends Controller
/** @var ObjectGroup $objectGroup */
foreach ($result as $objectGroup) {
$return[] = [
'id' => (string) $objectGroup->id,
'id' => (string)$objectGroup->id,
'name' => $objectGroup->title,
'title' => $objectGroup->title,
];

View File

@@ -75,14 +75,14 @@ class PiggyBankController extends Controller
$currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency;
$objectGroup = $piggy->objectGroups()->first();
$response[] = [
'id' => (string) $piggy->id,
'id' => (string)$piggy->id,
'name' => $piggy->name,
'currency_id' => (string) $currency->id,
'currency_id' => (string)$currency->id,
'currency_name' => $currency->name,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
'object_group_id' => null === $objectGroup ? null : (string) $objectGroup->id,
'object_group_id' => null === $objectGroup ? null : (string)$objectGroup->id,
'object_group_title' => $objectGroup?->title,
];
}
@@ -107,7 +107,7 @@ class PiggyBankController extends Controller
$currentAmount = $this->piggyRepository->getRepetition($piggy)->currentamount ?? '0';
$objectGroup = $piggy->objectGroups()->first();
$response[] = [
'id' => (string) $piggy->id,
'id' => (string)$piggy->id,
'name' => $piggy->name,
'name_with_balance' => sprintf(
'%s (%s / %s)',
@@ -115,12 +115,12 @@ class PiggyBankController extends Controller
app('amount')->formatAnything($currency, $currentAmount, false),
app('amount')->formatAnything($currency, $piggy->targetamount, false),
),
'currency_id' => (string) $currency->id,
'currency_id' => (string)$currency->id,
'currency_name' => $currency->name,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
'object_group_id' => null === $objectGroup ? null : (string) $objectGroup->id,
'object_group_id' => null === $objectGroup ? null : (string)$objectGroup->id,
'object_group_title' => $objectGroup?->title,
];
}

View File

@@ -66,7 +66,7 @@ class RecurrenceController extends Controller
/** @var Recurrence $recurrence */
foreach ($recurrences as $recurrence) {
$response[] = [
'id' => (string) $recurrence->id,
'id' => (string)$recurrence->id,
'name' => $recurrence->title,
'description' => $recurrence->description,
];

View File

@@ -65,7 +65,7 @@ class RuleController extends Controller
/** @var Rule $rule */
foreach ($rules as $rule) {
$response[] = [
'id' => (string) $rule->id,
'id' => (string)$rule->id,
'name' => $rule->title,
'description' => $rule->description,
];

View File

@@ -65,7 +65,7 @@ class RuleGroupController extends Controller
/** @var RuleGroup $group */
foreach ($groups as $group) {
$response[] = [
'id' => (string) $group->id,
'id' => (string)$group->id,
'name' => $group->title,
'description' => $group->description,
];

View File

@@ -68,7 +68,7 @@ class TagController extends Controller
/** @var Tag $tag */
foreach ($result as $tag) {
$array[] = [
'id' => (string) $tag->id,
'id' => (string)$tag->id,
'name' => $tag->tag,
'tag' => $tag->tag,
];

View File

@@ -76,8 +76,8 @@ class TransactionController extends Controller
/** @var TransactionJournal $journal */
foreach ($filtered as $journal) {
$array[] = [
'id' => (string) $journal->id,
'transaction_group_id' => (string) $journal->transaction_group_id,
'id' => (string)$journal->id,
'transaction_group_id' => (string)$journal->transaction_group_id,
'name' => $journal->description,
'description' => $journal->description,
];
@@ -96,7 +96,7 @@ class TransactionController extends Controller
$result = new Collection();
if (is_numeric($data['query'])) {
// search for group, not journal.
$firstResult = $this->groupRepository->find((int) $data['query']);
$firstResult = $this->groupRepository->find((int)$data['query']);
if (null !== $firstResult) {
// group may contain multiple journals, each a result:
foreach ($firstResult->transactionJournals as $journal) {
@@ -114,8 +114,8 @@ class TransactionController extends Controller
/** @var TransactionJournal $journal */
foreach ($result as $journal) {
$array[] = [
'id' => (string) $journal->id,
'transaction_group_id' => (string) $journal->transaction_group_id,
'id' => (string)$journal->id,
'transaction_group_id' => (string)$journal->transaction_group_id,
'name' => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description),
'description' => sprintf('#%d: %s', $journal->transaction_group_id, $journal->description),
];

View File

@@ -65,7 +65,7 @@ class TransactionTypeController extends Controller
foreach ($types as $type) {
// different key for consistency.
$array[] = [
'id' => (string) $type->id,
'id' => (string)$type->id,
'name' => $type->type,
'type' => $type->type,
];

View File

@@ -104,7 +104,7 @@ class AccountController extends Controller
}
$currentSet = [
'label' => $account->name,
'currency_id' => (string) $currency->id,
'currency_id' => (string)$currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,

View File

@@ -76,38 +76,6 @@ abstract class Controller extends BaseController
);
}
/**
* Method to help build URL's.
*/
final protected function buildParams(): string
{
$return = '?';
$params = [];
foreach ($this->parameters as $key => $value) {
if ('page' === $key) {
continue;
}
if ($value instanceof Carbon) {
$params[$key] = $value->format('Y-m-d');
continue;
}
$params[$key] = $value;
}
return $return.http_build_query($params);
}
final protected function getManager(): Manager
{
// create some objects:
$manager = new Manager();
$baseUrl = request()->getSchemeAndHttpHost().'/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
return $manager;
}
/**
* Method to grab all parameters from the URL.
*/
@@ -216,4 +184,36 @@ abstract class Controller extends BaseController
return $bag;
}
/**
* Method to help build URL's.
*/
final protected function buildParams(): string
{
$return = '?';
$params = [];
foreach ($this->parameters as $key => $value) {
if ('page' === $key) {
continue;
}
if ($value instanceof Carbon) {
$params[$key] = $value->format('Y-m-d');
continue;
}
$params[$key] = $value;
}
return $return.http_build_query($params);
}
final protected function getManager(): Manager
{
// create some objects:
$manager = new Manager();
$baseUrl = request()->getSchemeAndHttpHost().'/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
return $manager;
}
}

View File

@@ -70,8 +70,8 @@ class TransactionController extends Controller
// to respond to what is in the $query.
// this is OK because only one thing can be in the query at the moment.
if ($this->isUpdateTransactionAccount($params)) {
$original = $this->repository->find((int) $params['where']['account_id']);
$destination = $this->repository->find((int) $params['update']['account_id']);
$original = $this->repository->find((int)$params['where']['account_id']);
$destination = $this->repository->find((int)$params['update']['account_id']);
/** @var AccountDestroyService $service */
$service = app(AccountDestroyService::class);

View File

@@ -68,6 +68,32 @@ class ExportController extends Controller
return $this->returnExport('accounts');
}
/**
* @throws FireflyException
*/
private function returnExport(string $key): LaravelResponse
{
$date = date('Y-m-d-H-i-s');
$fileName = sprintf('%s-export-%s.csv', $date, $key);
$data = $this->exporter->export();
/** @var LaravelResponse $response */
$response = response($data[$key]);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename='.$fileName)
->header('Content-Transfer-Encoding', 'binary')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', (string)strlen($data[$key]))
;
return $response;
}
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBills
@@ -189,30 +215,4 @@ class ExportController extends Controller
return $this->returnExport('transactions');
}
/**
* @throws FireflyException
*/
private function returnExport(string $key): LaravelResponse
{
$date = date('Y-m-d-H-i-s');
$fileName = sprintf('%s-export-%s.csv', $date, $key);
$data = $this->exporter->export();
/** @var LaravelResponse $response */
$response = response($data[$key]);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename='.$fileName)
->header('Content-Transfer-Encoding', 'binary')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', (string) strlen($data[$key]))
;
return $response;
}
}

View File

@@ -75,28 +75,28 @@ class TagController extends Controller
$genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) {
$currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int) $journal['foreign_currency_id'];
$currencyId = (int)$journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
if (0 !== $currencyId) {
$response[$currencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string) $currencyId,
'currency_id' => (string)$currencyId,
'currency_code' => $journal['currency_code'],
];
$response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']);
$response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose.
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // float but on purpose.
}
if (0 !== $foreignCurrencyId) {
$response[$foreignCurrencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string) $foreignCurrencyId,
'currency_id' => (string)$foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'],
];
$response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']);
$response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; // float but on purpose.
$response[$foreignCurrencyId]['difference_float'] = (float)$response[$foreignCurrencyId]['difference']; // float but on purpose.
}
}
@@ -130,8 +130,8 @@ class TagController extends Controller
/** @var array $journal */
foreach ($genericSet as $journal) {
$currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = (int) $journal['foreign_currency_id'];
$currencyId = (int)$journal['currency_id'];
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
/** @var array $tag */
foreach ($journal['tags'] as $tag) {
@@ -142,15 +142,15 @@ class TagController extends Controller
// on currency ID
if (0 !== $currencyId) {
$response[$key] ??= [
'id' => (string) $tagId,
'id' => (string)$tagId,
'name' => $tag['name'],
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string) $currencyId,
'currency_id' => (string)$currencyId,
'currency_code' => $journal['currency_code'],
];
$response[$key]['difference'] = bcadd($response[$key]['difference'], $journal['amount']);
$response[$key]['difference_float'] = (float) $response[$key]['difference']; // float but on purpose.
$response[$key]['difference_float'] = (float)$response[$key]['difference']; // float but on purpose.
}
// on foreign ID
@@ -158,11 +158,11 @@ class TagController extends Controller
$response[$foreignKey] = $journal[$foreignKey] ?? [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string) $foreignCurrencyId,
'currency_id' => (string)$foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'],
];
$response[$foreignKey]['difference'] = bcadd($response[$foreignKey]['difference'], $journal['foreign_amount']);
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // float but on purpose.
$response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; // float but on purpose.
}
}
}

View File

@@ -118,23 +118,6 @@ class BasicController extends Controller
return response()->json($return);
}
/**
* Check if date is outside session range.
*/
protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference
{
$result = false;
if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) {
$result = true;
}
// start and end in the past? use $end
if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) {
$result = true;
}
return $result;
}
private function getBalanceInformation(Carbon $start, Carbon $end): array
{
// prep some arrays:
@@ -152,7 +135,7 @@ class BasicController extends Controller
/** @var array $transactionJournal */
foreach ($set as $transactionJournal) {
$currencyId = (int) $transactionJournal['currency_id'];
$currencyId = (int)$transactionJournal['currency_id'];
$incomes[$currencyId] ??= '0';
$incomes[$currencyId] = bcadd(
$incomes[$currencyId],
@@ -170,7 +153,7 @@ class BasicController extends Controller
/** @var array $transactionJournal */
foreach ($set as $transactionJournal) {
$currencyId = (int) $transactionJournal['currency_id'];
$currencyId = (int)$transactionJournal['currency_id'];
$expenses[$currencyId] ??= '0';
$expenses[$currencyId] = bcadd($expenses[$currencyId], $transactionJournal['amount']);
$sums[$currencyId] ??= '0';
@@ -189,7 +172,7 @@ class BasicController extends Controller
'key' => sprintf('balance-in-%s', $currency->code),
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => $sums[$currencyId] ?? '0',
'currency_id' => (string) $currency->id,
'currency_id' => (string)$currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
@@ -202,7 +185,7 @@ class BasicController extends Controller
'key' => sprintf('spent-in-%s', $currency->code),
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => $expenses[$currencyId] ?? '0',
'currency_id' => (string) $currency->id,
'currency_id' => (string)$currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
@@ -214,7 +197,7 @@ class BasicController extends Controller
'key' => sprintf('earned-in-%s', $currency->code),
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
'monetary_value' => $incomes[$currencyId] ?? '0',
'currency_id' => (string) $currency->id,
'currency_id' => (string)$currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
@@ -248,7 +231,7 @@ class BasicController extends Controller
'key' => sprintf('bills-paid-in-%s', $info['code']),
'title' => trans('firefly.box_bill_paid_in_currency', ['currency' => $info['symbol']]),
'monetary_value' => $amount,
'currency_id' => (string) $info['id'],
'currency_id' => (string)$info['id'],
'currency_code' => $info['code'],
'currency_symbol' => $info['symbol'],
'currency_decimal_places' => $info['decimal_places'],
@@ -267,7 +250,7 @@ class BasicController extends Controller
'key' => sprintf('bills-unpaid-in-%s', $info['code']),
'title' => trans('firefly.box_bill_unpaid_in_currency', ['currency' => $info['symbol']]),
'monetary_value' => $amount,
'currency_id' => (string) $info['id'],
'currency_id' => (string)$info['id'],
'currency_code' => $info['code'],
'currency_symbol' => $info['symbol'],
'currency_decimal_places' => $info['decimal_places'],
@@ -294,21 +277,21 @@ class BasicController extends Controller
foreach ($spent as $row) {
// either an amount was budgeted or 0 is available.
$amount = (string) ($available[$row['currency_id']] ?? '0');
$amount = (string)($available[$row['currency_id']] ?? '0');
$spentInCurrency = $row['sum'];
$leftToSpend = bcadd($amount, $spentInCurrency);
$days = $today->diffInDays($end) + 1;
$perDay = '0';
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
$perDay = bcdiv($leftToSpend, (string) $days);
$perDay = bcdiv($leftToSpend, (string)$days);
}
$return[] = [
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
'monetary_value' => $leftToSpend,
'currency_id' => (string) $row['currency_id'],
'currency_id' => (string)$row['currency_id'],
'currency_code' => $row['currency_code'],
'currency_symbol' => $row['currency_symbol'],
'currency_decimal_places' => $row['currency_decimal_places'],
@@ -368,7 +351,7 @@ class BasicController extends Controller
'key' => sprintf('net-worth-in-%s', $data['currency_code']),
'title' => trans('firefly.box_net_worth_in_currency', ['currency' => $data['currency_symbol']]),
'monetary_value' => $amount,
'currency_id' => (string) $data['currency_id'],
'currency_id' => (string)$data['currency_id'],
'currency_code' => $data['currency_code'],
'currency_symbol' => $data['currency_symbol'],
'currency_decimal_places' => $data['currency_decimal_places'],
@@ -380,4 +363,21 @@ class BasicController extends Controller
return $return;
}
/**
* Check if date is outside session range.
*/
protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference
{
$result = false;
if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) {
$result = true;
}
// start and end in the past? use $end
if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) {
$result = true;
}
return $result;
}
}

View File

@@ -88,6 +88,35 @@ class ConfigurationController extends Controller
return response()->json($return);
}
/**
* Get all config values.
*/
private function getDynamicConfiguration(): array
{
$isDemoSite = app('fireflyconfig')->get('is_demo_site');
$updateCheck = app('fireflyconfig')->get('permission_update_check');
$lastCheck = app('fireflyconfig')->get('last_update_check');
$singleUser = app('fireflyconfig')->get('single_user_mode');
return [
'is_demo_site' => $isDemoSite?->data,
'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data,
'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data,
'single_user_mode' => $singleUser?->data,
];
}
private function getStaticConfiguration(): array
{
$list = EitherConfigKey::$static;
$return = [];
foreach ($list as $key) {
$return[$key] = config($key);
}
return $return;
}
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/configuration/getSingleConfiguration
@@ -145,33 +174,4 @@ class ConfigurationController extends Controller
return response()->json(['data' => $data])->header('Content-Type', self::CONTENT_TYPE);
}
/**
* Get all config values.
*/
private function getDynamicConfiguration(): array
{
$isDemoSite = app('fireflyconfig')->get('is_demo_site');
$updateCheck = app('fireflyconfig')->get('permission_update_check');
$lastCheck = app('fireflyconfig')->get('last_update_check');
$singleUser = app('fireflyconfig')->get('single_user_mode');
return [
'is_demo_site' => $isDemoSite?->data,
'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data,
'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data,
'single_user_mode' => $singleUser?->data,
];
}
private function getStaticConfiguration(): array
{
$list = EitherConfigKey::$static;
$return = [];
foreach ($list as $key) {
$return[$key] = config($key);
}
return $return;
}
}

View File

@@ -83,12 +83,12 @@ class MoveTransactionsRequest extends FormRequest
$data = $validator->getData();
$repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
$original = $repository->find((int) $data['original_account']);
$destination = $repository->find((int) $data['destination_account']);
$original = $repository->find((int)$data['original_account']);
$destination = $repository->find((int)$data['destination_account']);
// not the same type:
if ($original->accountType->type !== $destination->accountType->type) {
$validator->errors()->add('title', (string) trans('validation.same_account_type'));
$validator->errors()->add('title', (string)trans('validation.same_account_type'));
return;
}
@@ -98,7 +98,7 @@ class MoveTransactionsRequest extends FormRequest
// check different scenario's.
if (null === $originalCurrency xor null === $destinationCurrency) {
$validator->errors()->add('title', (string) trans('validation.same_account_currency'));
$validator->errors()->add('title', (string)trans('validation.same_account_currency'));
return;
}
@@ -107,7 +107,7 @@ class MoveTransactionsRequest extends FormRequest
return;
}
if ($originalCurrency->code !== $destinationCurrency->code) {
$validator->errors()->add('title', (string) trans('validation.same_account_currency'));
$validator->errors()->add('title', (string)trans('validation.same_account_currency'));
}
}
}

View File

@@ -78,6 +78,25 @@ class GenericRequest extends FormRequest
return $return;
}
private function parseAccounts(): void
{
if (0 !== $this->accounts->count()) {
return;
}
$repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
$array = $this->get('accounts');
if (is_array($array)) {
foreach ($array as $accountId) {
$accountId = (int)$accountId;
$account = $repository->find($accountId);
if (null !== $account) {
$this->accounts->push($account);
}
}
}
}
public function getBills(): Collection
{
$this->parseBills();
@@ -85,6 +104,25 @@ class GenericRequest extends FormRequest
return $this->bills;
}
private function parseBills(): void
{
if (0 !== $this->bills->count()) {
return;
}
$repository = app(BillRepositoryInterface::class);
$repository->setUser(auth()->user());
$array = $this->get('bills');
if (is_array($array)) {
foreach ($array as $billId) {
$billId = (int)$billId;
$bill = $repository->find($billId);
if (null !== $bill) {
$this->bills->push($bill);
}
}
}
}
public function getBudgets(): Collection
{
$this->parseBudgets();
@@ -92,6 +130,25 @@ class GenericRequest extends FormRequest
return $this->budgets;
}
private function parseBudgets(): void
{
if (0 !== $this->budgets->count()) {
return;
}
$repository = app(BudgetRepositoryInterface::class);
$repository->setUser(auth()->user());
$array = $this->get('budgets');
if (is_array($array)) {
foreach ($array as $budgetId) {
$budgetId = (int)$budgetId;
$budget = $repository->find($budgetId);
if (null !== $budget) {
$this->budgets->push($budget);
}
}
}
}
public function getCategories(): Collection
{
$this->parseCategories();
@@ -99,6 +156,25 @@ class GenericRequest extends FormRequest
return $this->categories;
}
private function parseCategories(): void
{
if (0 !== $this->categories->count()) {
return;
}
$repository = app(CategoryRepositoryInterface::class);
$repository->setUser(auth()->user());
$array = $this->get('categories');
if (is_array($array)) {
foreach ($array as $categoryId) {
$categoryId = (int)$categoryId;
$category = $repository->find($categoryId);
if (null !== $category) {
$this->categories->push($category);
}
}
}
}
public function getEnd(): Carbon
{
$date = $this->getCarbonDate('end');
@@ -154,100 +230,6 @@ class GenericRequest extends FormRequest
return $this->tags;
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
// this is cheating, but it works to initialize the collections.
$this->accounts = new Collection();
$this->budgets = new Collection();
$this->categories = new Collection();
$this->bills = new Collection();
$this->tags = new Collection();
return [
'start' => 'required|date',
'end' => 'required|date|after_or_equal:start',
];
}
private function parseAccounts(): void
{
if (0 !== $this->accounts->count()) {
return;
}
$repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
$array = $this->get('accounts');
if (is_array($array)) {
foreach ($array as $accountId) {
$accountId = (int)$accountId;
$account = $repository->find($accountId);
if (null !== $account) {
$this->accounts->push($account);
}
}
}
}
private function parseBills(): void
{
if (0 !== $this->bills->count()) {
return;
}
$repository = app(BillRepositoryInterface::class);
$repository->setUser(auth()->user());
$array = $this->get('bills');
if (is_array($array)) {
foreach ($array as $billId) {
$billId = (int)$billId;
$bill = $repository->find($billId);
if (null !== $bill) {
$this->bills->push($bill);
}
}
}
}
private function parseBudgets(): void
{
if (0 !== $this->budgets->count()) {
return;
}
$repository = app(BudgetRepositoryInterface::class);
$repository->setUser(auth()->user());
$array = $this->get('budgets');
if (is_array($array)) {
foreach ($array as $budgetId) {
$budgetId = (int)$budgetId;
$budget = $repository->find($budgetId);
if (null !== $budget) {
$this->budgets->push($budget);
}
}
}
}
private function parseCategories(): void
{
if (0 !== $this->categories->count()) {
return;
}
$repository = app(CategoryRepositoryInterface::class);
$repository->setUser(auth()->user());
$array = $this->get('categories');
if (is_array($array)) {
foreach ($array as $categoryId) {
$categoryId = (int)$categoryId;
$category = $repository->find($categoryId);
if (null !== $category) {
$this->categories->push($category);
}
}
}
}
private function parseTags(): void
{
if (0 !== $this->tags->count()) {
@@ -266,4 +248,22 @@ class GenericRequest extends FormRequest
}
}
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
// this is cheating, but it works to initialize the collections.
$this->accounts = new Collection();
$this->budgets = new Collection();
$this->categories = new Collection();
$this->bills = new Collection();
$this->tags = new Collection();
return [
'start' => 'required|date',
'end' => 'required|date|after_or_equal:start',
];
}
}

View File

@@ -83,7 +83,7 @@ class UpdateRequest extends FormRequest
$start = new Carbon($data['start']);
$end = new Carbon($data['end']);
if ($end->isBefore($start)) {
$validator->errors()->add('end', (string) trans('validation.date_after'));
$validator->errors()->add('end', (string)trans('validation.date_after'));
}
}
}

View File

@@ -73,6 +73,65 @@ class StoreRequest extends FormRequest
];
}
/**
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
*/
private function getTransactionData(): array
{
$return = [];
// transaction data:
/** @var null|array $transactions */
$transactions = $this->get('transactions');
if (null === $transactions) {
return [];
}
/** @var array $transaction */
foreach ($transactions as $transaction) {
$return[] = $this->getSingleTransactionData($transaction);
}
return $return;
}
/**
* Returns the repetition data as it is found in the submitted data.
*/
private function getRepetitionData(): array
{
$return = [];
// repetition data:
/** @var null|array $repetitions */
$repetitions = $this->get('repetitions');
if (null === $repetitions) {
return [];
}
/** @var array $repetition */
foreach ($repetitions as $repetition) {
$current = [];
if (array_key_exists('type', $repetition)) {
$current['type'] = $repetition['type'];
}
if (array_key_exists('moment', $repetition)) {
$current['moment'] = $repetition['moment'];
}
if (array_key_exists('skip', $repetition)) {
$current['skip'] = (int)$repetition['skip'];
}
if (array_key_exists('weekend', $repetition)) {
$current['weekend'] = (int)$repetition['weekend'];
}
$return[] = $current;
}
return $return;
}
/**
* The rules that the incoming request must be matched against.
*/
@@ -136,63 +195,4 @@ class StoreRequest extends FormRequest
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
*/
private function getTransactionData(): array
{
$return = [];
// transaction data:
/** @var null|array $transactions */
$transactions = $this->get('transactions');
if (null === $transactions) {
return [];
}
/** @var array $transaction */
foreach ($transactions as $transaction) {
$return[] = $this->getSingleTransactionData($transaction);
}
return $return;
}
/**
* Returns the repetition data as it is found in the submitted data.
*/
private function getRepetitionData(): array
{
$return = [];
// repetition data:
/** @var null|array $repetitions */
$repetitions = $this->get('repetitions');
if (null === $repetitions) {
return [];
}
/** @var array $repetition */
foreach ($repetitions as $repetition) {
$current = [];
if (array_key_exists('type', $repetition)) {
$current['type'] = $repetition['type'];
}
if (array_key_exists('moment', $repetition)) {
$current['moment'] = $repetition['moment'];
}
if (array_key_exists('skip', $repetition)) {
$current['skip'] = (int)$repetition['skip'];
}
if (array_key_exists('weekend', $repetition)) {
$current['weekend'] = (int)$repetition['weekend'];
}
$return[] = $current;
}
return $return;
}
}

View File

@@ -78,6 +78,70 @@ class UpdateRequest extends FormRequest
return $return;
}
/**
* Returns the repetition data as it is found in the submitted data.
*/
private function getRepetitionData(): ?array
{
$return = [];
// repetition data:
/** @var null|array $repetitions */
$repetitions = $this->get('repetitions');
if (null === $repetitions) {
return null;
}
/** @var array $repetition */
foreach ($repetitions as $repetition) {
$current = [];
if (array_key_exists('type', $repetition)) {
$current['type'] = $repetition['type'];
}
if (array_key_exists('moment', $repetition)) {
$current['moment'] = (string)$repetition['moment'];
}
if (array_key_exists('skip', $repetition)) {
$current['skip'] = (int)$repetition['skip'];
}
if (array_key_exists('weekend', $repetition)) {
$current['weekend'] = (int)$repetition['weekend'];
}
$return[] = $current;
}
if (0 === count($return)) {
return null;
}
return $return;
}
/**
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
*/
private function getTransactionData(): array
{
$return = [];
// transaction data:
/** @var null|array $transactions */
$transactions = $this->get('transactions');
if (null === $transactions) {
return [];
}
/** @var array $transaction */
foreach ($transactions as $transaction) {
$return[] = $this->getSingleTransactionData($transaction);
}
return $return;
}
/**
* The rules that the incoming request must be matched against.
*/
@@ -146,68 +210,4 @@ class UpdateRequest extends FormRequest
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**
* Returns the repetition data as it is found in the submitted data.
*/
private function getRepetitionData(): ?array
{
$return = [];
// repetition data:
/** @var null|array $repetitions */
$repetitions = $this->get('repetitions');
if (null === $repetitions) {
return null;
}
/** @var array $repetition */
foreach ($repetitions as $repetition) {
$current = [];
if (array_key_exists('type', $repetition)) {
$current['type'] = $repetition['type'];
}
if (array_key_exists('moment', $repetition)) {
$current['moment'] = (string) $repetition['moment'];
}
if (array_key_exists('skip', $repetition)) {
$current['skip'] = (int) $repetition['skip'];
}
if (array_key_exists('weekend', $repetition)) {
$current['weekend'] = (int) $repetition['weekend'];
}
$return[] = $current;
}
if (0 === count($return)) {
return null;
}
return $return;
}
/**
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
*/
private function getTransactionData(): array
{
$return = [];
// transaction data:
/** @var null|array $transactions */
$transactions = $this->get('transactions');
if (null === $transactions) {
return [];
}
/** @var array $transaction */
foreach ($transactions as $transaction) {
$return[] = $this->getSingleTransactionData($transaction);
}
return $return;
}
}

View File

@@ -64,6 +64,42 @@ class StoreRequest extends FormRequest
return $data;
}
private function getRuleTriggers(): array
{
$triggers = $this->get('triggers');
$return = [];
if (is_array($triggers)) {
foreach ($triggers as $trigger) {
$return[] = [
'type' => $trigger['type'],
'value' => $trigger['value'],
'active' => $this->convertBoolean((string)($trigger['active'] ?? 'true')),
'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')),
];
}
}
return $return;
}
private function getRuleActions(): array
{
$actions = $this->get('actions');
$return = [];
if (is_array($actions)) {
foreach ($actions as $action) {
$return[] = [
'type' => $action['type'],
'value' => $action['value'],
'active' => $this->convertBoolean((string)($action['active'] ?? 'true')),
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
];
}
}
return $return;
}
/**
* The rules that the incoming request must be matched against.
*/
@@ -197,40 +233,4 @@ class StoreRequest extends FormRequest
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action'));
}
}
private function getRuleTriggers(): array
{
$triggers = $this->get('triggers');
$return = [];
if (is_array($triggers)) {
foreach ($triggers as $trigger) {
$return[] = [
'type' => $trigger['type'],
'value' => $trigger['value'],
'active' => $this->convertBoolean((string)($trigger['active'] ?? 'true')),
'stop_processing' => $this->convertBoolean((string)($trigger['stop_processing'] ?? 'false')),
];
}
}
return $return;
}
private function getRuleActions(): array
{
$actions = $this->get('actions');
$return = [];
if (is_array($actions)) {
foreach ($actions as $action) {
$return[] = [
'type' => $action['type'],
'value' => $action['value'],
'active' => $this->convertBoolean((string)($action['active'] ?? 'true')),
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
];
}
}
return $return;
}
}

View File

@@ -47,16 +47,6 @@ class TestRequest extends FormRequest
];
}
public function rules(): array
{
return [
'start' => 'date',
'end' => 'date|after_or_equal:start',
'accounts' => '',
'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts',
];
}
private function getPage(): int
{
return 0 === (int)$this->query('page') ? 1 : (int)$this->query('page');
@@ -81,4 +71,14 @@ class TestRequest extends FormRequest
{
return $this->get('accounts');
}
public function rules(): array
{
return [
'start' => 'date',
'end' => 'date|after_or_equal:start',
'accounts' => '',
'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts',
];
}
}

View File

@@ -46,16 +46,6 @@ class TriggerRequest extends FormRequest
];
}
public function rules(): array
{
return [
'start' => 'date',
'end' => 'date|after_or_equal:start',
'accounts' => '',
'accounts.*' => 'exists:accounts,id|belongsToUser:accounts',
];
}
private function getDate(string $field): ?Carbon
{
$value = $this->query($field);
@@ -75,4 +65,14 @@ class TriggerRequest extends FormRequest
{
return $this->get('accounts') ?? [];
}
public function rules(): array
{
return [
'start' => 'date',
'end' => 'date|after_or_equal:start',
'accounts' => '',
'accounts.*' => 'exists:accounts,id|belongsToUser:accounts',
];
}
}

View File

@@ -70,6 +70,50 @@ class UpdateRequest extends FormRequest
return $return;
}
private function getRuleTriggers(): ?array
{
if (!$this->has('triggers')) {
return null;
}
$triggers = $this->get('triggers');
$return = [];
if (is_array($triggers)) {
foreach ($triggers as $trigger) {
$active = array_key_exists('active', $trigger) ? $trigger['active'] : true;
$stopProcessing = array_key_exists('stop_processing', $trigger) ? $trigger['stop_processing'] : false;
$return[] = [
'type' => $trigger['type'],
'value' => $trigger['value'],
'active' => $active,
'stop_processing' => $stopProcessing,
];
}
}
return $return;
}
private function getRuleActions(): ?array
{
if (!$this->has('actions')) {
return null;
}
$actions = $this->get('actions');
$return = [];
if (is_array($actions)) {
foreach ($actions as $action) {
$return[] = [
'type' => $action['type'],
'value' => $action['value'],
'active' => $this->convertBoolean((string)($action['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
];
}
}
return $return;
}
/**
* The rules that the incoming request must be matched against.
*/
@@ -204,48 +248,4 @@ class UpdateRequest extends FormRequest
$validator->errors()->add(sprintf('actions.%d.active', $inactiveIndex), (string)trans('validation.at_least_one_active_action'));
}
}
private function getRuleTriggers(): ?array
{
if (!$this->has('triggers')) {
return null;
}
$triggers = $this->get('triggers');
$return = [];
if (is_array($triggers)) {
foreach ($triggers as $trigger) {
$active = array_key_exists('active', $trigger) ? $trigger['active'] : true;
$stopProcessing = array_key_exists('stop_processing', $trigger) ? $trigger['stop_processing'] : false;
$return[] = [
'type' => $trigger['type'],
'value' => $trigger['value'],
'active' => $active,
'stop_processing' => $stopProcessing,
];
}
}
return $return;
}
private function getRuleActions(): ?array
{
if (!$this->has('actions')) {
return null;
}
$actions = $this->get('actions');
$return = [];
if (is_array($actions)) {
foreach ($actions as $action) {
$return[] = [
'type' => $action['type'],
'value' => $action['value'],
'active' => $this->convertBoolean((string)($action['active'] ?? 'false')),
'stop_processing' => $this->convertBoolean((string)($action['stop_processing'] ?? 'false')),
];
}
}
return $return;
}
}

View File

@@ -46,16 +46,6 @@ class TestRequest extends FormRequest
];
}
public function rules(): array
{
return [
'start' => 'date',
'end' => 'date|after_or_equal:start',
'accounts' => '',
'accounts.*' => 'exists:accounts,id|belongsToUser:accounts',
];
}
private function getDate(string $field): ?Carbon
{
$value = $this->query($field);
@@ -75,4 +65,14 @@ class TestRequest extends FormRequest
{
return $this->get('accounts');
}
public function rules(): array
{
return [
'start' => 'date',
'end' => 'date|after_or_equal:start',
'accounts' => '',
'accounts.*' => 'exists:accounts,id|belongsToUser:accounts',
];
}
}

View File

@@ -46,14 +46,6 @@ class TriggerRequest extends FormRequest
];
}
public function rules(): array
{
return [
'start' => 'date',
'end' => 'date|after_or_equal:start',
];
}
private function getDate(string $field): ?Carbon
{
$value = $this->query($field);
@@ -77,4 +69,12 @@ class TriggerRequest extends FormRequest
return $this->get('accounts');
}
public function rules(): array
{
return [
'start' => 'date',
'end' => 'date|after_or_equal:start',
];
}
}

View File

@@ -69,134 +69,6 @@ class StoreRequest extends FormRequest
// TODO include location and ability to process it.
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
app('log')->debug('Collect rules of TransactionStoreRequest');
$validProtocols = config('firefly.valid_url_protocols');
return [
// basic fields for group:
'group_title' => 'min:1|max:1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean()],
'apply_rules' => [new IsBoolean()],
// transaction rules (in array for splits):
'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation',
'transactions.*.date' => ['required', new IsDateOrTime()],
'transactions.*.order' => 'numeric|min:0',
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
// amount
'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.source_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.source_number' => 'min:1|max:255|nullable',
'transactions.*.source_bic' => 'min:1|max:255|nullable|bic',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'min:1|max:255|nullable',
'transactions.*.destination_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.destination_number' => 'min:1|max:255|nullable',
'transactions.*.destination_bic' => 'min:1|max:255|nullable|bic',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser()],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUser()],
'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
'transactions.*.external_url' => sprintf('min:1|max:255|nullable|url:%s', $validProtocols),
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_db' => 'min:1|max:255|nullable',
'transactions.*.sepa_country' => 'min:1|max:255|nullable',
'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
// dates
'transactions.*.interest_date' => 'date|nullable',
'transactions.*.book_date' => 'date|nullable',
'transactions.*.process_date' => 'date|nullable',
'transactions.*.due_date' => 'date|nullable',
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
];
}
/**
* Configure the validator instance.
*/
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator): void {
// must be valid array.
$this->validateTransactionArray($validator);
// must submit at least one transaction.
app('log')->debug('Now going to validateOneTransaction');
$this->validateOneTransaction($validator);
app('log')->debug('Now done with validateOneTransaction');
// all journals must have a description
$this->validateDescriptions($validator);
// all transaction types must be equal:
$this->validateTransactionTypes($validator);
// validate foreign currency info
$this->validateForeignCurrencyInformation($validator);
// validate all account info
$this->validateAccountInformation($validator);
// validate source/destination is equal, depending on the transaction journal type.
$this->validateEqualAccounts($validator);
// the group must have a description if > 1 journal.
$this->validateGroupDescription($validator);
}
);
if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**
* Get transaction data.
*/
@@ -291,4 +163,132 @@ class StoreRequest extends FormRequest
return $return;
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
app('log')->debug('Collect rules of TransactionStoreRequest');
$validProtocols = config('firefly.valid_url_protocols');
return [
// basic fields for group:
'group_title' => 'min:1|max:1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean()],
'apply_rules' => [new IsBoolean()],
// transaction rules (in array for splits):
'transactions.*.type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation',
'transactions.*.date' => ['required', new IsDateOrTime()],
'transactions.*.order' => 'numeric|min:0',
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
// amount
'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.source_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.source_number' => 'min:1|max:255|nullable',
'transactions.*.source_bic' => 'min:1|max:255|nullable|bic',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'min:1|max:255|nullable',
'transactions.*.destination_iban' => 'min:1|max:255|nullable|iban',
'transactions.*.destination_number' => 'min:1|max:255|nullable',
'transactions.*.destination_bic' => 'min:1|max:255|nullable|bic',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser()],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUser()],
'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
'transactions.*.external_url' => sprintf('min:1|max:255|nullable|url:%s', $validProtocols),
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_db' => 'min:1|max:255|nullable',
'transactions.*.sepa_country' => 'min:1|max:255|nullable',
'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
// dates
'transactions.*.interest_date' => 'date|nullable',
'transactions.*.book_date' => 'date|nullable',
'transactions.*.process_date' => 'date|nullable',
'transactions.*.due_date' => 'date|nullable',
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
];
}
/**
* Configure the validator instance.
*/
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator): void {
// must be valid array.
$this->validateTransactionArray($validator);
// must submit at least one transaction.
app('log')->debug('Now going to validateOneTransaction');
$this->validateOneTransaction($validator);
app('log')->debug('Now done with validateOneTransaction');
// all journals must have a description
$this->validateDescriptions($validator);
// all transaction types must be equal:
$this->validateTransactionTypes($validator);
// validate foreign currency info
$this->validateForeignCurrencyInformation($validator);
// validate all account info
$this->validateAccountInformation($validator);
// validate source/destination is equal, depending on the transaction journal type.
$this->validateEqualAccounts($validator);
// the group must have a description if > 1 journal.
$this->validateGroupDescription($validator);
}
);
if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}

View File

@@ -90,127 +90,6 @@ class UpdateRequest extends FormRequest
return $data;
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$validProtocols = config('firefly.valid_url_protocols');
return [
// basic fields for group:
'group_title' => 'min:1|max:1000|nullable',
'apply_rules' => [new IsBoolean()],
// transaction rules (in array for splits):
'transactions.*.type' => 'in:withdrawal,deposit,transfer,opening-balance,reconciliation',
'transactions.*.date' => [new IsDateOrTime()],
'transactions.*.order' => 'numeric|min:0',
// group id:
'transactions.*.transaction_journal_id' => ['nullable', 'numeric', new BelongsUser()],
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
// amount
'transactions.*.amount' => [new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'min:1|max:255|nullable',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'min:1|max:255|nullable',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser(), 'nullable'],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255|nullable',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
'transactions.*.external_url' => sprintf('min:1|max:255|nullable|url:%s', $validProtocols),
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_db' => 'min:1|max:255|nullable',
'transactions.*.sepa_country' => 'min:1|max:255|nullable',
'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
// dates
'transactions.*.interest_date' => 'date|nullable',
'transactions.*.book_date' => 'date|nullable',
'transactions.*.process_date' => 'date|nullable',
'transactions.*.due_date' => 'date|nullable',
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
];
}
/**
* Configure the validator instance.
*/
public function withValidator(Validator $validator): void
{
app('log')->debug('Now in withValidator');
/** @var TransactionGroup $transactionGroup */
$transactionGroup = $this->route()->parameter('transactionGroup');
$validator->after(
function (Validator $validator) use ($transactionGroup): void {
// if more than one, verify that there are journal ID's present.
$this->validateJournalIds($validator, $transactionGroup);
// all transaction types must be equal:
$this->validateTransactionTypesForUpdate($validator);
// user wants to update a reconciled transaction.
// source, destination, amount + foreign_amount cannot be changed
// and must be omitted from the request.
$this->preventUpdateReconciled($validator, $transactionGroup);
// validate source/destination is equal, depending on the transaction journal type.
$this->validateEqualAccountsForUpdate($validator, $transactionGroup);
// see method:
// $this->preventNoAccountInfo($validator, );
// validate that the currency fits the source and/or destination account.
// validate all account info
$this->validateAccountInformationUpdate($validator, $transactionGroup);
}
);
if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
/**
* Get transaction data.
*
@@ -258,7 +137,7 @@ class UpdateRequest extends FormRequest
{
foreach ($this->integerFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->integerFromValue((string) $transaction[$fieldName]);
$current[$fieldName] = $this->integerFromValue((string)$transaction[$fieldName]);
}
}
@@ -273,7 +152,7 @@ class UpdateRequest extends FormRequest
{
foreach ($this->stringFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearString((string) $transaction[$fieldName]);
$current[$fieldName] = $this->clearString((string)$transaction[$fieldName]);
}
}
@@ -288,7 +167,7 @@ class UpdateRequest extends FormRequest
{
foreach ($this->textareaFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearStringKeepNewlines((string) $transaction[$fieldName]); // keep newlines
$current[$fieldName] = $this->clearStringKeepNewlines((string)$transaction[$fieldName]); // keep newlines
}
}
@@ -304,8 +183,8 @@ class UpdateRequest extends FormRequest
foreach ($this->dateFields as $fieldName) {
app('log')->debug(sprintf('Now at date field %s', $fieldName));
if (array_key_exists($fieldName, $transaction)) {
app('log')->debug(sprintf('New value: "%s"', (string) $transaction[$fieldName]));
$current[$fieldName] = $this->dateFromValue((string) $transaction[$fieldName]);
app('log')->debug(sprintf('New value: "%s"', (string)$transaction[$fieldName]));
$current[$fieldName] = $this->dateFromValue((string)$transaction[$fieldName]);
}
}
@@ -320,7 +199,7 @@ class UpdateRequest extends FormRequest
{
foreach ($this->booleanFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->convertBoolean((string) $transaction[$fieldName]);
$current[$fieldName] = $this->convertBoolean((string)$transaction[$fieldName]);
}
}
@@ -355,11 +234,132 @@ class UpdateRequest extends FormRequest
$current[$fieldName] = sprintf('%.12f', $value);
}
if (!is_float($value)) {
$current[$fieldName] = (string) $value;
$current[$fieldName] = (string)$value;
}
}
}
return $current;
}
/**
* The rules that the incoming request must be matched against.
*/
public function rules(): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$validProtocols = config('firefly.valid_url_protocols');
return [
// basic fields for group:
'group_title' => 'min:1|max:1000|nullable',
'apply_rules' => [new IsBoolean()],
// transaction rules (in array for splits):
'transactions.*.type' => 'in:withdrawal,deposit,transfer,opening-balance,reconciliation',
'transactions.*.date' => [new IsDateOrTime()],
'transactions.*.order' => 'numeric|min:0',
// group id:
'transactions.*.transaction_journal_id' => ['nullable', 'numeric', new BelongsUser()],
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
// amount
'transactions.*.amount' => [new IsValidPositiveAmount()],
'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.source_name' => 'min:1|max:255|nullable',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
'transactions.*.destination_name' => 'min:1|max:255|nullable',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser(), 'nullable'],
'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
'transactions.*.notes' => 'min:1|max:32768|nullable',
'transactions.*.tags' => 'min:0|max:255|nullable',
'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
'transactions.*.external_url' => sprintf('min:1|max:255|nullable|url:%s', $validProtocols),
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
'transactions.*.sepa_db' => 'min:1|max:255|nullable',
'transactions.*.sepa_country' => 'min:1|max:255|nullable',
'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
// dates
'transactions.*.interest_date' => 'date|nullable',
'transactions.*.book_date' => 'date|nullable',
'transactions.*.process_date' => 'date|nullable',
'transactions.*.due_date' => 'date|nullable',
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
];
}
/**
* Configure the validator instance.
*/
public function withValidator(Validator $validator): void
{
app('log')->debug('Now in withValidator');
/** @var TransactionGroup $transactionGroup */
$transactionGroup = $this->route()->parameter('transactionGroup');
$validator->after(
function (Validator $validator) use ($transactionGroup): void {
// if more than one, verify that there are journal ID's present.
$this->validateJournalIds($validator, $transactionGroup);
// all transaction types must be equal:
$this->validateTransactionTypesForUpdate($validator);
// user wants to update a reconciled transaction.
// source, destination, amount + foreign_amount cannot be changed
// and must be omitted from the request.
$this->preventUpdateReconciled($validator, $transactionGroup);
// validate source/destination is equal, depending on the transaction journal type.
$this->validateEqualAccountsForUpdate($validator, $transactionGroup);
// see method:
// $this->preventNoAccountInfo($validator, );
// validate that the currency fits the source and/or destination account.
// validate all account info
$this->validateAccountInformationUpdate($validator, $transactionGroup);
}
);
if ($validator->fails()) {
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
}
}
}