Clean up some classes, extend API validation.

This commit is contained in:
James Cole
2025-11-02 14:00:55 +01:00
parent d5e431c3a1
commit a57cf4e9be
28 changed files with 324 additions and 109 deletions

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers\Autocomplete;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteApiRequest;
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteTransactionApiRequest;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
@@ -64,7 +65,7 @@ class TransactionController extends Controller
);
}
public function transactions(AutocompleteApiRequest $request): JsonResponse
public function transactions(AutocompleteTransactionApiRequest $request): JsonResponse
{
$result = $this->repository->searchJournalDescriptions($request->attributes->get('query'), $request->attributes->get('limit'));

View File

@@ -136,12 +136,16 @@ class ListController extends Controller
/**
* Show all transaction groups related to the account.
*/
public function transactions(Request $request, Account $account): JsonResponse
public function transactions(PaginationRequest $request, Account $account): JsonResponse
{
$pageSize = $this->parameters->get('limit');
[
'limit' => $limit,
'offset' => $offset,
'page' => $page,
] = $request->attributes->all();
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
$types = $this->mapTransactionTypes($this->parameters->get('type'));
$types = $this->mapTransactionTypes($type);
$manager = $this->getManager();
/** @var User $admin */
@@ -151,7 +155,7 @@ class ListController extends Controller
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($admin)->setAccounts(new Collection()->push($account))
->withAPIInformation()->setLimit($pageSize)->setPage($this->parameters->get('page'))->setTypes($types)
->withAPIInformation()->setLimit($limit)->setPage($page)->setTypes($types)
;
if (null !== $this->parameters->get('start')) {

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
@@ -45,6 +46,7 @@ abstract class AggregateFormRequest extends ApiRequest
// instantiate all subrequests and share current requests' bags with them
Log::debug('Initializing AggregateFormRequest.');
foreach ($this->getRequests() as $config) {
$requestClass = is_array($config) ? array_shift($config) : $config;

View File

@@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Autocomplete;
use FireflyIII\Api\V1\Requests\AggregateFormRequest;
use FireflyIII\Api\V1\Requests\DateRequest;
use FireflyIII\Api\V1\Requests\Generic\ObjectTypeApiRequest;
use FireflyIII\Api\V1\Requests\Generic\QueryRequest;
use FireflyIII\Api\V1\Requests\Models\Account\AccountTypesApiRequest;
use FireflyIII\Api\V1\Requests\PaginationRequest;
@@ -39,7 +40,7 @@ class AutocompleteApiRequest extends AggregateFormRequest
return [
DateRequest::class,
[PaginationRequest::class, 'sort_class' => Account::class],
AccountTypesApiRequest::class,
[ObjectTypeApiRequest::class, 'object_type' => Account::class],
QueryRequest::class,
];
}

View File

@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/*
* AutocompleteApiRequest.php
* Copyright (c) 2025 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Requests\Autocomplete;
use FireflyIII\Api\V1\Requests\AggregateFormRequest;
use FireflyIII\Api\V1\Requests\DateRequest;
use FireflyIII\Api\V1\Requests\Generic\ObjectTypeApiRequest;
use FireflyIII\Api\V1\Requests\Generic\QueryRequest;
use FireflyIII\Api\V1\Requests\PaginationRequest;
use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction;
use Override;
class AutocompleteTransactionApiRequest extends AggregateFormRequest
{
#[Override]
protected function getRequests(): array
{
return [
DateRequest::class,
[PaginationRequest::class, 'sort_class' => Account::class],
[ObjectTypeApiRequest::class, 'object_type' => Transaction::class],
QueryRequest::class,
];
}
}

View File

@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
/*
* AccountTypeApiRequest.php
* Copyright (c) 2025 https://github.com/ctrl-f5
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Api\V1\Requests\Generic;
use FireflyIII\Api\V1\Requests\ApiRequest;
use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction;
use FireflyIII\Rules\Account\IsValidAccountTypeList;
use FireflyIII\Rules\TransactionType\IsValidTransactionTypeList;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\TransactionFilter;
use Illuminate\Validation\Validator;
use RuntimeException;
class ObjectTypeApiRequest extends ApiRequest
{
use AccountFilter;
use TransactionFilter;
private ?string $objectType = null;
public function handleConfig(array $config): void
{
parent::handleConfig($config);
$this->objectType = $config['object_type'] ?? null;
if (!$this->objectType) {
throw new RuntimeException('ObjectTypeApiRequest requires a object_type config');
}
}
public function rules(): array
{
$rule = null;
if (Account::class === $this->objectType) {
$rule = new IsValidAccountTypeList();
}
if (Transaction::class === $this->objectType) {
$rule = new IsValidTransactionTypeList();
}
return [
'types' => $rule,
];
}
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator): void {
if ($validator->failed()) {
return;
}
$type = $this->convertString('types', 'all');
$this->attributes->set('type', $type);
switch ($this->objectType) {
default:
$this->attributes->set('types', []);
case Account::class:
$this->attributes->set('types', $this->mapAccountTypes($type));
break;
case Transaction::class:
$this->attributes->set('types', $this->mapTransactionTypes($type));
break;
}
}
);
}
}

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Account;
use FireflyIII\Api\V1\Requests\AggregateFormRequest;
use FireflyIII\Api\V1\Requests\DateRangeRequest;
use FireflyIII\Api\V1\Requests\DateRequest;
use FireflyIII\Api\V1\Requests\Generic\ObjectTypeApiRequest;
use FireflyIII\Api\V1\Requests\PaginationRequest;
use FireflyIII\Models\Account;
@@ -38,6 +39,7 @@ class ShowRequest extends AggregateFormRequest
DateRangeRequest::class,
DateRequest::class,
AccountTypeApiRequest::class,
[ObjectTypeApiRequest::class, 'object_type' => Account::class],
];
}
}

View File

@@ -31,6 +31,7 @@ use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
use FireflyIII\Services\Internal\Support\BillServiceTrait;
use FireflyIII\User;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
/**
* Class BillFactory
@@ -47,7 +48,7 @@ class BillFactory
*/
public function create(array $data): ?Bill
{
app('log')->debug(sprintf('Now in %s', __METHOD__), $data);
Log::debug(sprintf('Now in %s', __METHOD__), $data);
$factory = app(TransactionCurrencyFactory::class);
$currency = $factory->find((int) ($data['currency_id'] ?? null), (string) ($data['currency_code'] ?? null))
?? app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
@@ -82,8 +83,8 @@ class BillFactory
]
);
} catch (QueryException $e) {
app('log')->error($e->getMessage());
app('log')->error($e->getTraceAsString());
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
throw new FireflyException('400000: Could not store bill.', 0, $e);
}

View File

@@ -27,7 +27,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Category;
use FireflyIII\User;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
/**
* Class CategoryFactory
*/
@@ -43,7 +43,7 @@ class CategoryFactory
$categoryId = (int) $categoryId;
$categoryName = (string) $categoryName;
app('log')->debug(sprintf('Going to find category with ID %d and name "%s"', $categoryId, $categoryName));
Log::debug(sprintf('Going to find category with ID %d and name "%s"', $categoryId, $categoryName));
if ('' === $categoryName && 0 === $categoryId) {
return null;
@@ -72,8 +72,8 @@ class CategoryFactory
]
);
} catch (QueryException $e) {
app('log')->error($e->getMessage());
app('log')->error($e->getTraceAsString());
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
throw new FireflyException('400003: Could not store new category.', 0, $e);
}

