mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-30 10:33:30 +00:00
Expand API and refactor for user groups.
This commit is contained in:
@@ -30,7 +30,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
@@ -79,6 +79,7 @@ class AccountController extends Controller
|
||||
*/
|
||||
public function accounts(AutocompleteRequest $request): JsonResponse
|
||||
{
|
||||
die('uses old administration ID check, needs to be updated. 1');
|
||||
$data = $request->getData();
|
||||
$types = $data['types'];
|
||||
$query = $data['query'];
|
||||
|
@@ -31,7 +31,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
@@ -55,6 +55,7 @@ class AccountController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
die('uses old administration ID check, needs to be updated.2');
|
||||
$this->repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
return $next($request);
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
@@ -32,8 +32,8 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Administration\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
@@ -78,6 +78,7 @@ class BudgetController extends Controller
|
||||
*/
|
||||
public function dashboard(DateRequest $request): JsonResponse
|
||||
{
|
||||
die('uses old administration ID check, needs to be updated.3');
|
||||
// get user.
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
|
@@ -32,7 +32,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
@@ -53,6 +53,7 @@ class CategoryController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
die('uses old administration ID check, needs to be updated.4');
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
$this->accountRepos->setAdministrationId(auth()->user()->user_group_id);
|
||||
|
@@ -171,7 +171,7 @@ class Controller extends BaseController
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final protected function jsonApiObject(string $key, Model $object, AbstractTransformer $transformer): array
|
||||
final protected function jsonApiObject(string $key, array | Model $object, AbstractTransformer $transformer): array
|
||||
{
|
||||
// create some objects:
|
||||
$manager = new Manager();
|
||||
|
@@ -27,7 +27,7 @@ namespace FireflyIII\Api\V2\Controllers\Model\Bill;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Repositories\Administration\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\AccountTransformer;
|
||||
use FireflyIII\Transformers\V2\BillTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -46,6 +46,7 @@ class ShowController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
die('uses old administration ID check, needs to be updated.5');
|
||||
$this->repository = app(BillRepositoryInterface::class);
|
||||
$this->repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
return $next($request);
|
||||
|
@@ -26,7 +26,7 @@ namespace FireflyIII\Api\V2\Controllers\Model\Bill;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||
use FireflyIII\Repositories\Administration\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
@@ -63,6 +63,7 @@ class SumController extends Controller
|
||||
*/
|
||||
public function paid(DateRequest $request): JsonResponse
|
||||
{
|
||||
die('uses old administration ID check, needs to be updated.6');
|
||||
$this->repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
$result = $this->repository->sumPaidInRange($this->parameters->get('start'), $this->parameters->get('end'));
|
||||
|
||||
@@ -82,6 +83,7 @@ class SumController extends Controller
|
||||
*/
|
||||
public function unpaid(DateRequest $request): JsonResponse
|
||||
{
|
||||
die('uses old administration ID check, needs to be updated.7');
|
||||
$this->repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
$result = $this->repository->sumUnpaidInRange($this->parameters->get('start'), $this->parameters->get('end'));
|
||||
|
||||
|
@@ -26,7 +26,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\PiggyBank;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Repositories\Administration\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\PiggyBankTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -44,6 +44,7 @@ class ShowController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
die('uses old administration ID check, needs to be updated.8');
|
||||
$this->repository = app(PiggyBankRepositoryInterface::class);
|
||||
$this->repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
return $next($request);
|
||||
|
@@ -26,25 +26,105 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Api\V2\Controllers\Model\Transaction;
|
||||
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Model\Transaction\StoreRequest;
|
||||
use FireflyIII\Events\StoredTransactionGroup;
|
||||
use FireflyIII\Exceptions\DuplicateTransactionException;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
|
||||
use FireflyIII\Rules\IsDuplicateTransaction;
|
||||
use FireflyIII\Transformers\V2\TransactionGroupTransformer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
/**
|
||||
* Class StoreController
|
||||
*/
|
||||
class StoreController extends Controller
|
||||
{
|
||||
private TransactionGroupRepositoryInterface $groupRepository;
|
||||
|
||||
/**
|
||||
* TransactionController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->groupRepository = app(TransactionGroupRepositoryInterface::class);
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO this method is practically the same as the V1 method and borrows as much code as possible.
|
||||
* TODO still it duplicates a lot.
|
||||
* TODO the v1 endpoints will never support separate administrations, this is an important distinction.
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @throws FireflyException
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function post(): JsonResponse
|
||||
public function post(StoreRequest $request): JsonResponse
|
||||
{
|
||||
|
||||
return response()->json([]);
|
||||
app('log')->debug('Now in API v2 StoreController::store()');
|
||||
$data = $request->getAll();
|
||||
$data['user'] = auth()->user()->id;
|
||||
$userGroup = $request->getUserGroup();
|
||||
$data['user_group'] = $userGroup;
|
||||
|
||||
// overrule user group and see where we end up.
|
||||
// what happens when we refer to a budget that is not in this user group?
|
||||
|
||||
app('log')->channel('audit')->info('Store new transaction over API.', $data);
|
||||
|
||||
try {
|
||||
$transactionGroup = $this->groupRepository->store($data);
|
||||
} catch (DuplicateTransactionException $e) {
|
||||
app('log')->warning('Caught a duplicate transaction. Return error message.');
|
||||
$validator = Validator::make(
|
||||
['transactions' => [['description' => $e->getMessage()]]],
|
||||
['transactions.0.description' => new IsDuplicateTransaction()]
|
||||
);
|
||||
throw new ValidationException($validator, 0, $e);
|
||||
} catch (FireflyException $e) {
|
||||
app('log')->warning('Caught an exception. Return error message.');
|
||||
app('log')->error($e->getMessage());
|
||||
$message = sprintf('Internal exception: %s', $e->getMessage());
|
||||
$validator = Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction()]);
|
||||
throw new ValidationException($validator, 0, $e);
|
||||
}
|
||||
app('preferences')->mark();
|
||||
$applyRules = $data['apply_rules'] ?? true;
|
||||
$fireWebhooks = $data['fire_webhooks'] ?? true;
|
||||
event(new StoredTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
|
||||
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
// use new group collector:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector
|
||||
->setUser($admin)
|
||||
// filter on transaction group.
|
||||
->setTransactionGroup($transactionGroup);
|
||||
|
||||
$selectedGroup = $collector->getGroups()->first();
|
||||
if (null === $selectedGroup) {
|
||||
throw new FireflyException('200032: Cannot find transaction. Possibly, a rule deleted this transaction after its creation.');
|
||||
}
|
||||
|
||||
$transformer = new TransactionGroupTransformer();
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
return response()
|
||||
->api($this->jsonApiObject('transactions', $selectedGroup, $transformer))
|
||||
->header('Content-Type', self::CONTENT_TYPE);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -36,11 +36,11 @@ use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\AvailableBudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\AvailableBudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\User;
|
||||
@@ -77,6 +77,8 @@ class BasicController extends Controller
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
|
||||
die('uses old administration ID check, needs to be updated.9');
|
||||
|
||||
$this->abRepository->setAdministrationId($user->user_group_id);
|
||||
$this->accountRepository->setAdministrationId($user->user_group_id);
|
||||
$this->billRepository->setAdministrationId($user->user_group_id);
|
||||
|
317
app/Api/V2/Request/Model/Transaction/StoreRequest.php
Normal file
317
app/Api/V2/Request/Model/Transaction/StoreRequest.php
Normal file
@@ -0,0 +1,317 @@
|
||||
<?php
|
||||
/*
|
||||
* StoreRequest.php
|
||||
* Copyright (c) 2023 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\Api\V2\Request\Model\Transaction;
|
||||
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Rules\BelongsUserGroup;
|
||||
use FireflyIII\Rules\IsBoolean;
|
||||
use FireflyIII\Rules\IsDateOrTime;
|
||||
use FireflyIII\Support\NullArrayObject;
|
||||
use FireflyIII\Support\Request\AppendsLocationData;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use FireflyIII\User;
|
||||
use FireflyIII\Validation\CurrencyValidation;
|
||||
use FireflyIII\Validation\GroupValidation;
|
||||
use FireflyIII\Validation\TransactionValidation;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
/**
|
||||
* Class StoreRequest
|
||||
*
|
||||
* TODO this class is basically the same as the v1 request. However, it does not accept
|
||||
* TODO models, objects and references that are NOT part of the designated user group (aka administration).
|
||||
* TODO this distinction is already made in the CheckLogin trait, where there is also a convenient function
|
||||
* TODO to grab the current UserGroup. This code is slightly different from other v2 apis that use
|
||||
* TODO the "administration_id", those will have to be updated later on.
|
||||
*/
|
||||
class StoreRequest extends FormRequest
|
||||
{
|
||||
protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS];
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
|
||||
use TransactionValidation;
|
||||
use GroupValidation;
|
||||
use CurrencyValidation;
|
||||
use AppendsLocationData;
|
||||
|
||||
/**
|
||||
* Get all data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
app('log')->debug('V2: Get all data in TransactionStoreRequest');
|
||||
|
||||
return [
|
||||
'group_title' => $this->convertString('group_title'),
|
||||
'error_if_duplicate_hash' => $this->boolean('error_if_duplicate_hash'),
|
||||
'apply_rules' => $this->boolean('apply_rules', true),
|
||||
'fire_webhooks' => $this->boolean('fire_webhooks', true),
|
||||
'transactions' => $this->getTransactionData(),
|
||||
];
|
||||
// TODO include location and ability to process it.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get transaction data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
$return = [];
|
||||
/**
|
||||
* @var array $transaction
|
||||
*/
|
||||
foreach ($this->get('transactions') as $transaction) {
|
||||
$object = new NullArrayObject($transaction);
|
||||
$return[] = [
|
||||
'type' => $this->clearString($object['type'], false),
|
||||
'date' => $this->dateFromValue($object['date']),
|
||||
'order' => $this->integerFromValue((string)$object['order']),
|
||||
|
||||
'currency_id' => $this->integerFromValue((string)$object['currency_id']),
|
||||
'currency_code' => $this->clearString((string)$object['currency_code'], false),
|
||||
|
||||
// foreign currency info:
|
||||
'foreign_currency_id' => $this->integerFromValue((string)$object['foreign_currency_id']),
|
||||
'foreign_currency_code' => $this->clearString((string)$object['foreign_currency_code'], false),
|
||||
|
||||
// amount and foreign amount. Cannot be 0.
|
||||
'amount' => $this->clearString((string)$object['amount'], false),
|
||||
'foreign_amount' => $this->clearString((string)$object['foreign_amount'], false),
|
||||
|
||||
// description.
|
||||
'description' => $this->clearString($object['description'], false),
|
||||
|
||||
// source of transaction. If everything is null, assume cash account.
|
||||
'source_id' => $this->integerFromValue((string)$object['source_id']),
|
||||
'source_name' => $this->clearString((string)$object['source_name'], false),
|
||||
'source_iban' => $this->clearString((string)$object['source_iban'], false),
|
||||
'source_number' => $this->clearString((string)$object['source_number'], false),
|
||||
'source_bic' => $this->clearString((string)$object['source_bic'], false),
|
||||
|
||||
// destination of transaction. If everything is null, assume cash account.
|
||||
'destination_id' => $this->integerFromValue((string)$object['destination_id']),
|
||||
'destination_name' => $this->clearString((string)$object['destination_name'], false),
|
||||
'destination_iban' => $this->clearString((string)$object['destination_iban'], false),
|
||||
'destination_number' => $this->clearString((string)$object['destination_number'], false),
|
||||
'destination_bic' => $this->clearString((string)$object['destination_bic'], false),
|
||||
|
||||
// budget info
|
||||
'budget_id' => $this->integerFromValue((string)$object['budget_id']),
|
||||
'budget_name' => $this->clearString((string)$object['budget_name'], false),
|
||||
|
||||
// category info
|
||||
'category_id' => $this->integerFromValue((string)$object['category_id']),
|
||||
'category_name' => $this->clearString((string)$object['category_name'], false),
|
||||
|
||||
// journal bill reference. Optional. Will only work for withdrawals
|
||||
'bill_id' => $this->integerFromValue((string)$object['bill_id']),
|
||||
'bill_name' => $this->clearString((string)$object['bill_name'], false),
|
||||
|
||||
// piggy bank reference. Optional. Will only work for transfers
|
||||
'piggy_bank_id' => $this->integerFromValue((string)$object['piggy_bank_id']),
|
||||
'piggy_bank_name' => $this->clearString((string)$object['piggy_bank_name'], false),
|
||||
|
||||
// some other interesting properties
|
||||
'reconciled' => $this->convertBoolean((string)$object['reconciled']),
|
||||
'notes' => $this->clearString((string)$object['notes']),
|
||||
'tags' => $this->arrayFromValue($object['tags']),
|
||||
|
||||
// all custom fields:
|
||||
'internal_reference' => $this->clearString((string)$object['internal_reference'], false),
|
||||
'external_id' => $this->clearString((string)$object['external_id'], false),
|
||||
'original_source' => sprintf('ff3-v%s|api-v%s', config('firefly.version'), config('firefly.api_version')),
|
||||
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
|
||||
'bunq_payment_id' => $this->clearString((string)$object['bunq_payment_id'], false),
|
||||
'external_url' => $this->clearString((string)$object['external_url'], false),
|
||||
|
||||
'sepa_cc' => $this->clearString((string)$object['sepa_cc'], false),
|
||||
'sepa_ct_op' => $this->clearString((string)$object['sepa_ct_op'], false),
|
||||
'sepa_ct_id' => $this->clearString((string)$object['sepa_ct_id'], false),
|
||||
'sepa_db' => $this->clearString((string)$object['sepa_db'], false),
|
||||
'sepa_country' => $this->clearString((string)$object['sepa_country'], false),
|
||||
'sepa_ep' => $this->clearString((string)$object['sepa_ep'], false),
|
||||
'sepa_ci' => $this->clearString((string)$object['sepa_ci'], false),
|
||||
'sepa_batch_id' => $this->clearString((string)$object['sepa_batch_id'], false),
|
||||
// custom date fields. Must be Carbon objects. Presence is optional.
|
||||
'interest_date' => $this->dateFromValue($object['interest_date']),
|
||||
'book_date' => $this->dateFromValue($object['book_date']),
|
||||
'process_date' => $this->dateFromValue($object['process_date']),
|
||||
'due_date' => $this->dateFromValue($object['due_date']),
|
||||
'payment_date' => $this->dateFromValue($object['payment_date']),
|
||||
'invoice_date' => $this->dateFromValue($object['invoice_date']),
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
app('log')->debug('V2: Collect rules of TransactionStoreRequest');
|
||||
|
||||
// at this point the userGroup can't be NULL because the
|
||||
// authorize() method will complain. Loudly.
|
||||
/** @var UserGroup $userGroup */
|
||||
$userGroup = $this->getUserGroup();
|
||||
|
||||
return [
|
||||
// basic fields for group:
|
||||
'group_title' => 'between:1,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|numeric|gt:0',
|
||||
'transactions.*.foreign_amount' => 'numeric',
|
||||
|
||||
// description
|
||||
'transactions.*.description' => 'nullable|between:1,1000',
|
||||
|
||||
// source of transaction
|
||||
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUserGroup($userGroup)],
|
||||
'transactions.*.source_name' => 'between:1,255|nullable',
|
||||
'transactions.*.source_iban' => 'between:1,255|nullable|iban',
|
||||
'transactions.*.source_number' => 'between:1,255|nullable',
|
||||
'transactions.*.source_bic' => 'between:1,255|nullable|bic',
|
||||
|
||||
// destination of transaction
|
||||
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUserGroup($userGroup)],
|
||||
'transactions.*.destination_name' => 'between:1,255|nullable',
|
||||
'transactions.*.destination_iban' => 'between:1,255|nullable|iban',
|
||||
'transactions.*.destination_number' => 'between:1,255|nullable',
|
||||
'transactions.*.destination_bic' => 'between:1,255|nullable|bic',
|
||||
|
||||
// budget, category, bill and piggy
|
||||
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUserGroup($userGroup)],
|
||||
'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
|
||||
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUserGroup($userGroup), 'nullable'],
|
||||
'transactions.*.category_name' => 'between:1,255|nullable',
|
||||
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUserGroup($userGroup)],
|
||||
'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
|
||||
'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUserGroup($userGroup)],
|
||||
'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
|
||||
|
||||
// other interesting fields
|
||||
'transactions.*.reconciled' => [new IsBoolean()],
|
||||
'transactions.*.notes' => 'min:1|max:50000|nullable',
|
||||
'transactions.*.tags' => 'between:0,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' => 'min:1|max:255|nullable|url',
|
||||
|
||||
// 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.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
/** @var UserGroup $userGroup */
|
||||
$userGroup = $this->getUserGroup();
|
||||
$validator->after(
|
||||
function (Validator $validator) use ($user, $userGroup) {
|
||||
// must be valid array.
|
||||
$this->validateTransactionArray($validator); // does not need group validation.
|
||||
|
||||
// must submit at least one transaction.
|
||||
app('log')->debug('Now going to validateOneTransaction');
|
||||
$this->validateOneTransaction($validator); // does not need group validation.
|
||||
app('log')->debug('Now done with validateOneTransaction');
|
||||
|
||||
// all journals must have a description
|
||||
$this->validateDescriptions($validator); // does not need group validation.
|
||||
|
||||
// all transaction types must be equal:
|
||||
$this->validateTransactionTypes($validator); // does not need group validation.
|
||||
|
||||
// validate foreign currency info
|
||||
$this->validateForeignCurrencyInformation($validator); // does not need group validation.
|
||||
|
||||
// validate all account info
|
||||
$this->validateAccountInformation($validator, $user, $userGroup);
|
||||
|
||||
// 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);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -81,7 +81,7 @@ class TransactionGroupFactory
|
||||
|
||||
$group = new TransactionGroup();
|
||||
$group->user()->associate($this->user);
|
||||
$group->userGroup()->associate($this->user->userGroup);
|
||||
$group->userGroup()->associate($data['user_group'] ?? $this->user->userGroup);
|
||||
$group->title = $title;
|
||||
$group->save();
|
||||
|
||||
|
@@ -33,7 +33,7 @@ class TransactionObserver
|
||||
public function deleting(Transaction $transaction): void
|
||||
{
|
||||
app('log')->debug('Observe "deleting" of a transaction.');
|
||||
$transaction->transactionJournal->delete();
|
||||
$transaction?->transactionJournal?->delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
@@ -245,6 +245,7 @@ class NetWorth implements NetWorthInterface
|
||||
{
|
||||
$this->userGroup = $userGroup;
|
||||
$this->adminAccountRepository = app(AdminAccountRepositoryInterface::class);
|
||||
die('uses old administration ID check, needs to be updated.A');
|
||||
$this->adminAccountRepository->setAdministrationId($userGroup->id);
|
||||
}
|
||||
|
||||
|
@@ -29,8 +29,8 @@ use FireflyIII\Repositories\Account\AccountTasker;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use FireflyIII\Repositories\Account\OperationsRepository;
|
||||
use FireflyIII\Repositories\Account\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepository as AdminAccountRepository;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepository as AdminAccountRepository;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
@@ -42,9 +42,7 @@ class AccountServiceProvider extends ServiceProvider
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
}
|
||||
public function boot(): void {}
|
||||
|
||||
/**
|
||||
* Register the application services.
|
||||
@@ -84,7 +82,6 @@ class AccountServiceProvider extends ServiceProvider
|
||||
// phpstan thinks auth does not exist.
|
||||
if ($app->auth->check()) { // @phpstan-ignore-line
|
||||
$repository->setUser(auth()->user());
|
||||
$repository->setAdministrationId((int)auth()->user()->user_group_id);
|
||||
}
|
||||
|
||||
return $repository;
|
||||
|
@@ -25,8 +25,8 @@ namespace FireflyIII\Providers;
|
||||
|
||||
use FireflyIII\Repositories\Bill\BillRepository;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Bill\BillRepository as AdminBillRepository;
|
||||
use FireflyIII\Repositories\Administration\Bill\BillRepositoryInterface as AdminBillRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Bill\BillRepository as AdminBillRepository;
|
||||
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface as AdminBillRepositoryInterface;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
@@ -38,9 +38,7 @@ class BillServiceProvider extends ServiceProvider
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
}
|
||||
public function boot(): void {}
|
||||
|
||||
/**
|
||||
* Register the application services.
|
||||
|
@@ -25,20 +25,20 @@ namespace FireflyIII\Providers;
|
||||
|
||||
use FireflyIII\Repositories\Budget\AvailableBudgetRepository;
|
||||
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\AvailableBudgetRepository as AdminAbRepository;
|
||||
use FireflyIII\Repositories\Administration\Budget\AvailableBudgetRepositoryInterface as AdminAbRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\AvailableBudgetRepository as AdminAbRepository;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\AvailableBudgetRepositoryInterface as AdminAbRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetLimitRepository;
|
||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepository;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\BudgetRepository as AdminBudgetRepository;
|
||||
use FireflyIII\Repositories\Administration\Budget\BudgetRepositoryInterface as AdminBudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\BudgetRepository as AdminBudgetRepository;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\BudgetRepositoryInterface as AdminBudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\NoBudgetRepository;
|
||||
use FireflyIII\Repositories\Budget\NoBudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\OperationsRepository;
|
||||
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\Administration\Budget\OperationsRepository as AdminOperationsRepository;
|
||||
use FireflyIII\Repositories\Administration\Budget\OperationsRepositoryInterface as AdminOperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\OperationsRepository as AdminOperationsRepository;
|
||||
use FireflyIII\Repositories\UserGroups\Budget\OperationsRepositoryInterface as AdminOperationsRepositoryInterface;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
@@ -50,9 +50,7 @@ class BudgetServiceProvider extends ServiceProvider
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
}
|
||||
public function boot(): void {}
|
||||
|
||||
/**
|
||||
* Register the application services.
|
||||
@@ -80,6 +78,7 @@ class BudgetServiceProvider extends ServiceProvider
|
||||
$repository = app(AdminBudgetRepository::class);
|
||||
if ($app->auth->check()) { // @phpstan-ignore-line
|
||||
$repository->setUser(auth()->user());
|
||||
die('uses old administration ID check, needs to be updated.C');
|
||||
$repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
}
|
||||
|
||||
@@ -109,6 +108,7 @@ class BudgetServiceProvider extends ServiceProvider
|
||||
$repository = app(AdminAbRepository::class);
|
||||
if ($app->auth->check()) { // @phpstan-ignore-line
|
||||
$repository->setUser(auth()->user());
|
||||
die('uses old administration ID check, needs to be updated.D');
|
||||
$repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
}
|
||||
|
||||
@@ -164,6 +164,7 @@ class BudgetServiceProvider extends ServiceProvider
|
||||
$repository = app(AdminOperationsRepository::class);
|
||||
if ($app->auth->check()) { // @phpstan-ignore-line
|
||||
$repository->setUser(auth()->user());
|
||||
die('uses old administration ID check, needs to be updated.E');
|
||||
$repository->setAdministrationId(auth()->user()->user_group_id);
|
||||
}
|
||||
|
||||
|
@@ -26,8 +26,8 @@ namespace FireflyIII\Providers;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepository;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
|
||||
use FireflyIII\Repositories\Administration\PiggyBank\PiggyBankRepository as AdminPiggyBankRepository;
|
||||
use FireflyIII\Repositories\Administration\PiggyBank\PiggyBankRepositoryInterface as AdminPiggyBankRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\PiggyBank\PiggyBankRepository as AdminPiggyBankRepository;
|
||||
use FireflyIII\Repositories\UserGroups\PiggyBank\PiggyBankRepositoryInterface as AdminPiggyBankRepositoryInterface;
|
||||
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
@@ -40,9 +40,7 @@ class PiggyBankServiceProvider extends ServiceProvider
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
}
|
||||
public function boot(): void {}
|
||||
|
||||
/**
|
||||
* Register the application services.
|
||||
|
@@ -23,13 +23,13 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\Account;
|
||||
namespace FireflyIII\Repositories\UserGroups\Account;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Support\Repositories\Administration\AdministrationTrait;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
@@ -38,7 +38,7 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class AccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
use AdministrationTrait;
|
||||
use UserGroupTrait;
|
||||
|
||||
/**
|
||||
* @param Account $account
|
@@ -23,7 +23,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\Account;
|
||||
namespace FireflyIII\Repositories\UserGroups\Account;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
@@ -23,7 +23,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\Bill;
|
||||
namespace FireflyIII\Repositories\UserGroups\Bill;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Bill;
|
||||
@@ -31,7 +31,7 @@ use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\Support\Repositories\Administration\AdministrationTrait;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class BillRepository implements BillRepositoryInterface
|
||||
{
|
||||
use AdministrationTrait;
|
||||
use UserGroupTrait;
|
||||
|
||||
/**
|
||||
* Correct order of piggies in case of issues.
|
@@ -23,7 +23,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\Bill;
|
||||
namespace FireflyIII\Repositories\UserGroups\Bill;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Bill;
|
@@ -23,19 +23,19 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\Budget;
|
||||
namespace FireflyIII\Repositories\UserGroups\Budget;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\AvailableBudget;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\Support\Repositories\Administration\AdministrationTrait;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
|
||||
/**
|
||||
* Class AvailableBudgetRepository
|
||||
*/
|
||||
class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
||||
{
|
||||
use AdministrationTrait;
|
||||
use UserGroupTrait;
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
@@ -23,7 +23,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\Budget;
|
||||
namespace FireflyIII\Repositories\UserGroups\Budget;
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
@@ -23,9 +23,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\Budget;
|
||||
namespace FireflyIII\Repositories\UserGroups\Budget;
|
||||
|
||||
use FireflyIII\Support\Repositories\Administration\AdministrationTrait;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@@ -33,7 +33,7 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class BudgetRepository implements BudgetRepositoryInterface
|
||||
{
|
||||
use AdministrationTrait;
|
||||
use UserGroupTrait;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
@@ -23,7 +23,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\Budget;
|
||||
namespace FireflyIII\Repositories\UserGroups\Budget;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
@@ -23,13 +23,13 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\Budget;
|
||||
namespace FireflyIII\Repositories\UserGroups\Budget;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Support\Repositories\Administration\AdministrationTrait;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class OperationsRepository implements OperationsRepositoryInterface
|
||||
{
|
||||
use AdministrationTrait;
|
||||
use UserGroupTrait;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
@@ -132,6 +132,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
{
|
||||
/** @var BudgetRepositoryInterface $repos */
|
||||
$repos = app(BudgetRepositoryInterface::class);
|
||||
die('uses old administration ID check, needs to be updated.F');
|
||||
$repos->setAdministrationId($this->getAdministrationId());
|
||||
|
||||
return $repos->getActiveBudgets();
|
@@ -23,7 +23,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\Budget;
|
||||
namespace FireflyIII\Repositories\UserGroups\Budget;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
@@ -23,9 +23,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\PiggyBank;
|
||||
namespace FireflyIII\Repositories\UserGroups\PiggyBank;
|
||||
|
||||
use FireflyIII\Support\Repositories\Administration\AdministrationTrait;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@@ -33,7 +33,7 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
{
|
||||
use AdministrationTrait;
|
||||
use UserGroupTrait;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
@@ -23,7 +23,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Administration\PiggyBank;
|
||||
namespace FireflyIII\Repositories\UserGroups\PiggyBank;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Rules;
|
||||
|
||||
use Closure;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
@@ -31,54 +32,28 @@ use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class BelongsUser
|
||||
*/
|
||||
class BelongsUser implements Rule
|
||||
class BelongsUser implements ValidationRule
|
||||
{
|
||||
/**
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @return void
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function message(): string
|
||||
{
|
||||
return (string)trans('validation.belongs_user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
* @throws FireflyException
|
||||
*
|
||||
*/
|
||||
public function passes($attribute, $value): bool
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
$attribute = $this->parseAttribute($attribute);
|
||||
if (!auth()->check()) {
|
||||
return true;
|
||||
$fail('validation.belongs_user')->translate();
|
||||
return;
|
||||
}
|
||||
$attribute = (string)$attribute;
|
||||
Log::debug(sprintf('Going to validate %s', $attribute));
|
||||
|
||||
return match ($attribute) {
|
||||
$result = match ($attribute) {
|
||||
'piggy_bank_id' => $this->validatePiggyBankId((int)$value),
|
||||
'piggy_bank_name' => $this->validatePiggyBankName($value),
|
||||
'bill_id' => $this->validateBillId((int)$value),
|
||||
@@ -88,8 +63,11 @@ class BelongsUser implements Rule
|
||||
'category_id' => $this->validateCategoryId((int)$value),
|
||||
'budget_name' => $this->validateBudgetName($value),
|
||||
'source_id', 'destination_id' => $this->validateAccountId((int)$value),
|
||||
default => throw new FireflyException(sprintf('Rule BelongUser cannot handle "%s"', $attribute)),
|
||||
default => throw new FireflyException(sprintf('Rule BelongsUser cannot handle "%s"', $attribute)),
|
||||
};
|
||||
if (false === $result) {
|
||||
$fail('validation.belongs_user')->translate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
262
app/Rules/BelongsUserGroup.php
Normal file
262
app/Rules/BelongsUserGroup.php
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
/*
|
||||
* BelongsUserGroup.php
|
||||
* Copyright (c) 2023 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;
|
||||
|
||||
use Closure;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class BelongsUserGroup
|
||||
* TODO this method has a lot in common with BelongsUser but will check if the UserGroup
|
||||
* TODO that is submitted is valid. This method will not validate if the user has a valid ROLE in this
|
||||
* TODO group.
|
||||
*/
|
||||
class BelongsUserGroup implements ValidationRule
|
||||
{
|
||||
private UserGroup $userGroup;
|
||||
|
||||
/**
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(UserGroup $userGroup)
|
||||
{
|
||||
$this->userGroup = $userGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
$attribute = $this->parseAttribute($attribute);
|
||||
if (!auth()->check()) {
|
||||
$fail('validation.belongs_user')->translate();
|
||||
return;
|
||||
}
|
||||
$attribute = (string)$attribute;
|
||||
Log::debug(sprintf('Going to validate %s', $attribute));
|
||||
|
||||
$result = match ($attribute) {
|
||||
'piggy_bank_id' => $this->validatePiggyBankId((int)$value),
|
||||
'piggy_bank_name' => $this->validatePiggyBankName($value),
|
||||
'bill_id' => $this->validateBillId((int)$value),
|
||||
'transaction_journal_id' => $this->validateJournalId((int)$value),
|
||||
'bill_name' => $this->validateBillName($value),
|
||||
'budget_id' => $this->validateBudgetId((int)$value),
|
||||
'category_id' => $this->validateCategoryId((int)$value),
|
||||
'budget_name' => $this->validateBudgetName($value),
|
||||
'source_id', 'destination_id' => $this->validateAccountId((int)$value),
|
||||
default => throw new FireflyException(sprintf('Rule BelongsUser cannot handle "%s"', $attribute)),
|
||||
};
|
||||
if (false === $result) {
|
||||
$fail('validation.belongs_user_or_user_group')->translate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $attribute
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function parseAttribute(string $attribute): string
|
||||
{
|
||||
$parts = explode('.', $attribute);
|
||||
if (1 === count($parts)) {
|
||||
return $attribute;
|
||||
}
|
||||
if (3 === count($parts)) {
|
||||
return $parts[2];
|
||||
}
|
||||
|
||||
return $attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validatePiggyBankId(int $value): bool
|
||||
{
|
||||
$count = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
|
||||
->where('piggy_banks.id', '=', $value)
|
||||
->where('accounts.user_group_id', '=', $this->userGroup->id)->count();
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validatePiggyBankName(string $value): bool
|
||||
{
|
||||
$count = $this->countField(PiggyBank::class, 'name', $value);
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $field
|
||||
* @param string $value
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
*/
|
||||
protected function countField(string $class, string $field, string $value): int
|
||||
{
|
||||
$value = trim($value);
|
||||
$objects = [];
|
||||
// get all objects belonging to user:
|
||||
if (PiggyBank::class === $class) {
|
||||
$objects = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
|
||||
->where('accounts.user_group_id', '=', $this->userGroup->id)->get(['piggy_banks.*']);
|
||||
}
|
||||
if (PiggyBank::class !== $class) {
|
||||
$objects = $class::where('user_group_id', '=', $this->userGroup->id)->get();
|
||||
}
|
||||
$count = 0;
|
||||
foreach ($objects as $object) {
|
||||
$objectValue = trim((string)$object->$field);
|
||||
app('log')->debug(sprintf('Comparing object "%s" with value "%s"', $objectValue, $value));
|
||||
if ($objectValue === $value) {
|
||||
$count++;
|
||||
app('log')->debug(sprintf('Hit! Count is now %d', $count));
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validateBillId(int $value): bool
|
||||
{
|
||||
if (0 === $value) {
|
||||
return true;
|
||||
}
|
||||
$count = Bill::where('id', '=', $value)->where('user_group_id', '=', $this->userGroup->id)->count();
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validateJournalId(int $value): bool
|
||||
{
|
||||
if (0 === $value) {
|
||||
return true;
|
||||
}
|
||||
$count = TransactionJournal::where('id', '=', $value)->where('user_group_id', '=', $this->userGroup->id)->count();
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validateBillName(string $value): bool
|
||||
{
|
||||
$count = $this->countField(Bill::class, 'name', $value);
|
||||
app('log')->debug(sprintf('Result of countField for bill name "%s" is %d', $value, $count));
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validateBudgetId(int $value): bool
|
||||
{
|
||||
if (0 === $value) {
|
||||
return true;
|
||||
}
|
||||
$count = Budget::where('id', '=', $value)->where('user_group_id', '=', $this->userGroup->id)->count();
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validateCategoryId(int $value): bool
|
||||
{
|
||||
$count = Category::where('id', '=', $value)->where('user_group_id', '=', $this->userGroup->id)->count();
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validateBudgetName(string $value): bool
|
||||
{
|
||||
$count = $this->countField(Budget::class, 'name', $value);
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validateAccountId(int $value): bool
|
||||
{
|
||||
if (0 === $value) {
|
||||
// its ok to submit 0. other checks will fail.
|
||||
return true;
|
||||
}
|
||||
$count = Account::where('id', '=', $value)->where('user_group_id', '=', $this->userGroup->id)->count();
|
||||
|
||||
return 1 === $count;
|
||||
}
|
||||
}
|
@@ -1,95 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
* AdministrationTrait.php
|
||||
* Copyright (c) 2023 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\Support\Repositories\Administration;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\GroupMembership;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
|
||||
/**
|
||||
* Trait AdministrationTrait
|
||||
*/
|
||||
trait AdministrationTrait
|
||||
{
|
||||
protected ?int $administrationId = null;
|
||||
protected User $user;
|
||||
protected ?UserGroup $userGroup = null;
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getAdministrationId(): int
|
||||
{
|
||||
return $this->administrationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $administrationId
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function setAdministrationId(int $administrationId): void
|
||||
{
|
||||
$this->administrationId = $administrationId;
|
||||
$this->refreshAdministration();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function refreshAdministration(): void
|
||||
{
|
||||
if (null !== $this->administrationId) {
|
||||
$memberships = GroupMembership::where('user_id', $this->user->id)
|
||||
->where('user_group_id', $this->administrationId)
|
||||
->count();
|
||||
if (0 === $memberships) {
|
||||
throw new FireflyException(sprintf('User #%d has no access to administration #%d', $this->user->id, $this->administrationId));
|
||||
}
|
||||
$this->userGroup = UserGroup::find($this->administrationId);
|
||||
if (null === $this->userGroup) {
|
||||
throw new FireflyException(sprintf('Unfound administration for user #%d', $this->user->id));
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw new FireflyException(sprintf('Cannot validate administration for user #%d', $this->user->id));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Authenticatable|User|null $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUser(Authenticatable|User|null $user): void
|
||||
{
|
||||
if (null !== $user) {
|
||||
$this->user = $user;
|
||||
}
|
||||
}
|
||||
}
|
85
app/Support/Repositories/UserGroup/UserGroupTrait.php
Normal file
85
app/Support/Repositories/UserGroup/UserGroupTrait.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
* UserGroupTrait.php
|
||||
* Copyright (c) 2023 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\Support\Repositories\UserGroup;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\GroupMembership;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
|
||||
/**
|
||||
* Trait UserGroupTrait
|
||||
*/
|
||||
trait UserGroupTrait
|
||||
{
|
||||
protected User $user;
|
||||
protected UserGroup $userGroup;
|
||||
|
||||
/**
|
||||
* @param Authenticatable|User|null $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUser(Authenticatable | User | null $user): void
|
||||
{
|
||||
if (null !== $user) {
|
||||
$this->user = $user;
|
||||
$this->userGroup = $user->userGroup;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO This method does not check if the user has access to this particular user group.
|
||||
*
|
||||
* @param UserGroup $userGroup
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUserGroup(UserGroup $userGroup): void
|
||||
{
|
||||
$this->userGroup = $userGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userGroupId
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function setUserGroupById(int $userGroupId): void
|
||||
{
|
||||
$memberships = GroupMembership::where('user_id', $this->user->id)
|
||||
->where('user_group_id', $userGroupId)
|
||||
->count();
|
||||
if (0 === $memberships) {
|
||||
throw new FireflyException(sprintf('User #%d has no access to administration #%d', $this->user->id, $userGroupId));
|
||||
}
|
||||
$this->userGroup = UserGroup::find($userGroupId);
|
||||
if (null === $this->userGroup) {
|
||||
throw new FireflyException(sprintf('Unfound administration for user #%d', $this->user->id));
|
||||
}
|
||||
}
|
||||
}
|
@@ -27,7 +27,6 @@ use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use ValueError;
|
||||
|
||||
/**
|
||||
* Trait ChecksLogin
|
||||
@@ -51,20 +50,51 @@ trait ChecksLogin
|
||||
app('log')->debug('Request class has no acceptedRoles array');
|
||||
return true; // check for false already took place.
|
||||
}
|
||||
/** @var UserGroup $userGroup */
|
||||
$userGroup = $this->route()->parameter('userGroup');
|
||||
if (null === $userGroup) {
|
||||
app('log')->debug('Request class has no userGroup parameter.');
|
||||
return true;
|
||||
}
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$user = auth()->user();
|
||||
$userGroup = $this->getUserGroup();
|
||||
if (null === $userGroup) {
|
||||
app('log')->error('User has no valid user group submitted or otherwise.');
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var UserRoleEnum $role */
|
||||
foreach ($this->acceptedRoles as $role) {
|
||||
if ($user->hasRoleInGroup($userGroup, $role, true, true)) {
|
||||
// system owner cannot overrule this, MUST be member of the group.
|
||||
if ($user->hasRoleInGroup($userGroup, $role, true, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user group or NULL if none is set.
|
||||
* Will throw exception if invalid.
|
||||
*
|
||||
* @return UserGroup|null
|
||||
*/
|
||||
public function getUserGroup(): ?UserGroup
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
app('log')->debug('Now in getUserGroup()');
|
||||
/** @var UserGroup $userGroup */
|
||||
$userGroup = $this->route()->parameter('userGroup');
|
||||
if (null === $userGroup) {
|
||||
app('log')->debug('Request class has no userGroup parameter, but perhaps there is a parameter.');
|
||||
$userGroupId = (int)$this->get('user_group_id');
|
||||
if (0 === $userGroupId) {
|
||||
app('log')->debug(sprintf('Request class has no user_group_id parameter, grab default from user (group #%d).', $user->user_group_id));
|
||||
$userGroupId = (int)$user->user_group_id;
|
||||
}
|
||||
$userGroup = UserGroup::find($userGroupId);
|
||||
if (null === $userGroup) {
|
||||
app('log')->error(sprintf('Request class has user_group_id (#%d), but group does not exist.', $userGroupId));
|
||||
return null;
|
||||
}
|
||||
app('log')->debug('Request class has valid user_group_id.');
|
||||
}
|
||||
return $userGroup;
|
||||
}
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@ namespace FireflyIII\Support\Request;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\Exceptions\InvalidDateException;
|
||||
use Carbon\Exceptions\InvalidFormatException;
|
||||
use FireflyIII\Repositories\Administration\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
@@ -171,6 +171,7 @@ trait ConvertsDataTypes
|
||||
// set administration ID
|
||||
// group ID
|
||||
$administrationId = auth()->user()->getAdministrationId();
|
||||
die('uses old administration ID check, needs to be updated.G');
|
||||
$repository->setAdministrationId($administrationId);
|
||||
|
||||
$set = $this->get('accounts');
|
||||
|
@@ -139,7 +139,7 @@ trait DepositValidation
|
||||
// if the user submits an ID, but that ID is not of the correct type,
|
||||
// return false.
|
||||
if (null !== $accountId) {
|
||||
$search = $this->accountRepository->find($accountId);
|
||||
$search = $this->getRepository()->find($accountId);
|
||||
if (null !== $search && !in_array($search->accountType->type, $validTypes, true)) {
|
||||
Log::debug(sprintf('User submitted an ID (#%d), which is a "%s", so this is not a valid source.', $accountId, $search->accountType->type));
|
||||
Log::debug(sprintf('Firefly III accepts ID #%d as valid account data.', $accountId));
|
||||
@@ -153,7 +153,7 @@ trait DepositValidation
|
||||
|
||||
// if user submits an IBAN:
|
||||
if (null !== $accountIban) {
|
||||
$search = $this->accountRepository->findByIbanNull($accountIban, $validTypes);
|
||||
$search = $this->getRepository()->findByIbanNull($accountIban, $validTypes);
|
||||
if (null !== $search && !in_array($search->accountType->type, $validTypes, true)) {
|
||||
Log::debug(sprintf('User submitted IBAN ("%s"), which is a "%s", so this is not a valid source.', $accountIban, $search->accountType->type));
|
||||
$result = false;
|
||||
@@ -167,7 +167,7 @@ trait DepositValidation
|
||||
|
||||
// if user submits a number:
|
||||
if (null !== $accountNumber && '' !== $accountNumber) {
|
||||
$search = $this->accountRepository->findByAccountNumber($accountNumber, $validTypes);
|
||||
$search = $this->getRepository()->findByAccountNumber($accountNumber, $validTypes);
|
||||
if (null !== $search && !in_array($search->accountType->type, $validTypes, true)) {
|
||||
Log::debug(
|
||||
sprintf('User submitted number ("%s"), which is a "%s", so this is not a valid source.', $accountNumber, $search->accountType->type)
|
||||
|
@@ -115,7 +115,7 @@ trait OBValidation
|
||||
// return false.
|
||||
if (null !== $accountId && null === $accountName) {
|
||||
Log::debug('Source ID is not null, but name is null.');
|
||||
$search = $this->accountRepository->find($accountId);
|
||||
$search = $this->getRepository()->find($accountId);
|
||||
|
||||
// the source resulted in an account, but it's not of a valid type.
|
||||
if (null !== $search && !in_array($search->accountType->type, $validTypes, true)) {
|
||||
|
@@ -108,7 +108,7 @@ trait WithdrawalValidation
|
||||
|
||||
// if there's an ID it must be of the "validTypes".
|
||||
if (null !== $accountId && 0 !== $accountId) {
|
||||
$found = $this->accountRepository->find($accountId);
|
||||
$found = $this->getRepository()->find($accountId);
|
||||
if (null !== $found) {
|
||||
$type = $found->accountType->type;
|
||||
if (in_array($type, $validTypes, true)) {
|
||||
|
@@ -26,9 +26,10 @@ namespace FireflyIII\Validation;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface as UserGroupAccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use FireflyIII\Validation\Account\AccountValidatorProperties;
|
||||
use FireflyIII\Validation\Account\DepositValidation;
|
||||
use FireflyIII\Validation\Account\LiabilityValidation;
|
||||
use FireflyIII\Validation\Account\OBValidation;
|
||||
@@ -42,7 +43,6 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class AccountValidator
|
||||
{
|
||||
use AccountValidatorProperties;
|
||||
use WithdrawalValidation;
|
||||
use DepositValidation;
|
||||
use TransferValidation;
|
||||
@@ -50,28 +50,32 @@ class AccountValidator
|
||||
use OBValidation;
|
||||
use LiabilityValidation;
|
||||
|
||||
public bool $createMode;
|
||||
public string $destError;
|
||||
public ?Account $destination;
|
||||
public ?Account $source;
|
||||
public string $sourceError;
|
||||
private AccountRepositoryInterface $accountRepository;
|
||||
private array $combinations;
|
||||
private string $transactionType;
|
||||
private User $user;
|
||||
public bool $createMode;
|
||||
public string $destError;
|
||||
public ?Account $destination;
|
||||
public ?Account $source;
|
||||
public string $sourceError;
|
||||
private AccountRepositoryInterface $accountRepository;
|
||||
private array $combinations;
|
||||
private string $transactionType;
|
||||
private bool $useUserGroupRepository = false;
|
||||
private User $user;
|
||||
private UserGroup $userGroup;
|
||||
private UserGroupAccountRepositoryInterface $userGroupAccountRepository;
|
||||
|
||||
/**
|
||||
* AccountValidator constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->createMode = false;
|
||||
$this->destError = 'No error yet.';
|
||||
$this->sourceError = 'No error yet.';
|
||||
$this->combinations = config('firefly.source_dests');
|
||||
$this->source = null;
|
||||
$this->destination = null;
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->createMode = false;
|
||||
$this->destError = 'No error yet.';
|
||||
$this->sourceError = 'No error yet.';
|
||||
$this->combinations = config('firefly.source_dests');
|
||||
$this->source = null;
|
||||
$this->destination = null;
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->userGroupAccountRepository = app(UserGroupAccountRepositoryInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,6 +130,19 @@ class AccountValidator
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->accountRepository->setUser($user);
|
||||
$this->useUserGroupRepository = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UserGroup $userGroup
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUserGroup(UserGroup $userGroup): void
|
||||
{
|
||||
$this->userGroup = $userGroup;
|
||||
$this->userGroupAccountRepository->setUserGroup($userGroup);
|
||||
$this->useUserGroupRepository = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,7 +282,7 @@ class AccountValidator
|
||||
|
||||
// find by ID
|
||||
if (null !== $accountId && $accountId > 0) {
|
||||
$first = $this->accountRepository->find($accountId);
|
||||
$first = $this->getRepository()->find($accountId);
|
||||
$accountType = null === $first ? 'invalid' : $first->accountType->type;
|
||||
$check = in_array($accountType, $validTypes, true);
|
||||
$check = $inverse ? !$check : $check; // reverse the validation check if necessary.
|
||||
@@ -277,7 +294,7 @@ class AccountValidator
|
||||
|
||||
// find by iban
|
||||
if (null !== $accountIban && '' !== (string)$accountIban) {
|
||||
$first = $this->accountRepository->findByIbanNull($accountIban, $validTypes);
|
||||
$first = $this->getRepository()->findByIbanNull($accountIban, $validTypes);
|
||||
$accountType = null === $first ? 'invalid' : $first->accountType->type;
|
||||
$check = in_array($accountType, $validTypes, true);
|
||||
$check = $inverse ? !$check : $check; // reverse the validation check if necessary.
|
||||
@@ -289,7 +306,7 @@ class AccountValidator
|
||||
|
||||
// find by number
|
||||
if (null !== $accountNumber && '' !== (string)$accountNumber) {
|
||||
$first = $this->accountRepository->findByAccountNumber($accountNumber, $validTypes);
|
||||
$first = $this->getRepository()->findByAccountNumber($accountNumber, $validTypes);
|
||||
$accountType = null === $first ? 'invalid' : $first->accountType->type;
|
||||
$check = in_array($accountType, $validTypes, true);
|
||||
$check = $inverse ? !$check : $check; // reverse the validation check if necessary.
|
||||
@@ -301,7 +318,7 @@ class AccountValidator
|
||||
|
||||
// find by name:
|
||||
if ('' !== (string)$accountName) {
|
||||
$first = $this->accountRepository->findByName($accountName, $validTypes);
|
||||
$first = $this->getRepository()->findByName($accountName, $validTypes);
|
||||
if (null !== $first) {
|
||||
app('log')->debug(sprintf('Name: Found %s account #%d ("%s", IBAN "%s")', $first->accountType->type, $first->id, $first->name, $first->iban ?? 'no iban'));
|
||||
return $first;
|
||||
@@ -311,4 +328,16 @@ class AccountValidator
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AccountRepositoryInterface|UserGroupAccountRepositoryInterface
|
||||
*/
|
||||
private function getRepository(): AccountRepositoryInterface | UserGroupAccountRepositoryInterface
|
||||
{
|
||||
if ($this->useUserGroupRepository) {
|
||||
return $this->userGroupAccountRepository;
|
||||
}
|
||||
|
||||
return $this->accountRepository;
|
||||
}
|
||||
}
|
||||
|
@@ -27,7 +27,6 @@ namespace FireflyIII\Validation\Administration;
|
||||
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\UserRole;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
|
@@ -47,7 +47,6 @@ use PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException;
|
||||
use PragmaRX\Google2FA\Exceptions\InvalidCharactersException;
|
||||
use PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException;
|
||||
use ValueError;
|
||||
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
|
@@ -30,7 +30,9 @@ use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
@@ -42,17 +44,20 @@ trait TransactionValidation
|
||||
/**
|
||||
* Validates the given account information. Switches on given transaction type.
|
||||
*
|
||||
* @param Validator $validator
|
||||
* Inclusion of user and/or group is optional.
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @param User|null $user
|
||||
* @param UserGroup|null $userGroup
|
||||
*/
|
||||
public function validateAccountInformation(Validator $validator): void
|
||||
public function validateAccountInformation(Validator $validator, User $user = null, UserGroup $userGroup = null): void
|
||||
{
|
||||
if ($validator->errors()->count() > 0) {
|
||||
return;
|
||||
}
|
||||
Log::debug('Now in validateAccountInformation (TransactionValidation) ()');
|
||||
$transactions = $this->getTransactionsArray($validator);
|
||||
$data = $validator->getData();
|
||||
|
||||
$transactions = $this->getTransactionsArray($validator);
|
||||
$data = $validator->getData();
|
||||
$transactionType = $data['type'] ?? 'invalid';
|
||||
|
||||
Log::debug(sprintf('Going to loop %d transaction(s)', count($transactions)));
|
||||
@@ -61,6 +66,8 @@ trait TransactionValidation
|
||||
* @var array $transaction
|
||||
*/
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$transaction['user'] = $user;
|
||||
$transaction['user_group'] = $userGroup;
|
||||
if (!is_int($index)) {
|
||||
continue;
|
||||
}
|
||||
@@ -107,6 +114,13 @@ trait TransactionValidation
|
||||
/** @var AccountValidator $accountValidator */
|
||||
$accountValidator = app(AccountValidator::class);
|
||||
|
||||
if (array_key_exists('user', $transaction) && null !== $transaction['user']) {
|
||||
$accountValidator->setUser($transaction['user']);
|
||||
}
|
||||
if (array_key_exists('user_group', $transaction) && null !== $transaction['user_group']) {
|
||||
$accountValidator->setUserGroup($transaction['user_group']);
|
||||
}
|
||||
|
||||
$transactionType = $transaction['type'] ?? $transactionType;
|
||||
$accountValidator->setTransactionType($transactionType);
|
||||
|
||||
@@ -204,7 +218,8 @@ trait TransactionValidation
|
||||
array $transaction,
|
||||
string $transactionType,
|
||||
int $index
|
||||
): void {
|
||||
): void
|
||||
{
|
||||
Log::debug('Now in sanityCheckForeignCurrency()');
|
||||
if (0 !== $validator->errors()->count()) {
|
||||
Log::debug('Already have errors, return');
|
||||
|
@@ -50,6 +50,7 @@ return [
|
||||
'invalid_transaction_type' => 'Invalid transaction type.',
|
||||
'invalid_selection' => 'Your selection is invalid.',
|
||||
'belongs_user' => 'This value is invalid for this field.',
|
||||
'belongs_user_or_user_group' => 'This value is invalid for this field.',
|
||||
'at_least_one_transaction' => 'Need at least one transaction.',
|
||||
'recurring_transaction_id' => 'Need at least one transaction.',
|
||||
'need_id_to_match' => 'You need to submit this entry with an ID for the API to be able to match it.',
|
||||
|
Reference in New Issue
Block a user