View File

@@ -38,7 +38,6 @@ use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
use function Safe\json_encode;
/**
* Class PiggyBankFactory
*/
@@ -92,7 +91,7 @@ class PiggyBankFactory
/** @var PiggyBank $piggyBank */
$piggyBank = PiggyBank::createQuietly($piggyBankData);
} catch (QueryException $e) {
app('log')->error(sprintf('Could not store piggy bank: %s', $e->getMessage()), $piggyBankData);
Log::error(sprintf('Could not store piggy bank: %s', $e->getMessage()), $piggyBankData);
throw new FireflyException('400005: Could not store new piggy bank.', 0, $e);
}
@@ -211,7 +210,7 @@ class PiggyBankFactory
$current = 1;
foreach ($set as $piggyBank) {
if ($piggyBank->order !== $current) {
app('log')->debug(sprintf('Piggy bank #%d ("%s") was at place %d but should be on %d', $piggyBank->id, $piggyBank->name, $piggyBank->order, $current));
Log::debug(sprintf('Piggy bank #%d ("%s") was at place %d but should be on %d', $piggyBank->id, $piggyBank->name, $piggyBank->order, $current));
$piggyBank->order = $current;
$piggyBank->save();
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Models\Location;
use FireflyIII\Models\Tag;
use FireflyIII\Models\UserGroup;
use FireflyIII\User;
use Illuminate\Support\Facades\Log;
/**
* Class TagFactory
@@ -40,12 +41,12 @@ class TagFactory
public function findOrCreate(string $tag): ?Tag
{
$tag = trim($tag);
app('log')->debug(sprintf('Now in TagFactory::findOrCreate("%s")', $tag));
Log::debug(sprintf('Now in TagFactory::findOrCreate("%s")', $tag));
/** @var null|Tag $dbTag */
$dbTag = $this->user->tags()->where('tag', $tag)->first();
if (null !== $dbTag) {
app('log')->debug(sprintf('Tag exists (#%d), return it.', $dbTag->id));
Log::debug(sprintf('Tag exists (#%d), return it.', $dbTag->id));
return $dbTag;
}
@@ -60,11 +61,11 @@ class TagFactory
]
);
if (!$newTag instanceof Tag) {
app('log')->error(sprintf('TagFactory::findOrCreate("%s") but tag is unexpectedly NULL!', $tag));
Log::error(sprintf('TagFactory::findOrCreate("%s") but tag is unexpectedly NULL!', $tag));
return null;
}
app('log')->debug(sprintf('Created new tag #%d ("%s")', $newTag->id, $newTag->tag));
Log::debug(sprintf('Created new tag #%d ("%s")', $newTag->id, $newTag->tag));
return $newTag;
}

View File

@@ -33,6 +33,7 @@ use FireflyIII\Rules\UniqueIban;
use FireflyIII\Services\Internal\Update\AccountUpdateService;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Log;
/**
* Class TransactionFactory
@@ -96,9 +97,9 @@ class TransactionFactory
/** @var null|Transaction $result */
$result = Transaction::create($data);
} catch (QueryException $e) {
app('log')->error(sprintf('Could not create transaction: %s', $e->getMessage()), $data);
app('log')->error($e->getMessage());
app('log')->error($e->getTraceAsString());
Log::error(sprintf('Could not create transaction: %s', $e->getMessage()), $data);
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
throw new FireflyException(sprintf('Query exception when creating transaction: %s', $e->getMessage()), 0, $e);
}
@@ -106,7 +107,7 @@ class TransactionFactory
throw new FireflyException('Transaction is NULL.');
}
app('log')->debug(
Log::debug(
sprintf(
'Created transaction #%d (%s %s, account %s), part of journal #%d',
$result->id,
@@ -138,17 +139,17 @@ class TransactionFactory
private function updateAccountInformation(): void
{
if (!array_key_exists('iban', $this->accountInformation)) {
app('log')->debug('No IBAN information in array, will not update.');
Log::debug('No IBAN information in array, will not update.');
return;
}
if ('' !== (string) $this->account->iban) {
app('log')->debug('Account already has IBAN information, will not update.');
Log::debug('Account already has IBAN information, will not update.');
return;
}
if ($this->account->iban === $this->accountInformation['iban']) {
app('log')->debug('Account already has this IBAN, will not update.');
Log::debug('Account already has this IBAN, will not update.');
return;
}
@@ -157,12 +158,12 @@ class TransactionFactory
'iban' => ['required', new UniqueIban($this->account, $this->account->accountType->type)],
]);
if ($validator->fails()) {
app('log')->debug('Invalid or non-unique IBAN, will not update.');
Log::debug('Invalid or non-unique IBAN, will not update.');
return;
}
app('log')->debug('Will update account with IBAN information.');
Log::debug('Will update account with IBAN information.');
$service = app(AccountUpdateService::class);
$service->update($this->account, ['iban' => $this->accountInformation['iban']]);
}

View File

@@ -29,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\UserGroup;
use FireflyIII\User;
use Illuminate\Support\Facades\Log;
/**
* Class TransactionGroupFactory
@@ -55,7 +56,7 @@ class TransactionGroupFactory
*/
public function create(array $data): TransactionGroup
{
app('log')->debug('Now in TransactionGroupFactory::create()');
Log::debug('Now in TransactionGroupFactory::create()');
$this->journalFactory->setUser($data['user']);
$this->journalFactory->setUserGroup($data['user_group']);
$this->journalFactory->setErrorOnHash($data['error_if_duplicate_hash'] ?? false);
@@ -63,7 +64,7 @@ class TransactionGroupFactory
try {
$collection = $this->journalFactory->create($data);
} catch (DuplicateTransactionException $e) {
app('log')->warning('GroupFactory::create() caught journalFactory::create() with a duplicate!');
Log::warning('GroupFactory::create() caught journalFactory::create() with a duplicate!');
throw new DuplicateTransactionException($e->getMessage(), 0, $e);
}

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Factory;
use Carbon\Carbon;
use FireflyIII\Models\TransactionJournalMeta;
use Illuminate\Support\Facades\Log;
/**
* Class TransactionJournalMetaFactory
@@ -34,27 +35,27 @@ class TransactionJournalMetaFactory
{
public function updateOrCreate(array $data): ?TransactionJournalMeta
{
// app('log')->debug('In updateOrCreate()');
// Log::debug('In updateOrCreate()');
$value = $data['data'];
/** @var null|TransactionJournalMeta $entry */
$entry = $data['journal']->transactionJournalMeta()->where('name', $data['name'])->first();
if (null === $value && null !== $entry) {
// app('log')->debug('Value is empty, delete meta value.');
// Log::debug('Value is empty, delete meta value.');
$entry->delete();
return null;
}
if ($data['data'] instanceof Carbon) {
app('log')->debug('Is a carbon object.');
Log::debug('Is a carbon object.');
$value = $data['data']->toW3cString();
}
if ('' === (string) $value) {
// app('log')->debug('Is an empty string.');
// Log::debug('Is an empty string.');
// don't store blank strings.
if (null !== $entry) {
app('log')->debug('Will not store empty strings, delete meta value');
Log::debug('Will not store empty strings, delete meta value');
$entry->delete();
}
@@ -62,13 +63,13 @@ class TransactionJournalMetaFactory
}
if (null === $entry) {
// app('log')->debug('Will create new object.');
app('log')->debug(sprintf('Going to create new meta-data entry to store "%s".', $data['name']));
// Log::debug('Will create new object.');
Log::debug(sprintf('Going to create new meta-data entry to store "%s".', $data['name']));
$entry = new TransactionJournalMeta();
$entry->transactionJournal()->associate($data['journal']);
$entry->name = $data['name'];
}
app('log')->debug('Will update value and return.');
Log::debug('Will update value and return.');
$entry->data = $value;
$entry->save();

View File

@@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use Illuminate\Support\Collection;
use Throwable;
use Illuminate\Support\Facades\Log;
/**
* Class MonthReportGenerator.
@@ -58,8 +59,8 @@ class MonthReportGenerator implements ReportGeneratorInterface
->render()
;
} catch (Throwable $e) {
app('log')->error(sprintf('Cannot render reports.double.report: %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
Log::error(sprintf('Cannot render reports.double.report: %s', $e->getMessage()));
Log::error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
throw new FireflyException($result, 0, $e);

View File

@@ -105,8 +105,8 @@ class MonthReportGenerator implements ReportGeneratorInterface
->render()
;
} catch (Throwable $e) {
app('log')->error(sprintf('Cannot render reports.audit.report: %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
Log::error(sprintf('Cannot render reports.audit.report: %s', $e->getMessage()));
Log::error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
throw new FireflyException($result, 0, $e);

View File

@@ -30,6 +30,7 @@ use FireflyIII\Generator\Report\ReportGeneratorInterface;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use Illuminate\Support\Collection;
use Throwable;
use Illuminate\Support\Facades\Log;
/**
* Class MonthReportGenerator.
@@ -72,8 +73,8 @@ class MonthReportGenerator implements ReportGeneratorInterface
->render()
;
} catch (Throwable $e) {
app('log')->error(sprintf('Cannot render reports.account.report: %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
Log::error(sprintf('Cannot render reports.account.report: %s', $e->getMessage()));
Log::error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
throw new FireflyException($result, 0, $e);
@@ -132,7 +133,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
protected function getExpenses(): array
{
if (0 !== count($this->expenses)) {
app('log')->debug('Return previous set of expenses.');
Log::debug('Return previous set of expenses.');
return $this->expenses;
}

View File

@@ -30,6 +30,7 @@ use FireflyIII\Generator\Report\ReportGeneratorInterface;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use Illuminate\Support\Collection;
use Throwable;
use Illuminate\Support\Facades\Log;
/**
* Class MonthReportGenerator.
@@ -73,8 +74,8 @@ class MonthReportGenerator implements ReportGeneratorInterface
->render()
;
} catch (Throwable $e) {
app('log')->error(sprintf('Cannot render reports.category.month: %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
Log::error(sprintf('Cannot render reports.category.month: %s', $e->getMessage()));
Log::error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
throw new FireflyException($result, 0, $e);
@@ -131,7 +132,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
protected function getExpenses(): array
{
if (0 !== count($this->expenses)) {
app('log')->debug('Return previous set of expenses.');
Log::debug('Return previous set of expenses.');
return $this->expenses;
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use Illuminate\Support\Collection;
use Throwable;
use Illuminate\Support\Facades\Log;
/**
* Class MonthReportGenerator.
@@ -56,8 +57,8 @@ class MonthReportGenerator implements ReportGeneratorInterface
try {
return view('reports.default.month', compact('accountIds', 'reportType'))->with('start', $this->start)->with('end', $this->end)->render();
} catch (Throwable $e) {
app('log')->error(sprintf('Cannot render reports.default.month: %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
Log::error(sprintf('Cannot render reports.default.month: %s', $e->getMessage()));
Log::error($e->getTraceAsString());
$result = 'Could not render report view.';
throw new FireflyException($result, 0, $e);

View File

@@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use Illuminate\Support\Collection;
use Throwable;
use Illuminate\Support\Facades\Log;
/**
* Class MonthReportGenerator.
@@ -60,8 +61,8 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
compact('accountIds', 'reportType')
)->with('start', $this->start)->with('end', $this->end)->render();
} catch (Throwable $e) {
app('log')->error(sprintf('Cannot render reports.default.multi-year: %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
Log::error(sprintf('Cannot render reports.default.multi-year: %s', $e->getMessage()));
Log::error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
throw new FireflyException($result, 0, $e);

View File

@@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use Illuminate\Support\Collection;
use Throwable;
use Illuminate\Support\Facades\Log;
/**
* Class MonthReportGenerator.
@@ -60,8 +61,8 @@ class YearReportGenerator implements ReportGeneratorInterface
compact('accountIds', 'reportType')
)->with('start', $this->start)->with('end', $this->end)->render();
} catch (Throwable $e) {
app('log')->error(sprintf('Cannot render reports.account.report: %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
Log::error(sprintf('Cannot render reports.account.report: %s', $e->getMessage()));
Log::error($e->getTraceAsString());
$result = 'Could not render report view.';
throw new FireflyException($result, 0, $e);

View File

@@ -29,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use Illuminate\Support\Collection;
use Throwable;
use Illuminate\Support\Facades\Log;
/**
* Class MonthReportGenerator.
@@ -67,8 +68,8 @@ class MonthReportGenerator implements ReportGeneratorInterface
compact('accountIds', 'reportType', 'tagIds')
)->with('start', $this->start)->with('end', $this->end)->with('tags', $this->tags)->with('accounts', $this->accounts)->render();
} catch (Throwable $e) {
app('log')->error(sprintf('Cannot render reports.tag.month: %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
Log::error(sprintf('Cannot render reports.tag.month: %s', $e->getMessage()));
Log::error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
throw new FireflyException($result, 0, $e);

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Rules;
use Closure;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface;
use FireflyIII\User;
@@ -68,11 +69,18 @@ class IsAllowedGroupAction implements ValidationRule
break;
}
}
$this->validateUserGroup((int) $value, $fail);
$this->validateUserGroup((int)$value, $fail);
}
private function validateUserGroup(int $userGroupId, Closure $fail): void
{
try {
throw new FireflyException('Here we are');
} catch (FireflyException $e) {
Log::error($e->getTraceAsString());
}
die('here we are');
Log::debug(sprintf('validateUserGroup: %s', static::class));
if (!auth()->check()) {
Log::debug('validateUserGroup: user is not logged in, return NULL.');
@@ -82,7 +90,7 @@ class IsAllowedGroupAction implements ValidationRule
}
/** @var User $user */
$user = auth()->user();
$user = auth()->user();
if (0 !== $userGroupId) {
Log::debug(sprintf('validateUserGroup: user group submitted, search for memberships in group #%d.', $userGroupId));
}
@@ -102,7 +110,7 @@ class IsAllowedGroupAction implements ValidationRule
}
// need to get the group from the membership:
$userGroup = $this->repository->getById($userGroupId);
$userGroup = $this->repository->getById($userGroupId);
if (null === $userGroup) {
Log::debug(sprintf('validateUserGroup: group #%d does not exist.', $userGroupId));
$fail('validation.belongs_user_or_user_group')->translate();

View File

@@ -0,0 +1,56 @@
<?php
/*
* IsValidAccountType.php
* Copyright (c) 2024 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
declare(strict_types=1);
namespace FireflyIII\Rules\TransactionType;
use Closure;
use FireflyIII\Support\Http\Api\TransactionFilter;
use Illuminate\Contracts\Validation\ValidationRule;
use Override;
class IsValidTransactionTypeList implements ValidationRule
{
use TransactionFilter;
#[Override]
public function validate(string $attribute, mixed $value, Closure $fail): void
{
// only check the type.
$values = [];
if (is_string($value)) {
$values = explode(',', $value);
}
if (!is_array($values)) {
$fail('validation.invalid_transaction_type_list')->translate();
}
$keys = array_keys($this->transactionTypes);
foreach ($values as $entry) {
$entry = (string)$entry;
if (!in_array($entry, $keys, true)) {
$fail('validation.invalid_transaction_type_list')->translate();
}
}
}
}

View File

@@ -31,39 +31,48 @@ use FireflyIII\Enums\TransactionTypeEnum;
*/
trait TransactionFilter
{
/**
* All the types you can request.
*/
protected function mapTransactionTypes(string $type): array
{
$types = [
'all' => [
protected $transactionTypes
= [
'all' => [
TransactionTypeEnum::WITHDRAWAL->value,
TransactionTypeEnum::DEPOSIT->value,
TransactionTypeEnum::TRANSFER->value,
TransactionTypeEnum::OPENING_BALANCE->value,
TransactionTypeEnum::RECONCILIATION->value,
],
'withdrawal' => [TransactionTypeEnum::WITHDRAWAL->value],
'withdrawals' => [TransactionTypeEnum::WITHDRAWAL->value],
'expense' => [TransactionTypeEnum::WITHDRAWAL->value],
'expenses' => [TransactionTypeEnum::WITHDRAWAL->value],
'income' => [TransactionTypeEnum::DEPOSIT->value],
'deposit' => [TransactionTypeEnum::DEPOSIT->value],
'deposits' => [TransactionTypeEnum::DEPOSIT->value],
'transfer' => [TransactionTypeEnum::TRANSFER->value],
'transfers' => [TransactionTypeEnum::TRANSFER->value],
'opening_balance' => [TransactionTypeEnum::OPENING_BALANCE->value],
'reconciliation' => [TransactionTypeEnum::RECONCILIATION->value],
'reconciliations' => [TransactionTypeEnum::RECONCILIATION->value],
'special' => [TransactionTypeEnum::OPENING_BALANCE->value, TransactionTypeEnum::RECONCILIATION->value],
'specials' => [TransactionTypeEnum::OPENING_BALANCE->value, TransactionTypeEnum::RECONCILIATION->value],
'default' => [TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value],
TransactionTypeEnum::WITHDRAWAL->value => [TransactionTypeEnum::WITHDRAWAL->value],
'withdrawal' => [TransactionTypeEnum::WITHDRAWAL->value],
'withdrawals' => [TransactionTypeEnum::WITHDRAWAL->value],
'expense' => [TransactionTypeEnum::WITHDRAWAL->value],
'expenses' => [TransactionTypeEnum::WITHDRAWAL->value],
TransactionTypeEnum::DEPOSIT->value => [TransactionTypeEnum::DEPOSIT->value],
'income' => [TransactionTypeEnum::DEPOSIT->value],
'deposit' => [TransactionTypeEnum::DEPOSIT->value],
'deposits' => [TransactionTypeEnum::DEPOSIT->value],
TransactionTypeEnum::TRANSFER->value => [TransactionTypeEnum::TRANSFER->value],
'transfer' => [TransactionTypeEnum::TRANSFER->value],
'transfers' => [TransactionTypeEnum::TRANSFER->value],
TransactionTypeEnum::OPENING_BALANCE->value => [TransactionTypeEnum::OPENING_BALANCE->value],
'opening_balance' => [TransactionTypeEnum::OPENING_BALANCE->value],
TransactionTypeEnum::RECONCILIATION->value => [TransactionTypeEnum::RECONCILIATION->value],
'reconciliation' => [TransactionTypeEnum::RECONCILIATION->value],
'reconciliations' => [TransactionTypeEnum::RECONCILIATION->value],
'special' => [TransactionTypeEnum::OPENING_BALANCE->value, TransactionTypeEnum::RECONCILIATION->value],
'specials' => [TransactionTypeEnum::OPENING_BALANCE->value, TransactionTypeEnum::RECONCILIATION->value],
'default' => [TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value],
];
/**
* All the types you can request.
*/
protected function mapTransactionTypes(string $type): array
{
$return = [];
$parts = explode(',', $type);
foreach ($parts as $part) {
$return = array_merge($return, $types[$part] ?? $types['default']);
if(array_key_exists($part, $this->transactionTypes)) {
$return = array_merge($return, $this->transactionTypes[$part]);
}
}
return array_unique($return);

View File

@@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Support\Http\Api;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\UserGroup;
use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface;
use FireflyIII\User;

View File

@@ -31,6 +31,7 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
/**
* Class LinkToBill.
@@ -54,29 +55,16 @@ class LinkToBill implements ActionInterface
$bill = $repository->findByName($billName);
if (null !== $bill && TransactionTypeEnum::WITHDRAWAL->value === $journal['transaction_type_type']) {
$count = DB::table('transaction_journals')->where('id', '=', $journal['transaction_journal_id'])
->where('bill_id', $bill->id)->count()
;
$count = DB::table('transaction_journals')->where('id', '=', $journal['transaction_journal_id'])->where('bill_id', $bill->id)->count();
if (0 !== $count) {
app('log')->error(
sprintf(
'RuleAction LinkToBill could not set the bill of journal #%d to bill "%s": already set.',
$journal['transaction_journal_id'],
$billName
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_linked_to_subscription', ['name' => $billName])));
Log::error(sprintf('RuleAction LinkToBill could not set the bill of journal #%d to bill "%s": already set.', $journal['transaction_journal_id'], $billName));
// event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_linked_to_subscription', ['name' => $billName])));
return false;
}
DB::table('transaction_journals')
->where('id', '=', $journal['transaction_journal_id'])
->update(['bill_id' => $bill->id])
;
app('log')->debug(
sprintf('RuleAction LinkToBill set the bill of journal #%d to bill #%d ("%s").', $journal['transaction_journal_id'], $bill->id, $bill->name)
);
DB::table('transaction_journals')->where('id', '=', $journal['transaction_journal_id'])->update(['bill_id' => $bill->id]);
Log::debug(sprintf('RuleAction LinkToBill set the bill of journal #%d to bill #%d ("%s").', $journal['transaction_journal_id'], $bill->id, $bill->name));
/** @var TransactionJournal $object */
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
@@ -85,13 +73,7 @@ class LinkToBill implements ActionInterface
return true;
}
app('log')->error(
sprintf(
'RuleAction LinkToBill could not set the bill of journal #%d to bill "%s": no such bill found or not a withdrawal.',
$journal['transaction_journal_id'],
$billName
)
);
Log::error(sprintf('RuleAction LinkToBill could not set the bill of journal #%d to bill "%s": no such bill found or not a withdrawal.', $journal['transaction_journal_id'], $billName));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_subscription', ['name' => $billName])));
return false;