mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-27 05:31:27 +00:00
Compare commits
31 Commits
develop-20
...
develop-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03be2704ce | ||
|
|
0638d109d0 | ||
|
|
cb5d856769 | ||
|
|
04fe5d1fc4 | ||
|
|
45e9d4f8de | ||
|
|
73fdbb6202 | ||
|
|
e49dbefddd | ||
|
|
fc5143337a | ||
|
|
4b3eb6dace | ||
|
|
c741b2a819 | ||
|
|
cebfaa32bf | ||
|
|
d356d39d43 | ||
|
|
7d9f22d3f4 | ||
|
|
c6c8f282e2 | ||
|
|
6a64420721 | ||
|
|
fcde4e2488 | ||
|
|
aa5c4c20e9 | ||
|
|
794e31e487 | ||
|
|
16bf186312 | ||
|
|
45c722e786 | ||
|
|
36d9e5c3fe | ||
|
|
8d614de67f | ||
|
|
d17da670ab | ||
|
|
5bf4df9ad8 | ||
|
|
07db6b59ce | ||
|
|
e16f1cf4ee | ||
|
|
4c80d929ca | ||
|
|
16364d9859 | ||
|
|
c24f6acb2c | ||
|
|
4bd19e0627 | ||
|
|
69d839997a |
881
.ci/php-cs-fixer/composer.lock
generated
881
.ci/php-cs-fixer/composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -28,10 +28,11 @@ use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountBalance;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
@@ -39,11 +40,13 @@ use Illuminate\Http\JsonResponse;
|
||||
*/
|
||||
class AccountController extends Controller
|
||||
{
|
||||
use AccountFilter;
|
||||
|
||||
// use AccountFilter;
|
||||
private AdminAccountRepositoryInterface $adminRepository;
|
||||
private array $balanceTypes;
|
||||
private AccountRepositoryInterface $repository;
|
||||
private TransactionCurrency $default;
|
||||
private ExchangeRateConverter $converter;
|
||||
|
||||
// private array $balanceTypes;
|
||||
// private AccountRepositoryInterface $repository;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
@@ -53,14 +56,20 @@ class AccountController extends Controller
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
// new way of user group validation
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
$this->adminRepository = app(AdminAccountRepositoryInterface::class);
|
||||
$this->adminRepository->setUserGroup($this->validateUserGroup($request));
|
||||
$this->adminRepository->setUserGroup($userGroup);
|
||||
$this->default = app('amount')->getDefaultCurrency();
|
||||
$this->converter = app(ExchangeRateConverter::class);
|
||||
|
||||
// $this->repository = app(AccountRepositoryInterface::class);
|
||||
// $this->adminRepository->setUserGroup($this->validateUserGroup($request));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
$this->balanceTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
|
||||
// $this->balanceTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,59 +82,68 @@ class AccountController extends Controller
|
||||
* 5. Collector uses user_group_id
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function accounts(AutocompleteRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->getData();
|
||||
$types = $data['types'];
|
||||
$query = $data['query'];
|
||||
$date = $this->parameters->get('date') ?? today(config('app.timezone'));
|
||||
$result = $this->adminRepository->searchAccount((string) $query, $types, $data['limit']);
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$groupedResult = [];
|
||||
$allItems = [];
|
||||
$queryParameters = $request->getParameters();
|
||||
$result = $this->adminRepository->searchAccount((string) $queryParameters['query'], $queryParameters['account_types'], $queryParameters['size']);
|
||||
$return = [];
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($result as $account) {
|
||||
$nameWithBalance = $account->name;
|
||||
$currency = $this->repository->getAccountCurrency($account) ?? $defaultCurrency;
|
||||
|
||||
if (in_array($account->accountType->type, $this->balanceTypes, true)) {
|
||||
$balance = app('steam')->balance($account, $date);
|
||||
$nameWithBalance = sprintf('%s (%s)', $account->name, app('amount')->formatAnything($currency, $balance, false));
|
||||
}
|
||||
$type = (string) trans(sprintf('firefly.%s', $account->accountType->type));
|
||||
$groupedResult[$type] ??= [
|
||||
'group ' => $type,
|
||||
'items' => [],
|
||||
];
|
||||
$allItems[] = [
|
||||
'id' => (string) $account->id,
|
||||
'value' => (string) $account->id,
|
||||
'name' => $account->name,
|
||||
'name_with_balance' => $nameWithBalance,
|
||||
'label' => $nameWithBalance,
|
||||
'type' => $account->accountType->type,
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_name' => $currency->name,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
];
|
||||
$return[] = $this->parseAccount($account);
|
||||
}
|
||||
|
||||
usort(
|
||||
$allItems,
|
||||
static function (array $left, array $right): int {
|
||||
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
|
||||
$posLeft = (int) array_search($left['type'], $order, true);
|
||||
$posRight = (int) array_search($right['type'], $order, true);
|
||||
return response()->json($return);
|
||||
}
|
||||
|
||||
return $posLeft - $posRight;
|
||||
}
|
||||
);
|
||||
private function parseAccount(Account $account): array
|
||||
{
|
||||
$currency = $this->adminRepository->getAccountCurrency($account);
|
||||
|
||||
return response()->json($allItems);
|
||||
return [
|
||||
'id' => (string) $account->id,
|
||||
'title' => $account->name,
|
||||
'meta' => [
|
||||
'type' => $account->accountType->type,
|
||||
'currency_id' => null === $currency ? null : (string) $currency->id,
|
||||
'currency_code' => $currency?->code,
|
||||
'currency_symbol' => $currency?->symbol,
|
||||
'currency_decimal' => $currency?->decimal_places,
|
||||
'account_balances' => $this->getAccountBalances($account),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function getAccountBalances(Account $account): array
|
||||
{
|
||||
$return = [];
|
||||
$balances = $this->adminRepository->getAccountBalances($account);
|
||||
|
||||
/** @var AccountBalance $balance */
|
||||
foreach ($balances as $balance) {
|
||||
$return[] = $this->parseAccountBalance($balance);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
private function parseAccountBalance(AccountBalance $balance): array
|
||||
{
|
||||
$currency = $balance->transactionCurrency;
|
||||
|
||||
return [
|
||||
'title' => $balance->title,
|
||||
'native_amount' => $this->converter->convert($currency, $this->default, today(), $balance->balance),
|
||||
'amount' => app('steam')->bcround($balance->balance, $currency->decimal_places),
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'native_currency_id' => (string) $this->default->id,
|
||||
'native_currency_code' => $this->default->code,
|
||||
'native_currency_symbol' => $this->default->symbol,
|
||||
'native_currency_decimal' => $this->default->decimal_places,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Transformers\V2\AccountTransformer;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
@@ -63,17 +64,28 @@ class IndexController extends Controller
|
||||
public function index(IndexRequest $request): JsonResponse
|
||||
{
|
||||
$this->repository->resetAccountOrder();
|
||||
$types = $request->getAccountTypes();
|
||||
$sorting = $request->getSortInstructions('accounts');
|
||||
$filters = $request->getFilterInstructions('accounts');
|
||||
$accounts = $this->repository->getAccountsByType($types, $sorting, $filters);
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$count = $accounts->count();
|
||||
$accounts = $accounts->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
|
||||
$transformer = new AccountTransformer();
|
||||
$types = $request->getAccountTypes();
|
||||
$sorting = $request->getSortInstructions('accounts');
|
||||
$filters = $request->getFilterInstructions('accounts');
|
||||
$accounts = $this->repository->getAccountsByType($types, $sorting, $filters);
|
||||
$pageSize = $this->parameters->get('limit');
|
||||
$count = $accounts->count();
|
||||
|
||||
// depending on the sort parameters, this list must not be split, because the
|
||||
// order is calculated in the account transformer and by that time it's too late.
|
||||
$first = array_key_first($sorting);
|
||||
$disablePagination = in_array($first, ['last_activity', 'balance', 'balance_difference'], true);
|
||||
Log::debug(sprintf('Will disable pagination in account index v2? %s', var_export($disablePagination, true)));
|
||||
if (!$disablePagination) {
|
||||
$accounts = $accounts->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||
}
|
||||
$paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
|
||||
$transformer = new AccountTransformer();
|
||||
|
||||
$this->parameters->set('disablePagination', $disablePagination);
|
||||
$this->parameters->set('pageSize', $pageSize);
|
||||
$this->parameters->set('sort', $sorting);
|
||||
|
||||
$this->parameters->set('filters', $filters);
|
||||
$transformer->setParameters($this->parameters); // give params to transformer
|
||||
|
||||
|
||||
@@ -23,24 +23,59 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V2\Request\Autocomplete;
|
||||
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\Exceptions\InvalidFormatException;
|
||||
use FireflyIII\JsonApi\Rules\IsValidFilter;
|
||||
use FireflyIII\JsonApi\Rules\IsValidPage;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use LaravelJsonApi\Core\Query\QueryParameters;
|
||||
use LaravelJsonApi\Validation\Rule as JsonApiRule;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class AutocompleteRequest
|
||||
*/
|
||||
class AutocompleteRequest extends FormRequest
|
||||
{
|
||||
use AccountFilter;
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
|
||||
protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS];
|
||||
/**
|
||||
* Loops over all possible query parameters (these are shared over ALL auto complete requests)
|
||||
* and returns a validated array of parameters.
|
||||
*
|
||||
* The advantage is a single class. But you may also submit "account types" to an endpoint that doesn't use these.
|
||||
*/
|
||||
public function getParameters(): array
|
||||
{
|
||||
$queryParameters = QueryParameters::cast($this->all());
|
||||
|
||||
try {
|
||||
$date = Carbon::createFromFormat('Y-m-d', $queryParameters->filter()?->value('date', date('Y-m-d')), config('app.timezone'));
|
||||
} catch (InvalidFormatException $e) {
|
||||
Log::debug(sprintf('Invalid date format in autocomplete request. Using today: %s', $e->getMessage()));
|
||||
$date = today();
|
||||
}
|
||||
$query = $queryParameters->filter()?->value('query', '') ?? '';
|
||||
$size = (int) ($queryParameters->page()['size'] ?? 50);
|
||||
$accountTypes = $this->getAccountTypeParameter($queryParameters->filter()?->value('account_types', '') ?? '');
|
||||
|
||||
return [
|
||||
'date' => $date,
|
||||
'query' => $query,
|
||||
'size' => $size,
|
||||
'account_types' => $accountTypes,
|
||||
];
|
||||
}
|
||||
|
||||
public function getData(): array
|
||||
{
|
||||
return [];
|
||||
$types = $this->convertString('types');
|
||||
$array = [];
|
||||
if ('' !== $types) {
|
||||
@@ -63,7 +98,27 @@ class AutocompleteRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'limit' => 'min:0|max:1337',
|
||||
'fields' => JsonApiRule::notSupported(),
|
||||
'filter' => ['nullable', 'array', new IsValidFilter(['query', 'date', 'account_types'])],
|
||||
'include' => JsonApiRule::notSupported(),
|
||||
'page' => ['nullable', 'array', new IsValidPage(['size'])],
|
||||
'sort' => JsonApiRule::notSupported(),
|
||||
];
|
||||
}
|
||||
|
||||
private function getAccountTypeParameter(mixed $types): array
|
||||
{
|
||||
if (is_string($types) && str_contains($types, ',')) {
|
||||
$types = explode(',', $types);
|
||||
}
|
||||
if (!is_iterable($types)) {
|
||||
$types = [$types];
|
||||
}
|
||||
$return = [];
|
||||
foreach ($types as $type) {
|
||||
$return = array_merge($return, $this->mapAccountTypes($type));
|
||||
}
|
||||
|
||||
return array_unique($return);
|
||||
}
|
||||
}
|
||||
|
||||
32
app/Console/Commands/Correction/CorrectAccountBalance.php
Normal file
32
app/Console/Commands/Correction/CorrectAccountBalance.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Support\Models\AccountBalanceCalculator;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class CorrectionSkeleton
|
||||
*/
|
||||
class CorrectAccountBalance extends Command
|
||||
{
|
||||
use ShowsFriendlyMessages;
|
||||
protected $description = 'Recalculate all account balance amounts';
|
||||
|
||||
protected $signature = 'firefly-iii:correct-account-balance';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$this->correctBalanceAmounts();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function correctBalanceAmounts(): void
|
||||
{
|
||||
AccountBalanceCalculator::recalculate(null, null);
|
||||
}
|
||||
}
|
||||
@@ -74,6 +74,7 @@ class CorrectDatabase extends Command
|
||||
'firefly-iii:unify-group-accounts',
|
||||
'firefly-iii:trigger-credit-recalculation',
|
||||
'firefly-iii:migrate-preferences',
|
||||
'firefly-iii:correct-account-balance',
|
||||
];
|
||||
foreach ($commands as $command) {
|
||||
$this->friendlyLine(sprintf('Now executing command "%s"', $command));
|
||||
|
||||
49
app/Entities/AccountBalance.php
Normal file
49
app/Entities/AccountBalance.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/*
|
||||
* AccountBalance.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\Entities;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
class AccountBalance
|
||||
{
|
||||
public string $id;
|
||||
public string $amount;
|
||||
public string $currencyId;
|
||||
|
||||
public static function fromArray(): self
|
||||
{
|
||||
$balance = new self();
|
||||
$balance->id = (string) random_int(1, 1000);
|
||||
$balance->name = (string) random_int(1, 1000);
|
||||
$balance->amount = (string) random_int(1, 1000);
|
||||
$balance->currencyId = '1';
|
||||
|
||||
return $balance;
|
||||
}
|
||||
|
||||
public function getAccount(): Account
|
||||
{
|
||||
return Account::inRandomOrder()->first();
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ use Illuminate\Session\TokenMismatchException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Validation\ValidationException as LaravelValidationException;
|
||||
use Laravel\Passport\Exceptions\OAuthServerException as LaravelOAuthException;
|
||||
use LaravelJsonApi\Core\Exceptions\JsonApiException;
|
||||
use League\OAuth2\Server\Exception\OAuthServerException;
|
||||
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -63,6 +64,7 @@ class Handler extends ExceptionHandler
|
||||
HttpException::class,
|
||||
SuspiciousOperationException::class,
|
||||
BadHttpHeaderException::class,
|
||||
JsonApiException::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Handlers\Observer;
|
||||
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Support\Models\AccountBalanceCalculator;
|
||||
|
||||
/**
|
||||
* Class TransactionObserver
|
||||
@@ -35,4 +36,16 @@ class TransactionObserver
|
||||
app('log')->debug('Observe "deleting" of a transaction.');
|
||||
$transaction?->transactionJournal?->delete();
|
||||
}
|
||||
|
||||
public function updated(Transaction $transaction): void
|
||||
{
|
||||
app('log')->debug('Observe "updated" of a transaction.');
|
||||
AccountBalanceCalculator::recalculateForAccount($transaction->account);
|
||||
}
|
||||
|
||||
public function created(Transaction $transaction): void
|
||||
{
|
||||
app('log')->debug('Observe "created" of a transaction.');
|
||||
AccountBalanceCalculator::recalculateForAccount($transaction->account);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Api\V3\Controllers;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\JsonApi\V3\AccountBalances\AccountBalanceSchema;
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Contracts\Support\Responsable;
|
||||
use LaravelJsonApi\Core\Facades\JsonApi;
|
||||
use LaravelJsonApi\Core\Responses\DataResponse;
|
||||
use LaravelJsonApi\Laravel\Http\Controllers\Actions;
|
||||
use LaravelJsonApi\Laravel\Http\Requests\AnonymousQuery;
|
||||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
use Actions\AttachRelationship;
|
||||
use Actions\Destroy;
|
||||
use Actions\DetachRelationship;
|
||||
use Actions\FetchMany;
|
||||
use Actions\FetchOne;
|
||||
use Actions\FetchRelated;
|
||||
use Actions\FetchRelationship;
|
||||
use Actions\Store;
|
||||
use Actions\Update;
|
||||
use Actions\UpdateRelationship;
|
||||
|
||||
public function readAccountBalances(AnonymousQuery $query, AccountBalanceSchema $schema, Account $account): Responsable
|
||||
{
|
||||
$schema = JsonApi::server()->schemas()->schemaFor('account-balances');
|
||||
|
||||
$models = $schema
|
||||
->repository()
|
||||
->queryAll()
|
||||
->withRequest($query)
|
||||
->withAccount($account)
|
||||
->get()
|
||||
;
|
||||
|
||||
return DataResponse::make($models);
|
||||
}
|
||||
}
|
||||
@@ -86,14 +86,15 @@ class DebugController extends Controller
|
||||
{
|
||||
app('preferences')->mark();
|
||||
$request->session()->forget(['start', 'end', '_previous', 'viewRange', 'range', 'is_custom_range', 'temp-mfa-secret', 'temp-mfa-codes']);
|
||||
app('log')->debug('Call cache:clear...');
|
||||
|
||||
Artisan::call('cache:clear');
|
||||
app('log')->debug('Call config:clear...');
|
||||
Artisan::call('config:clear');
|
||||
app('log')->debug('Call route:clear...');
|
||||
Artisan::call('route:clear');
|
||||
app('log')->debug('Call twig:clean...');
|
||||
Artisan::call('view:clear');
|
||||
|
||||
// also do some recalculations.
|
||||
Artisan::call('firefly-iii:correct-account-balance');
|
||||
Artisan::call('firefly-iii:trigger-credit-recalculation');
|
||||
|
||||
try {
|
||||
Artisan::call('twig:clean');
|
||||
@@ -101,7 +102,6 @@ class DebugController extends Controller
|
||||
throw new FireflyException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
app('log')->debug('Call view:clear...');
|
||||
Artisan::call('view:clear');
|
||||
|
||||
return redirect(route('index'));
|
||||
|
||||
@@ -29,6 +29,7 @@ use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use Illuminate\Bus\Queueable;
|
||||
@@ -100,7 +101,7 @@ class DownloadExchangeRates implements ShouldQueue
|
||||
|
||||
try {
|
||||
$res = $client->get($url);
|
||||
} catch (RequestException $e) {
|
||||
} catch (ConnectException|RequestException $e) {
|
||||
app('log')->warning(sprintf('Trying to grab "%s" resulted in error "%d".', $url, $e->getMessage()));
|
||||
|
||||
return;
|
||||
|
||||
52
app/JsonApi/Rules/IsValidFilter.php
Normal file
52
app/JsonApi/Rules/IsValidFilter.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/*
|
||||
* IsValidFilter.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\JsonApi\Rules;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
|
||||
class IsValidFilter implements ValidationRule
|
||||
{
|
||||
private array $allowed;
|
||||
|
||||
public function __construct(array $keys)
|
||||
{
|
||||
$this->allowed = $keys;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
||||
{
|
||||
if ('filter' !== $attribute) {
|
||||
$fail('validation.bad_api_filter')->translate();
|
||||
}
|
||||
if (!is_array($value)) {
|
||||
$value = explode(',', $value);
|
||||
}
|
||||
foreach ($value as $key => $val) {
|
||||
if (!in_array($key, $this->allowed, true)) {
|
||||
$fail('validation.bad_api_filter')->translate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
52
app/JsonApi/Rules/IsValidPage.php
Normal file
52
app/JsonApi/Rules/IsValidPage.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/*
|
||||
* IsValidFilter.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\JsonApi\Rules;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
|
||||
class IsValidPage implements ValidationRule
|
||||
{
|
||||
private array $allowed;
|
||||
|
||||
public function __construct(array $keys)
|
||||
{
|
||||
$this->allowed = $keys;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
||||
{
|
||||
if ('page' !== $attribute) {
|
||||
$fail('validation.bad_api_filter')->translate();
|
||||
}
|
||||
if (!is_array($value)) {
|
||||
$value = explode(',', $value);
|
||||
}
|
||||
foreach ($value as $key => $val) {
|
||||
if (!in_array($key, $this->allowed, true)) {
|
||||
$fail('validation.bad_api_page')->translate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
45
app/JsonApi/V3/AccountBalances/AccountBalanceRepository.php
Normal file
45
app/JsonApi/V3/AccountBalances/AccountBalanceRepository.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/*
|
||||
* AccountBalanceRepository.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\JsonApi\V3\AccountBalances;
|
||||
|
||||
use FireflyIII\Entities\AccountBalance;
|
||||
use LaravelJsonApi\Contracts\Store\QueriesAll;
|
||||
use LaravelJsonApi\NonEloquent\AbstractRepository;
|
||||
|
||||
class AccountBalanceRepository extends AbstractRepository implements QueriesAll
|
||||
{
|
||||
#[\Override]
|
||||
public function find(string $resourceId): ?object
|
||||
{
|
||||
return AccountBalance::fromArray();
|
||||
}
|
||||
|
||||
public function queryAll(): Capabilities\AccountBalanceQuery
|
||||
{
|
||||
return Capabilities\AccountBalanceQuery::make()
|
||||
->withServer($this->server)
|
||||
->withSchema($this->schema)
|
||||
;
|
||||
}
|
||||
}
|
||||
44
app/JsonApi/V3/AccountBalances/AccountBalanceResource.php
Normal file
44
app/JsonApi/V3/AccountBalances/AccountBalanceResource.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\JsonApi\V3\AccountBalances;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use LaravelJsonApi\Core\Resources\JsonApiResource;
|
||||
|
||||
class AccountBalanceResource extends JsonApiResource
|
||||
{
|
||||
/**
|
||||
* Get the resource id.
|
||||
*/
|
||||
public function id(): string
|
||||
{
|
||||
return $this->resource->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource's attributes.
|
||||
*
|
||||
* @param null|Request $request
|
||||
*/
|
||||
public function attributes($request): iterable
|
||||
{
|
||||
return [
|
||||
'name' => $this->resource->amount,
|
||||
'amount' => $this->resource->amount,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource's relationships.
|
||||
*
|
||||
* @param null|Request $request
|
||||
*/
|
||||
public function relationships($request): iterable
|
||||
{
|
||||
return [
|
||||
$this->relation('account')->withData($this->resource->getAccount()),
|
||||
];
|
||||
}
|
||||
}
|
||||
50
app/JsonApi/V3/AccountBalances/AccountBalanceSchema.php
Normal file
50
app/JsonApi/V3/AccountBalances/AccountBalanceSchema.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\JsonApi\V3\AccountBalances;
|
||||
|
||||
use FireflyIII\Entities\AccountBalance;
|
||||
use LaravelJsonApi\Core\Schema\Schema;
|
||||
use LaravelJsonApi\Eloquent\Fields\Relations\HasOne;
|
||||
use LaravelJsonApi\NonEloquent\Fields\Attribute;
|
||||
use LaravelJsonApi\NonEloquent\Fields\ID;
|
||||
|
||||
class AccountBalanceSchema extends Schema
|
||||
{
|
||||
/**
|
||||
* The model the schema corresponds to.
|
||||
*/
|
||||
public static string $model = AccountBalance::class;
|
||||
|
||||
/**
|
||||
* Get the resource fields.
|
||||
*/
|
||||
public function fields(): array
|
||||
{
|
||||
return [
|
||||
ID::make(),
|
||||
Attribute::make('name'),
|
||||
Attribute::make('amount'),
|
||||
HasOne::make('account'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource filters.
|
||||
*/
|
||||
public function filters(): array
|
||||
{
|
||||
return [
|
||||
// Filter::make('id'),
|
||||
];
|
||||
}
|
||||
|
||||
public function repository(): AccountBalanceRepository
|
||||
{
|
||||
return AccountBalanceRepository::make()
|
||||
->withServer($this->server)
|
||||
->withSchema($this)
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/*
|
||||
* AccountBalanceQuery.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\JsonApi\V3\AccountBalances\Capabilities;
|
||||
|
||||
use FireflyIII\Entities\AccountBalance;
|
||||
use FireflyIII\Models\Account;
|
||||
use LaravelJsonApi\NonEloquent\Capabilities\QueryAll;
|
||||
|
||||
class AccountBalanceQuery extends QueryAll
|
||||
{
|
||||
private Account $account;
|
||||
|
||||
/**
|
||||
* QuerySites constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function get(): iterable
|
||||
{
|
||||
return [
|
||||
AccountBalance::fromArray(),
|
||||
AccountBalance::fromArray(),
|
||||
AccountBalance::fromArray(),
|
||||
AccountBalance::fromArray(),
|
||||
];
|
||||
}
|
||||
|
||||
public function withAccount(Account $account): self
|
||||
{
|
||||
$this->account = $account;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
53
app/JsonApi/V3/Accounts/AccountRepository.php
Normal file
53
app/JsonApi/V3/Accounts/AccountRepository.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/*
|
||||
* AccountRepository.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\JsonApi\V3\Accounts;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Support\JsonApi\Concerns\UsergroupAware;
|
||||
use LaravelJsonApi\Contracts\Store\QueriesAll;
|
||||
use LaravelJsonApi\NonEloquent\AbstractRepository;
|
||||
|
||||
class AccountRepository extends AbstractRepository implements QueriesAll
|
||||
{
|
||||
use UsergroupAware;
|
||||
|
||||
/**
|
||||
* SiteRepository constructor.
|
||||
*/
|
||||
public function __construct() {}
|
||||
|
||||
public function find(string $resourceId): ?object
|
||||
{
|
||||
return Account::find((int) $resourceId);
|
||||
}
|
||||
|
||||
public function queryAll(): Capabilities\AccountQuery
|
||||
{
|
||||
return Capabilities\AccountQuery::make()
|
||||
->withUserGroup($this->userGroup)
|
||||
->withServer($this->server)
|
||||
->withSchema($this->schema)
|
||||
;
|
||||
}
|
||||
}
|
||||
129
app/JsonApi/V3/Accounts/AccountResource.php
Normal file
129
app/JsonApi/V3/Accounts/AccountResource.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\JsonApi\V3\Accounts;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Http\Request;
|
||||
use LaravelJsonApi\Core\Resources\JsonApiResource;
|
||||
|
||||
/**
|
||||
* @property Account $resource
|
||||
*/
|
||||
class AccountResource extends JsonApiResource
|
||||
{
|
||||
/**
|
||||
* Get the resource's attributes.
|
||||
*
|
||||
* @param null|Request $request
|
||||
*/
|
||||
public function attributes($request): iterable
|
||||
{
|
||||
return [
|
||||
'created_at' => $this->resource->created_at,
|
||||
'updated_at' => $this->resource->updated_at,
|
||||
'name' => $this->resource->name,
|
||||
'iban' => '' === $this->resource->iban ? null : $this->resource->iban,
|
||||
'active' => $this->resource->active,
|
||||
'last_activity' => $this->resource->last_activity,
|
||||
'type' => $this->resource->type,
|
||||
'account_role' => $this->resource->account_role,
|
||||
|
||||
// 'virtual_balance' => $this->resource->virtual_balance,
|
||||
// 'native_balance' => $this->resource->native_balance,
|
||||
// 'user' => $this->resource->user_array,
|
||||
// 'balances' => []
|
||||
//
|
||||
// currency
|
||||
// 'currency_id' => $this->resource->currency_id,
|
||||
// 'currency_code' => $this->resource->currency_code,
|
||||
// 'currency_symbol' => $this->resource->currency_symbol,
|
||||
// 'currency_decimal_places' => $this->resource->currency_decimal_places,
|
||||
|
||||
// balance (in currency, on date)
|
||||
// 'current_balance' => $this->resource->current_balance,
|
||||
|
||||
// 'current_balance' => app('steam')->bcround(app('steam')->balance($account, $date), $decimalPlaces),
|
||||
// 'current_balance_date' => $date->toAtomString(),
|
||||
// 'notes' => $this->repository->getNoteText($account),
|
||||
// 'monthly_payment_date' => $monthlyPaymentDate,
|
||||
// 'credit_card_type' => $creditCardType,
|
||||
// 'account_number' => $this->repository->getMetaValue($account, 'account_number'),
|
||||
// 'bic' => $this->repository->getMetaValue($account, 'BIC'),
|
||||
// 'opening_balance' => $openingBalance,
|
||||
// 'opening_balance_date' => $openingBalanceDate,
|
||||
// 'liability_type' => $liabilityType,
|
||||
// 'liability_direction' => $liabilityDirection,
|
||||
// 'interest' => $interest,
|
||||
// 'interest_period' => $interestPeriod,
|
||||
// 'current_debt' => $this->repository->getMetaValue($account, 'current_debt'),
|
||||
// 'include_net_worth' => $includeNetWorth,
|
||||
// 'longitude' => $longitude,
|
||||
// 'latitude' => $latitude,
|
||||
// 'zoom_level' => $zoomLevel,
|
||||
|
||||
// 'order' => $order,
|
||||
|
||||
// 'currency_id' => (string) $currency->id,
|
||||
// 'currency_code' => $currency->code,
|
||||
// 'currency_symbol' => $currency->symbol,
|
||||
// 'currency_decimal_places' => $currency->decimal_places,
|
||||
//
|
||||
// 'native_currency_id' => (string) $this->default->id,
|
||||
// 'native_currency_code' => $this->default->code,
|
||||
// 'native_currency_symbol' => $this->default->symbol,
|
||||
// 'native_currency_decimal_places' => $this->default->decimal_places,
|
||||
//
|
||||
// // balance:
|
||||
// 'current_balance' => $balance,
|
||||
// 'native_current_balance' => $nativeBalance,
|
||||
// 'current_balance_date' => $this->getDate()->endOfDay()->toAtomString(),
|
||||
//
|
||||
// // balance difference
|
||||
// 'balance_difference' => $balanceDiff,
|
||||
// 'native_balance_difference' => $nativeBalanceDiff,
|
||||
// 'balance_difference_start' => $diffStart,
|
||||
// 'balance_difference_end' => $diffEnd,
|
||||
//
|
||||
// // more meta
|
||||
// 'last_activity' => array_key_exists($id, $this->lastActivity) ? $this->lastActivity[$id]->toAtomString() : null,
|
||||
//
|
||||
// // liability stuff
|
||||
// 'liability_type' => $liabilityType,
|
||||
// 'liability_direction' => $liabilityDirection,
|
||||
// 'interest' => $interest,
|
||||
// 'interest_period' => $interestPeriod,
|
||||
// 'current_debt' => $currentDebt,
|
||||
//
|
||||
// // object group
|
||||
// 'object_group_id' => null !== $objectGroupId ? (string) $objectGroupId : null,
|
||||
// 'object_group_order' => $objectGroupOrder,
|
||||
// 'object_group_title' => $objectGroupTitle,
|
||||
// 'notes' => $this->repository->getNoteText($account),
|
||||
// 'monthly_payment_date' => $monthlyPaymentDate,
|
||||
// 'credit_card_type' => $creditCardType,
|
||||
// 'bic' => $this->repository->getMetaValue($account, 'BIC'),
|
||||
// 'virtual_balance' => number_format((float) $account->virtual_balance, $decimalPlaces, '.', ''),
|
||||
// 'opening_balance' => $openingBalance,
|
||||
// 'opening_balance_date' => $openingBalanceDate,
|
||||
// 'include_net_worth' => $includeNetWorth,
|
||||
// 'longitude' => $longitude,
|
||||
// 'latitude' => $latitude,
|
||||
// 'zoom_level' => $zoomLevel,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource's relationships.
|
||||
*
|
||||
* @param null|Request $request
|
||||
*/
|
||||
public function relationships($request): iterable
|
||||
{
|
||||
return [
|
||||
$this->relation('user')->withData($this->resource->user),
|
||||
$this->relation('account_balances')->withData($this->resource->balances),
|
||||
];
|
||||
}
|
||||
}
|
||||
64
app/JsonApi/V3/Accounts/AccountSchema.php
Normal file
64
app/JsonApi/V3/Accounts/AccountSchema.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\JsonApi\V3\Accounts;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use LaravelJsonApi\Eloquent\Contracts\Paginator;
|
||||
use LaravelJsonApi\Eloquent\Fields\Boolean;
|
||||
use LaravelJsonApi\Eloquent\Fields\DateTime;
|
||||
use LaravelJsonApi\Eloquent\Fields\ID;
|
||||
use LaravelJsonApi\Eloquent\Fields\Number;
|
||||
use LaravelJsonApi\Eloquent\Fields\Relations\HasMany;
|
||||
use LaravelJsonApi\Eloquent\Fields\Relations\HasOne;
|
||||
use LaravelJsonApi\Eloquent\Fields\Str;
|
||||
use LaravelJsonApi\Eloquent\Filters\WhereIdIn;
|
||||
use LaravelJsonApi\Eloquent\Pagination\PagePagination;
|
||||
use LaravelJsonApi\Eloquent\Schema;
|
||||
|
||||
class AccountSchema extends Schema
|
||||
{
|
||||
/**
|
||||
* The model the schema corresponds to.
|
||||
*/
|
||||
public static string $model = Account::class;
|
||||
|
||||
/**
|
||||
* Get the resource fields.
|
||||
*/
|
||||
public function fields(): array
|
||||
{
|
||||
return [
|
||||
ID::make(),
|
||||
DateTime::make('created_at')->sortable()->readOnly(),
|
||||
DateTime::make('updated_at')->sortable()->readOnly(),
|
||||
Str::make('name')->sortable(),
|
||||
Str::make('account_type'),
|
||||
Str::make('virtual_balance'),
|
||||
Str::make('iban'),
|
||||
Boolean::make('active'),
|
||||
Number::make('order'),
|
||||
HasOne::make('user'),
|
||||
HasMany::make('account_balances'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource filters.
|
||||
*/
|
||||
public function filters(): array
|
||||
{
|
||||
return [
|
||||
WhereIdIn::make($this),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource paginator.
|
||||
*/
|
||||
public function pagination(): ?Paginator
|
||||
{
|
||||
return PagePagination::make();
|
||||
}
|
||||
}
|
||||
73
app/JsonApi/V3/Accounts/Capabilities/AccountQuery.php
Normal file
73
app/JsonApi/V3/Accounts/Capabilities/AccountQuery.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/*
|
||||
* AccountQuery.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\JsonApi\V3\Accounts\Capabilities;
|
||||
|
||||
use FireflyIII\Support\JsonApi\Concerns\UsergroupAware;
|
||||
use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment;
|
||||
use FireflyIII\Support\JsonApi\ExpandsQuery;
|
||||
use FireflyIII\Support\JsonApi\FiltersPagination;
|
||||
use FireflyIII\Support\JsonApi\SortsCollection;
|
||||
use FireflyIII\Support\JsonApi\ValidateSortParameters;
|
||||
use LaravelJsonApi\Contracts\Store\HasPagination;
|
||||
use LaravelJsonApi\NonEloquent\Capabilities\QueryAll;
|
||||
use LaravelJsonApi\NonEloquent\Concerns\PaginatesEnumerables;
|
||||
|
||||
class AccountQuery extends QueryAll implements HasPagination
|
||||
{
|
||||
use ExpandsQuery;
|
||||
use FiltersPagination;
|
||||
use PaginatesEnumerables;
|
||||
use SortsCollection;
|
||||
use UsergroupAware;
|
||||
use ValidateSortParameters;
|
||||
|
||||
#[\Override]
|
||||
public function get(): iterable
|
||||
{
|
||||
$filters = $this->queryParameters->filter();
|
||||
$sort = $this->queryParameters->sortFields();
|
||||
$pagination = $this->filtersPagination($this->queryParameters->page());
|
||||
$needsAll = $this->validateParams('account', $sort);
|
||||
$query = $this->userGroup->accounts();
|
||||
|
||||
if (!$needsAll) {
|
||||
$query = $this->addPagination($query, $pagination);
|
||||
}
|
||||
$query = $this->addSortParams($query, $sort);
|
||||
$query = $this->addFilterParams('account', $query, $filters);
|
||||
|
||||
$collection = $query->get(['accounts.*']);
|
||||
|
||||
// enrich data
|
||||
$enrichment = new AccountEnrichment();
|
||||
$collection = $enrichment->enrich($collection);
|
||||
|
||||
// add filters after the query
|
||||
|
||||
// add sort after the query
|
||||
return $this->sortCollection($collection, $sort);
|
||||
// var_dump($filters->value('name'));
|
||||
// exit;
|
||||
}
|
||||
}
|
||||
38
app/JsonApi/V3/Server.php
Normal file
38
app/JsonApi/V3/Server.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\JsonApi\V3;
|
||||
|
||||
use FireflyIII\JsonApi\V3\Accounts\AccountSchema;
|
||||
use FireflyIII\JsonApi\V3\AccountBalances\AccountBalanceSchema;
|
||||
use FireflyIII\JsonApi\V3\Users\UserSchema;
|
||||
use LaravelJsonApi\Core\Server\Server as BaseServer;
|
||||
|
||||
class Server extends BaseServer
|
||||
{
|
||||
/**
|
||||
* The base URI namespace for this server.
|
||||
*/
|
||||
protected string $baseUri = '/api/v3';
|
||||
|
||||
/**
|
||||
* Bootstrap the server when it is handling an HTTP request.
|
||||
*/
|
||||
public function serving(): void
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the server's list of schemas.
|
||||
*/
|
||||
protected function allSchemas(): array
|
||||
{
|
||||
return [
|
||||
AccountSchema::class,
|
||||
UserSchema::class,
|
||||
AccountBalanceSchema::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
41
app/JsonApi/V3/Users/UserResource.php
Normal file
41
app/JsonApi/V3/Users/UserResource.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\JsonApi\V3\Users;
|
||||
|
||||
use FireflyIII\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use LaravelJsonApi\Core\Resources\JsonApiResource;
|
||||
|
||||
/**
|
||||
* @property User $resource
|
||||
*/
|
||||
class UserResource extends JsonApiResource
|
||||
{
|
||||
/**
|
||||
* Get the resource's attributes.
|
||||
*
|
||||
* @param null|Request $request
|
||||
*/
|
||||
public function attributes($request): iterable
|
||||
{
|
||||
return [
|
||||
'created_at' => $this->resource->created_at,
|
||||
'updated_at' => $this->resource->updated_at,
|
||||
'email' => $this->resource->email,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource's relationships.
|
||||
*
|
||||
* @param null|Request $request
|
||||
*/
|
||||
public function relationships($request): iterable
|
||||
{
|
||||
return [
|
||||
// @TODO
|
||||
];
|
||||
}
|
||||
}
|
||||
55
app/JsonApi/V3/Users/UserSchema.php
Normal file
55
app/JsonApi/V3/Users/UserSchema.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\JsonApi\V3\Users;
|
||||
|
||||
use FireflyIII\User;
|
||||
use LaravelJsonApi\Eloquent\Contracts\Paginator;
|
||||
use LaravelJsonApi\Eloquent\Fields\DateTime;
|
||||
use LaravelJsonApi\Eloquent\Fields\ID;
|
||||
use LaravelJsonApi\Eloquent\Fields\Relations\HasMany;
|
||||
use LaravelJsonApi\Eloquent\Fields\Str;
|
||||
use LaravelJsonApi\Eloquent\Filters\WhereIdIn;
|
||||
use LaravelJsonApi\Eloquent\Pagination\PagePagination;
|
||||
use LaravelJsonApi\Eloquent\Schema;
|
||||
|
||||
class UserSchema extends Schema
|
||||
{
|
||||
/**
|
||||
* The model the schema corresponds to.
|
||||
*/
|
||||
public static string $model = User::class;
|
||||
|
||||
/**
|
||||
* Get the resource fields.
|
||||
*/
|
||||
public function fields(): array
|
||||
{
|
||||
return [
|
||||
ID::make(),
|
||||
DateTime::make('created_at')->sortable()->readOnly(),
|
||||
DateTime::make('updated_at')->sortable()->readOnly(),
|
||||
Str::make('email'),
|
||||
HasMany::make('accounts'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource filters.
|
||||
*/
|
||||
public function filters(): array
|
||||
{
|
||||
return [
|
||||
WhereIdIn::make($this),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource paginator.
|
||||
*/
|
||||
public function pagination(): ?Paginator
|
||||
{
|
||||
return PagePagination::make();
|
||||
}
|
||||
}
|
||||
@@ -193,6 +193,11 @@ class Account extends Model
|
||||
return $this->hasMany(AccountMeta::class);
|
||||
}
|
||||
|
||||
public function accountBalances(): HasMany
|
||||
{
|
||||
return $this->hasMany(AccountBalance::class);
|
||||
}
|
||||
|
||||
public function getEditNameAttribute(): string
|
||||
{
|
||||
$name = $this->name;
|
||||
|
||||
25
app/Models/AccountBalance.php
Normal file
25
app/Models/AccountBalance.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class AccountBalance extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
protected $fillable = ['account_id', 'title', 'transaction_currency_id', 'balance'];
|
||||
|
||||
public function account(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Account::class);
|
||||
}
|
||||
|
||||
public function transactionCurrency(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(TransactionCurrency::class);
|
||||
}
|
||||
}
|
||||
48
app/Policies/AccountBalancePolicy.php
Normal file
48
app/Policies/AccountBalancePolicy.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/*
|
||||
* AccountPolicy.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\Policies;
|
||||
|
||||
use FireflyIII\Entities\AccountBalance;
|
||||
use FireflyIII\User;
|
||||
|
||||
class AccountBalancePolicy
|
||||
{
|
||||
/**
|
||||
* TODO needs better authentication.
|
||||
*/
|
||||
public function view(User $user, AccountBalance $accountBalance): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Everybody can do this, but selection should limit to user.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public function viewAny(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
67
app/Policies/AccountPolicy.php
Normal file
67
app/Policies/AccountPolicy.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/*
|
||||
* AccountPolicy.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\Policies;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\User;
|
||||
|
||||
class AccountPolicy
|
||||
{
|
||||
/**
|
||||
* TODO needs better authentication.
|
||||
*/
|
||||
public function view(User $user, Account $account): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
return auth()->check() && $user->id === $account->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Everybody can do this, but selection should limit to user.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public function viewAny(): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Everybody can do this, but selection should limit to user.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public function viewUser(User $user, Account $account): bool
|
||||
{
|
||||
return $this->view($user, $account);
|
||||
}
|
||||
|
||||
public function viewAccountBalances(User $user, Account $account): bool
|
||||
{
|
||||
return $this->view($user, $account);
|
||||
}
|
||||
}
|
||||
48
app/Policies/BalancePolicy.php
Normal file
48
app/Policies/BalancePolicy.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/*
|
||||
* BalancePolicy.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\Policies;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\User;
|
||||
|
||||
class BalancePolicy
|
||||
{
|
||||
/**
|
||||
* TODO needs better authentication.
|
||||
*/
|
||||
public function view(User $user, Account $account): bool
|
||||
{
|
||||
return auth()->check() && $user->id === $account->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Everybody can do this, but selection should limit to user.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public function viewAny(): bool
|
||||
{
|
||||
return auth()->check();
|
||||
}
|
||||
}
|
||||
58
app/Policies/UserPolicy.php
Normal file
58
app/Policies/UserPolicy.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/*
|
||||
* UserPolicy.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\Policies;
|
||||
|
||||
use FireflyIII\User;
|
||||
|
||||
class UserPolicy
|
||||
{
|
||||
/**
|
||||
* TODO needs better authentication.
|
||||
*/
|
||||
public function view(User $user, User $user1): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
return auth()->check() && $user->id === $account->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Everybody can do this, but selection should limit to user.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public function viewAny(): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
public function viewAccounts(User $user): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
return auth()->check();
|
||||
}
|
||||
}
|
||||
@@ -302,6 +302,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
;
|
||||
if ('' !== $query) {
|
||||
// split query on spaces just in case:
|
||||
// TODO this will always fail because it searches for AND.
|
||||
$parts = explode(' ', $query);
|
||||
foreach ($parts as $part) {
|
||||
$search = sprintf('%%%s%%', $part);
|
||||
@@ -384,4 +385,10 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function getAccountBalances(Account $account): Collection
|
||||
{
|
||||
return $account->accountBalances;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ interface AccountRepositoryInterface
|
||||
|
||||
public function getAccountCurrency(Account $account): ?TransactionCurrency;
|
||||
|
||||
public function getAccountBalances(Account $account): Collection;
|
||||
|
||||
public function getAccountsById(array $accountIds): Collection;
|
||||
|
||||
public function getAccountsByType(array $types, ?array $sort = [], ?array $filters = []): Collection;
|
||||
|
||||
48
app/Support/JsonApi/Concerns/UsergroupAware.php
Normal file
48
app/Support/JsonApi/Concerns/UsergroupAware.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/*
|
||||
* UsergroupAware.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\Support\JsonApi\Concerns;
|
||||
|
||||
use FireflyIII\Models\UserGroup;
|
||||
|
||||
trait UsergroupAware
|
||||
{
|
||||
protected UserGroup $userGroup;
|
||||
|
||||
public function getUserGroup(): UserGroup
|
||||
{
|
||||
return $this->userGroup;
|
||||
}
|
||||
|
||||
public function setUserGroup(UserGroup $userGroup): void
|
||||
{
|
||||
$this->userGroup = $userGroup;
|
||||
}
|
||||
|
||||
public function withUserGroup(UserGroup $userGroup): self
|
||||
{
|
||||
$this->userGroup = $userGroup;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
149
app/Support/JsonApi/Enrichments/AccountEnrichment.php
Normal file
149
app/Support/JsonApi/Enrichments/AccountEnrichment.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/*
|
||||
* AccountEnricher.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\Support\JsonApi\Enrichments;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class AccountEnrichment implements EnrichmentInterface
|
||||
{
|
||||
private Collection $collection;
|
||||
private array $currencies;
|
||||
|
||||
#[\Override]
|
||||
public function enrich(Collection $collection): Collection
|
||||
{
|
||||
$this->collection = $collection;
|
||||
$this->currencies = [];
|
||||
// do everything here:
|
||||
$this->getLastActivity();
|
||||
// $this->getMetaBalances();
|
||||
$this->collectAccountTypes();
|
||||
$this->collectMetaData();
|
||||
|
||||
$this->collection->transform(function (Account $account) {
|
||||
$account->user_array = ['id' => 1, 'bla bla' => 'bla'];
|
||||
$account->balances = collect([
|
||||
['balance_id' => 1, 'balance' => 5],
|
||||
['balance_id' => 2, 'balance' => 5],
|
||||
['balance_id' => 3, 'balance' => 5],
|
||||
]);
|
||||
|
||||
return $account;
|
||||
});
|
||||
|
||||
return $this->collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO this method refers to a single-use method inside Steam that could be moved here.
|
||||
*/
|
||||
private function getLastActivity(): void
|
||||
{
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$lastActivity = $accountRepository->getLastActivity($this->collection);
|
||||
foreach ($lastActivity as $row) {
|
||||
$this->collection->where('id', $row['account_id'])->first()->last_activity = Carbon::parse($row['date_max'], config('app.timezone'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO this method refers to a single-use method inside Steam that could be moved here.
|
||||
*/
|
||||
private function getMetaBalances(): void
|
||||
{
|
||||
try {
|
||||
$array = app('steam')->balancesByAccountsConverted($this->collection, today());
|
||||
} catch (FireflyException $e) {
|
||||
Log::error(sprintf('Could not load balances: %s', $e->getMessage()));
|
||||
|
||||
return;
|
||||
}
|
||||
foreach ($array as $accountId => $row) {
|
||||
$this->collection->where('id', $accountId)->first()->balance = $row['balance'];
|
||||
$this->collection->where('id', $accountId)->first()->native_balance = $row['native_balance'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO this method refers to a single-use method inside Steam that could be moved here.
|
||||
*/
|
||||
private function collectAccountTypes(): void
|
||||
{
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$accountTypes = $accountRepository->getAccountTypes($this->collection);
|
||||
$types = [];
|
||||
|
||||
/** @var AccountType $row */
|
||||
foreach ($accountTypes as $row) {
|
||||
$types[$row->id] = $row->type;
|
||||
}
|
||||
$this->collection->transform(function (Account $account) use ($types) {
|
||||
$account->type = $types[$account->id];
|
||||
|
||||
return $account;
|
||||
});
|
||||
}
|
||||
|
||||
private function collectMetaData(): void
|
||||
{
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
$metaFields = $accountRepository->getMetaValues($this->collection, ['currency_id', 'account_role', 'account_number', 'liability_direction', 'interest', 'interest_period', 'current_debt']);
|
||||
$currencyIds = $metaFields->where('name', 'currency_id')->pluck('data')->toArray();
|
||||
|
||||
$currencies = [];
|
||||
foreach ($repository->getByIds($currencyIds) as $currency) {
|
||||
$id = $currency->id;
|
||||
$currencies[$id] = $currency;
|
||||
}
|
||||
|
||||
$this->collection->transform(function (Account $account) use ($metaFields, $currencies) {
|
||||
$set = $metaFields->where('account_id', $account->id);
|
||||
foreach ($set as $entry) {
|
||||
$account->{$entry->name} = $entry->data;
|
||||
if ('currency_id' === $entry->name) {
|
||||
$id = (int) $entry->data;
|
||||
$account->currency_code = $currencies[$id]?->code;
|
||||
$account->currency_symbol = $currencies[$id]?->symbol;
|
||||
$account->currency_decimal_places = $currencies[$id]?->decimal_places;
|
||||
}
|
||||
}
|
||||
|
||||
return $account;
|
||||
});
|
||||
}
|
||||
}
|
||||
31
app/Support/JsonApi/Enrichments/EnrichmentInterface.php
Normal file
31
app/Support/JsonApi/Enrichments/EnrichmentInterface.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/*
|
||||
* EnricherInterface.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\Support\JsonApi\Enrichments;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
interface EnrichmentInterface
|
||||
{
|
||||
public function enrich(Collection $collection): Collection;
|
||||
}
|
||||
85
app/Support/JsonApi/ExpandsQuery.php
Normal file
85
app/Support/JsonApi/ExpandsQuery.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/*
|
||||
* ExpandsQuery.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\Support\JsonApi;
|
||||
|
||||
use FireflyIII\Support\Http\Api\AccountFilter;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use LaravelJsonApi\Core\Query\FilterParameters;
|
||||
use LaravelJsonApi\Core\Query\SortFields;
|
||||
|
||||
trait ExpandsQuery
|
||||
{
|
||||
use AccountFilter;
|
||||
|
||||
final protected function addPagination(Builder $query, array $pagination): Builder
|
||||
{
|
||||
$skip = ($pagination['number'] - 1) * $pagination['size'];
|
||||
|
||||
return $query->skip($skip)->take($pagination['size']);
|
||||
}
|
||||
|
||||
final protected function addSortParams(Builder $query, ?SortFields $sort): Builder
|
||||
{
|
||||
if (null === $sort) {
|
||||
return $query;
|
||||
}
|
||||
foreach ($sort->all() as $sortField) {
|
||||
$query->orderBy($sortField->name(), $sortField->isAscending() ? 'ASC' : 'DESC');
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
final protected function addFilterParams(string $class, Builder $query, ?FilterParameters $filters): Builder
|
||||
{
|
||||
if (null === $filters) {
|
||||
return $query;
|
||||
}
|
||||
$config = config(sprintf('firefly.valid_query_filters.%s', $class)) ?? [];
|
||||
if (0 === count($filters->all())) {
|
||||
return $query;
|
||||
}
|
||||
$query->where(function (Builder $q) use ($config, $filters): void {
|
||||
foreach ($filters->all() as $filter) {
|
||||
if (in_array($filter->key(), $config, true)) {
|
||||
foreach ($filter->value() as $value) {
|
||||
$q->where($filter->key(), 'LIKE', sprintf('%%%s%%', $value));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// some filters are special, i.e. the account type filter.
|
||||
$typeFilters = $filters->value('type', false);
|
||||
if (false !== $typeFilters && count($typeFilters) > 0) {
|
||||
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||
foreach ($typeFilters as $typeFilter) {
|
||||
$types = $this->mapAccountTypes($typeFilter);
|
||||
$query->whereIn('account_types.type', $types);
|
||||
}
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
55
app/Support/JsonApi/FiltersPagination.php
Normal file
55
app/Support/JsonApi/FiltersPagination.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/*
|
||||
* FiltersPagination.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\Support\JsonApi;
|
||||
|
||||
trait FiltersPagination
|
||||
{
|
||||
protected function filtersPagination(?array $pagination): array
|
||||
{
|
||||
if (null === $pagination) {
|
||||
return [
|
||||
'number' => 1,
|
||||
'size' => $this->getPageSize(),
|
||||
];
|
||||
}
|
||||
// cleanup page number
|
||||
$pagination['number'] = (int) ($pagination['number'] ?? 1);
|
||||
$pagination['number'] = min(65536, max($pagination['number'], 1));
|
||||
|
||||
// clean up page size
|
||||
$pagination['size'] = (int) ($pagination['size'] ?? $this->getPageSize());
|
||||
$pagination['size'] = min(1337, max($pagination['size'], 1));
|
||||
|
||||
return $pagination;
|
||||
}
|
||||
|
||||
private function getPageSize(): int
|
||||
{
|
||||
if (auth()->check()) {
|
||||
return (int) app('preferences')->get('listPageSize', 50)->data;
|
||||
}
|
||||
|
||||
return 50;
|
||||
}
|
||||
}
|
||||
42
app/Support/JsonApi/SortsCollection.php
Normal file
42
app/Support/JsonApi/SortsCollection.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/*
|
||||
* SortsCollection.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\Support\JsonApi;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use LaravelJsonApi\Core\Query\SortFields;
|
||||
|
||||
trait SortsCollection
|
||||
{
|
||||
protected function sortCollection(Collection $collection, ?SortFields $sortFields): Collection
|
||||
{
|
||||
if (null === $sortFields) {
|
||||
return $collection;
|
||||
}
|
||||
foreach ($sortFields->all() as $sortField) {
|
||||
$collection = $sortField->isAscending() ? $collection->sortBy($sortField->name()) : $collection->sortByDesc($sortField->name());
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
}
|
||||
46
app/Support/JsonApi/ValidateSortParameters.php
Normal file
46
app/Support/JsonApi/ValidateSortParameters.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/*
|
||||
* ValidateSortParameters.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\Support\JsonApi;
|
||||
|
||||
use LaravelJsonApi\Core\Query\SortFields;
|
||||
|
||||
trait ValidateSortParameters
|
||||
{
|
||||
public function validateParams(string $class, ?SortFields $params): bool
|
||||
{
|
||||
if (null === $params) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$config = config(sprintf('firefly.full_data_set.%s', $class)) ?? [];
|
||||
|
||||
foreach ($params->all() as $field) {
|
||||
if (in_array($field->name(), $config, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
208
app/Support/Models/AccountBalanceCalculator.php
Normal file
208
app/Support/Models/AccountBalanceCalculator.php
Normal file
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
/*
|
||||
* AccountBalanceCalculator.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\Support\Models;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountBalance;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class AccountBalanceCalculator
|
||||
{
|
||||
/**
|
||||
* Recalculate all balances for a given account.
|
||||
*
|
||||
* Je moet toch altijd wel alles doen want je weet niet waar een transaction journal invloed op heeft.
|
||||
* Dus dit aantikken per transaction journal is zinloos, beide accounts moeten gedaan worden.
|
||||
*/
|
||||
public static function recalculateForAccount(Account $account): void
|
||||
{
|
||||
self::recalculate($account);
|
||||
}
|
||||
|
||||
public static function recalculateForTransactionJournal(TransactionJournal $transactionJournal): void
|
||||
{
|
||||
foreach ($transactionJournal->transactions as $transaction) {
|
||||
self::recalculateForAccount($transaction->account);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* select account_id, transaction_currency_id, foreign_currency_id, sum(amount), sum(foreign_amount) from
|
||||
* transactions group by account_id, transaction_currency_id, foreign_currency_id
|
||||
*/
|
||||
public static function recalculate(?Account $account): void
|
||||
{
|
||||
self::recalculateLatest($account);
|
||||
// loop all transaction journals and set those amounts too.
|
||||
self::recalculateJournals($account);
|
||||
|
||||
// loop all dates and set those amounts too.
|
||||
}
|
||||
|
||||
private static function getAccountBalanceByAccount(int $account, int $currency): AccountBalance
|
||||
{
|
||||
$query = AccountBalance::where('title', 'balance')->where('account_id', $account)->where('transaction_currency_id', $currency);
|
||||
|
||||
$entry = $query->first();
|
||||
if (null !== $entry) {
|
||||
// Log::debug(sprintf('Found account balance "balance" for account #%d and currency #%d: %s', $account, $currency, $entry->balance));
|
||||
|
||||
return $entry;
|
||||
}
|
||||
$entry = new AccountBalance();
|
||||
$entry->title = 'balance';
|
||||
$entry->account_id = $account;
|
||||
$entry->transaction_currency_id = $currency;
|
||||
$entry->balance = '0';
|
||||
$entry->save();
|
||||
// Log::debug(sprintf('Created new account balance for account #%d and currency #%d: %s', $account, $currency, $entry->balance));
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
private static function getAccountBalanceByJournal(string $title, int $account, int $journal, int $currency): AccountBalance
|
||||
{
|
||||
$query = AccountBalance::where('title', $title)->where('account_id', $account)->where('transaction_journal_id', $journal)->where('transaction_currency_id', $currency);
|
||||
|
||||
$entry = $query->first();
|
||||
if (null !== $entry) {
|
||||
return $entry;
|
||||
}
|
||||
$entry = new AccountBalance();
|
||||
$entry->title = $title;
|
||||
$entry->account_id = $account;
|
||||
$entry->transaction_journal_id = $journal;
|
||||
$entry->transaction_currency_id = $currency;
|
||||
$entry->balance = '0';
|
||||
$entry->save();
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
private static function recalculateLatest(?Account $account): void
|
||||
{
|
||||
$query = Transaction::groupBy(['transactions.account_id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id']);
|
||||
|
||||
if (null !== $account) {
|
||||
$query->where('transactions.account_id', $account->id);
|
||||
}
|
||||
$result = $query->get(['transactions.account_id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id', \DB::raw('SUM(transactions.amount) as sum_amount'), \DB::raw('SUM(transactions.foreign_amount) as sum_foreign_amount')]);
|
||||
|
||||
// reset account balances:
|
||||
self::resetAccountBalancesByAccount('balance', $account);
|
||||
|
||||
/** @var \stdClass $row */
|
||||
foreach ($result as $row) {
|
||||
$account = (int) $row->account_id;
|
||||
$transactionCurrency = (int) $row->transaction_currency_id;
|
||||
$foreignCurrency = (int) $row->foreign_currency_id;
|
||||
$sumAmount = $row->sum_amount;
|
||||
$sumForeignAmount = $row->sum_foreign_amount;
|
||||
|
||||
// first create for normal currency:
|
||||
$entry = self::getAccountBalanceByAccount($account, $transactionCurrency);
|
||||
$entry->balance = bcadd($entry->balance, $sumAmount);
|
||||
$entry->save();
|
||||
// Log::debug(sprintf('Set balance entry #%d ("balance") to amount %s', $entry->id, $entry->balance));
|
||||
|
||||
// then do foreign amount, if present:
|
||||
if ($foreignCurrency > 0) {
|
||||
$entry = self::getAccountBalanceByAccount($account, $foreignCurrency);
|
||||
$entry->balance = bcadd($entry->balance, $sumForeignAmount);
|
||||
$entry->save();
|
||||
// Log::debug(sprintf('Set balance entry #%d ("balance") to amount %s', $entry->id, $entry->balance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function resetAccountBalancesByAccount(string $title, ?Account $account): void
|
||||
{
|
||||
if (null === $account) {
|
||||
AccountBalance::whereNotNull('updated_at')->where('title', $title)->update(['balance' => '0']);
|
||||
Log::debug('Set ALL balances to zero.');
|
||||
|
||||
return;
|
||||
}
|
||||
AccountBalance::where('account_id', $account->id)->where('title', $title)->update(['balance' => '0']);
|
||||
Log::debug(sprintf('Set balances of account #%d to zero.', $account->id));
|
||||
}
|
||||
|
||||
public static function recalculateByJournal(TransactionJournal $transactionJournal): void
|
||||
{
|
||||
Log::debug(sprintf('Recalculate balance after journal #%d', $transactionJournal->id));
|
||||
// update both account balances, but limit to this transaction or earlier.
|
||||
foreach ($transactionJournal->transactions as $transaction) {
|
||||
self::recalculate($transaction->account, $transactionJournal);
|
||||
}
|
||||
}
|
||||
|
||||
private static function recalculateJournals(?Account $account): void
|
||||
{
|
||||
$query = Transaction::groupBy(['transactions.account_id', 'transaction_journals.id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id']);
|
||||
$query->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id');
|
||||
$query->orderBy('transaction_journals.date', 'asc');
|
||||
if (null !== $account) {
|
||||
$query->where('transactions.account_id', $account->id);
|
||||
}
|
||||
$result = $query->get(['transactions.account_id', 'transaction_journals.id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id', \DB::raw('SUM(transactions.amount) as sum_amount'), \DB::raw('SUM(transactions.foreign_amount) as sum_foreign_amount')]);
|
||||
$amounts = [];
|
||||
|
||||
/** @var \stdClass $row */
|
||||
foreach ($result as $row) {
|
||||
$account = (int) $row->account_id;
|
||||
$transactionCurrency = (int) $row->transaction_currency_id;
|
||||
$foreignCurrency = (int) $row->foreign_currency_id;
|
||||
$sumAmount = $row->sum_amount;
|
||||
$sumForeignAmount = $row->sum_foreign_amount;
|
||||
$journalId = (int) $row->id;
|
||||
|
||||
// new amounts:
|
||||
$amounts[$account][$transactionCurrency] = bcadd($amounts[$account][$transactionCurrency] ?? '0', $sumAmount ?? '0');
|
||||
$amounts[$account][$foreignCurrency] = bcadd($amounts[$account][$foreignCurrency] ?? '0', $sumForeignAmount ?? '0');
|
||||
|
||||
// first create for normal currency:
|
||||
$entry = self::getAccountBalanceByJournal('balance_after_journal', $account, $journalId, $transactionCurrency);
|
||||
$entry->balance = $amounts[$account][$transactionCurrency];
|
||||
$entry->save();
|
||||
|
||||
// then do foreign amount, if present:
|
||||
if ($foreignCurrency > 0) {
|
||||
$entry = self::getAccountBalanceByJournal('balance_after_journal', $account, $journalId, $foreignCurrency);
|
||||
$entry->balance = $amounts[$account][$foreignCurrency];
|
||||
$entry->save();
|
||||
}
|
||||
}
|
||||
|
||||
// select transactions.account_id, transaction_journals.id, transactions.transaction_currency_id, transactions.foreign_currency_id, sum(transactions.amount), sum(transactions.foreign_amount)
|
||||
//
|
||||
// from transactions
|
||||
//
|
||||
// left join transaction_journals ON transaction_journals.id = transactions.transaction_journal_id
|
||||
//
|
||||
// group by account_id, transaction_journals.id, transaction_currency_id, foreign_currency_id
|
||||
// order by transaction_journals.date desc
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,12 @@ class AccountTransformer extends AbstractTransformer
|
||||
$this->convertedBalances = [];
|
||||
$this->balanceDifferences = [];
|
||||
|
||||
Log::debug(sprintf('collectMetaData on %d object(s)', $objects->count()));
|
||||
|
||||
// first collect all the "heavy" stuff that relies on ALL data to be present.
|
||||
// get last activity:
|
||||
$this->getLastActivity($objects);
|
||||
|
||||
// get balances of all accounts
|
||||
$this->getMetaBalances($objects);
|
||||
|
||||
@@ -75,18 +81,25 @@ class AccountTransformer extends AbstractTransformer
|
||||
// get account types:
|
||||
$this->collectAccountTypes($objects);
|
||||
|
||||
// get last activity:
|
||||
$this->getLastActivity($objects);
|
||||
|
||||
// add balance difference
|
||||
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
|
||||
$this->getBalanceDifference($objects, $this->parameters->get('start'), $this->parameters->get('end'));
|
||||
}
|
||||
|
||||
// get object groups"
|
||||
// get object groups
|
||||
$this->getObjectGroups($objects);
|
||||
|
||||
return $this->sortAccounts($objects);
|
||||
// sort:
|
||||
$objects = $this->sortAccounts($objects);
|
||||
|
||||
// if pagination is disabled, do it now:
|
||||
if (true === $this->parameters->get('disablePagination')) {
|
||||
$page = (int) $this->parameters->get('page');
|
||||
$size = (int) $this->parameters->get('pageSize');
|
||||
$objects = $objects->slice(($page - 1) * $size, $size);
|
||||
}
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
private function getDate(): Carbon
|
||||
|
||||
@@ -87,6 +87,8 @@
|
||||
"guzzlehttp/guzzle": "^7.8",
|
||||
"jc5/google2fa-laravel": "^2.0",
|
||||
"jc5/recovery": "^2",
|
||||
"laravel-json-api/laravel": "^4.0",
|
||||
"laravel-json-api/non-eloquent": "^4.0",
|
||||
"laravel/framework": "^11",
|
||||
"laravel/passport": "^12",
|
||||
"laravel/sanctum": "^4",
|
||||
@@ -101,13 +103,13 @@
|
||||
"psr/log": "<4",
|
||||
"ramsey/uuid": "^4.7",
|
||||
"rcrowe/twigbridge": "^0.14",
|
||||
"twig/twig": "3.8.0",
|
||||
"spatie/laravel-html": "^3.2",
|
||||
"spatie/laravel-ignition": "^2",
|
||||
"spatie/period": "^2.4",
|
||||
"symfony/expression-language": "^7.0",
|
||||
"symfony/http-client": "^7.0",
|
||||
"symfony/mailgun-mailer": "^7.0"
|
||||
"symfony/mailgun-mailer": "^7.0",
|
||||
"twig/twig": "3.8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^3.9",
|
||||
@@ -116,6 +118,7 @@
|
||||
"fakerphp/faker": "1.*",
|
||||
"filp/whoops": "2.*",
|
||||
"larastan/larastan": "^2",
|
||||
"laravel-json-api/testing": "^3.0",
|
||||
"mockery/mockery": "1.*",
|
||||
"phpstan/extension-installer": "^1.3",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
|
||||
1272
composer.lock
generated
1272
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -117,7 +117,7 @@ return [
|
||||
'expression_engine' => false,
|
||||
// see cer.php for exchange rates feature flag.
|
||||
],
|
||||
'version' => 'develop/2024-04-29',
|
||||
'version' => 'develop/2024-05-16',
|
||||
'api_version' => '2.0.14',
|
||||
'db_version' => 24,
|
||||
|
||||
@@ -941,4 +941,10 @@ return [
|
||||
'accounts' => ['name', 'active', 'iban', 'balance', 'last_activity', 'balance_difference', 'current_debt'],
|
||||
],
|
||||
],
|
||||
'full_data_set' => [
|
||||
'account' => ['last_activity', 'balance_difference', 'current_balance', 'current_debt'],
|
||||
],
|
||||
'valid_query_filters' => [
|
||||
'account' => ['name', 'iban', 'active'],
|
||||
],
|
||||
];
|
||||
|
||||
35
config/jsonapi.php
Normal file
35
config/jsonapi.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use FireflyIII\JsonApi\V3\Server;
|
||||
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Root Namespace
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The root JSON:API namespace, within your application's namespace.
|
||||
| This is used when generating any class that does not sit *within*
|
||||
| a server's namespace. For example, new servers and filters.
|
||||
|
|
||||
| By default this is set to `JsonApi` which means the root namespace
|
||||
| will be `\App\JsonApi`, if your application's namespace is `App`.
|
||||
*/
|
||||
'namespace' => 'JsonApi',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Servers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| A list of the JSON:API compliant APIs in your application, referred to
|
||||
| as "servers". They must be listed below, with the array key being the
|
||||
| unique name for each server, and the value being the fully-qualified
|
||||
| class name of the server class.
|
||||
*/
|
||||
'servers' => [
|
||||
'v3' => Server::class,
|
||||
],
|
||||
];
|
||||
@@ -284,7 +284,7 @@ class CreateMainTables extends Migration
|
||||
$table->integer('budget_id', false, true);
|
||||
$table->date('startdate');
|
||||
$table->decimal('amount', 32, 12);
|
||||
$table->string('repeat_freq', 30);
|
||||
$table->string('repeat_freq', 30)->nullable();
|
||||
$table->boolean('repeats')->default(0);
|
||||
$table->foreign('budget_id')->references('id')->on('budgets')->onDelete('cascade');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (!Schema::hasTable('account_balances')) {
|
||||
Schema::create('account_balances', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
$table->string('title', 100)->nullable();
|
||||
$table->integer('account_id', false, true);
|
||||
$table->integer('transaction_currency_id', false, true);
|
||||
$table->date('date')->nullable();
|
||||
$table->integer('transaction_journal_id', false, true)->nullable();
|
||||
$table->decimal('balance', 32, 12);
|
||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||
$table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
|
||||
$table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade');
|
||||
|
||||
$table->unique(['account_id', 'transaction_currency_id', 'transaction_journal_id', 'date', 'title'], 'unique_account_currency');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('account_balances');
|
||||
}
|
||||
};
|
||||
619
package-lock.json
generated
619
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -10,17 +10,17 @@
|
||||
"title": "T\u00edtol"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"drag_and_drop": "Arrossega i deixa anar",
|
||||
"active": "Est\u00e0 actiu?",
|
||||
"name": "Nom",
|
||||
"type": "Tipus",
|
||||
"number": "Account number",
|
||||
"number": "N\u00famero de compte",
|
||||
"liability_type": "Tipus de passiu",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
"current_balance": "Balan\u00e7 actual",
|
||||
"last_activity": "Darrera activitat",
|
||||
"amount_due": "Import pendent",
|
||||
"balance_difference": "Difer\u00e8ncia de saldo",
|
||||
"menu": "Men\u00fa"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III no pot determinar el tipus de transacci\u00f3 a partir d'aquest compte font.",
|
||||
|
||||
@@ -10,17 +10,17 @@
|
||||
"title": "T\u00edtol"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"drag_and_drop": "Arrossega i deixa anar",
|
||||
"active": "Est\u00e0 actiu?",
|
||||
"name": "Nom",
|
||||
"type": "Tipus",
|
||||
"number": "Account number",
|
||||
"number": "N\u00famero de compte",
|
||||
"liability_type": "Tipus de passiu",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
"current_balance": "Balan\u00e7 actual",
|
||||
"last_activity": "Darrera activitat",
|
||||
"amount_due": "Import pendent",
|
||||
"balance_difference": "Difer\u00e8ncia de saldo",
|
||||
"menu": "Men\u00fa"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Firefly III no pot determinar el tipus de transacci\u00f3 a partir d'aquest compte font.",
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
"date_time_fns": "do MMMM yyyy @ HH:mm:ss",
|
||||
"month_and_day_fns": "d MMMM y",
|
||||
"does_not_exist": "(config.does_not_exist)",
|
||||
"date_time_fns_short": "MMMM do, yyyy @ HH:mm"
|
||||
"date_time_fns_short": "D MMMM yyyy [o] HH:mm"
|
||||
},
|
||||
"form": {
|
||||
"title": "Tytu\u0142"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"drag_and_drop": "Przeci\u0105gnij i upu\u015b\u0107",
|
||||
"active": "Jest aktywny?",
|
||||
"name": "Nazwa",
|
||||
"type": "Typ",
|
||||
"number": "Account number",
|
||||
"number": "Numer konta",
|
||||
"liability_type": "Rodzaj zobowi\u0105zania",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"current_balance": "Bie\u017c\u0105ce saldo",
|
||||
"last_activity": "Ostatnia aktywno\u015b\u0107",
|
||||
"amount_due": "Do zap\u0142aty",
|
||||
"balance_difference": "R\u00f3\u017cnica salda",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
@@ -38,20 +38,20 @@
|
||||
"interest_calc_quarterly": "Kwartalnie",
|
||||
"spent": "Wydano",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
"administration_role_owner": "Owner",
|
||||
"administration_role_ro": "Read-only",
|
||||
"administration_role_mng_trx": "Manage transactions",
|
||||
"administration_role_mng_meta": "Manage classification and meta-data",
|
||||
"administration_role_mng_budgets": "Manage budgets",
|
||||
"administration_role_mng_piggies": "Manage piggy banks",
|
||||
"administration_role_mng_subscriptions": "Manage subscriptions",
|
||||
"administration_role_mng_rules": "Manage rules",
|
||||
"administration_role_mng_recurring": "Manage recurring transactions ",
|
||||
"administration_you": "Twoja rola: {{role}}",
|
||||
"administration_role_owner": "W\u0142a\u015bciciel",
|
||||
"administration_role_ro": "Tylko odczyt",
|
||||
"administration_role_mng_trx": "Zarz\u0105dzanie transakcjami",
|
||||
"administration_role_mng_meta": "Zarz\u0105dzanie klasyfikacj\u0105 i meta-danymi",
|
||||
"administration_role_mng_budgets": "Zarz\u0105dzanie bud\u017cetami",
|
||||
"administration_role_mng_piggies": "Zarz\u0105dzanie skarbonkami",
|
||||
"administration_role_mng_subscriptions": "Zarz\u0105dzanie subskrypcjami",
|
||||
"administration_role_mng_rules": "Zarz\u0105dzanie regu\u0142ami",
|
||||
"administration_role_mng_recurring": "Zarz\u0105dzanie transakcjami cyklicznymi ",
|
||||
"administration_role_mng_webhooks": "Manage webhooks",
|
||||
"administration_role_mng_currencies": "Manage currencies",
|
||||
"administration_role_view_reports": "View reports",
|
||||
"administration_role_full": "Full access",
|
||||
"administration_role_mng_currencies": "Zarz\u0105dzanie walutami",
|
||||
"administration_role_view_reports": "Przegl\u0105danie raport\u00f3w",
|
||||
"administration_role_full": "Pe\u0142ny dost\u0119p",
|
||||
"new_administration_created": "New financial administration \"{{title}}\" has been created",
|
||||
"left": "Pozosta\u0142o",
|
||||
"paid": "Zap\u0142acone",
|
||||
@@ -70,10 +70,10 @@
|
||||
"unknown_dest_plain": "Nieznane konto docelowe",
|
||||
"unknown_any_plain": "Nieznane konto",
|
||||
"unknown_budget_plain": "Brak bud\u017cetu",
|
||||
"stored_journal_js": "Successfully created new transaction \"{{description}}\"",
|
||||
"stored_journal_js": "Pomy\u015blnie utworzono now\u0105 transakcj\u0119 \"{{description}}\"",
|
||||
"wait_loading_transaction": "Poczekaj na za\u0142adowanie formularza",
|
||||
"nothing_found": "(nic nie znaleziono)",
|
||||
"wait_loading_data": "Please wait for your information to load...",
|
||||
"wait_loading_data": "Prosz\u0119 poczeka\u0107 na za\u0142adowanie informacji...",
|
||||
"Transfer": "Transfer",
|
||||
"Withdrawal": "Wyp\u0142ata",
|
||||
"Deposit": "Wp\u0142ata",
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
"date_time_fns": "do MMMM yyyy @ HH:mm:ss",
|
||||
"month_and_day_fns": "d MMMM y",
|
||||
"does_not_exist": "(config.does_not_exist)",
|
||||
"date_time_fns_short": "MMMM do, yyyy @ HH:mm"
|
||||
"date_time_fns_short": "D MMMM yyyy [o] HH:mm"
|
||||
},
|
||||
"form": {
|
||||
"title": "Tytu\u0142"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"drag_and_drop": "Przeci\u0105gnij i upu\u015b\u0107",
|
||||
"active": "Jest aktywny?",
|
||||
"name": "Nazwa",
|
||||
"type": "Typ",
|
||||
"number": "Account number",
|
||||
"number": "Numer konta",
|
||||
"liability_type": "Rodzaj zobowi\u0105zania",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"current_balance": "Bie\u017c\u0105ce saldo",
|
||||
"last_activity": "Ostatnia aktywno\u015b\u0107",
|
||||
"amount_due": "Do zap\u0142aty",
|
||||
"balance_difference": "R\u00f3\u017cnica salda",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
@@ -38,20 +38,20 @@
|
||||
"interest_calc_quarterly": "Kwartalnie",
|
||||
"spent": "Wydano",
|
||||
"administration_owner": "Administration owner: {{email}}",
|
||||
"administration_you": "Your role: {{role}}",
|
||||
"administration_role_owner": "Owner",
|
||||
"administration_role_ro": "Read-only",
|
||||
"administration_role_mng_trx": "Manage transactions",
|
||||
"administration_role_mng_meta": "Manage classification and meta-data",
|
||||
"administration_role_mng_budgets": "Manage budgets",
|
||||
"administration_role_mng_piggies": "Manage piggy banks",
|
||||
"administration_role_mng_subscriptions": "Manage subscriptions",
|
||||
"administration_role_mng_rules": "Manage rules",
|
||||
"administration_role_mng_recurring": "Manage recurring transactions ",
|
||||
"administration_you": "Twoja rola: {{role}}",
|
||||
"administration_role_owner": "W\u0142a\u015bciciel",
|
||||
"administration_role_ro": "Tylko odczyt",
|
||||
"administration_role_mng_trx": "Zarz\u0105dzanie transakcjami",
|
||||
"administration_role_mng_meta": "Zarz\u0105dzanie klasyfikacj\u0105 i meta-danymi",
|
||||
"administration_role_mng_budgets": "Zarz\u0105dzanie bud\u017cetami",
|
||||
"administration_role_mng_piggies": "Zarz\u0105dzanie skarbonkami",
|
||||
"administration_role_mng_subscriptions": "Zarz\u0105dzanie subskrypcjami",
|
||||
"administration_role_mng_rules": "Zarz\u0105dzanie regu\u0142ami",
|
||||
"administration_role_mng_recurring": "Zarz\u0105dzanie transakcjami cyklicznymi ",
|
||||
"administration_role_mng_webhooks": "Manage webhooks",
|
||||
"administration_role_mng_currencies": "Manage currencies",
|
||||
"administration_role_view_reports": "View reports",
|
||||
"administration_role_full": "Full access",
|
||||
"administration_role_mng_currencies": "Zarz\u0105dzanie walutami",
|
||||
"administration_role_view_reports": "Przegl\u0105danie raport\u00f3w",
|
||||
"administration_role_full": "Pe\u0142ny dost\u0119p",
|
||||
"new_administration_created": "New financial administration \"{{title}}\" has been created",
|
||||
"left": "Pozosta\u0142o",
|
||||
"paid": "Zap\u0142acone",
|
||||
@@ -70,10 +70,10 @@
|
||||
"unknown_dest_plain": "Nieznane konto docelowe",
|
||||
"unknown_any_plain": "Nieznane konto",
|
||||
"unknown_budget_plain": "Brak bud\u017cetu",
|
||||
"stored_journal_js": "Successfully created new transaction \"{{description}}\"",
|
||||
"stored_journal_js": "Pomy\u015blnie utworzono now\u0105 transakcj\u0119 \"{{description}}\"",
|
||||
"wait_loading_transaction": "Poczekaj na za\u0142adowanie formularza",
|
||||
"nothing_found": "(nic nie znaleziono)",
|
||||
"wait_loading_data": "Please wait for your information to load...",
|
||||
"wait_loading_data": "Prosz\u0119 poczeka\u0107 na za\u0142adowanie informacji...",
|
||||
"Transfer": "Transfer",
|
||||
"Withdrawal": "Wyp\u0142ata",
|
||||
"Deposit": "Wp\u0142ata",
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
"title": "T\u00edtulo"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"drag_and_drop": "Arrastar e soltar",
|
||||
"active": "Est\u00e1 ativo?",
|
||||
"name": "Nome",
|
||||
"type": "Tipo",
|
||||
"number": "Account number",
|
||||
"number": "N\u00famero da conta",
|
||||
"liability_type": "Tipo de passivo",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"current_balance": "Saldo atual",
|
||||
"last_activity": "\u00daltima atividade",
|
||||
"amount_due": "Valor devido",
|
||||
"balance_difference": "Diferen\u00e7a de saldo",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
"title": "T\u00edtulo"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"drag_and_drop": "Arrastar e soltar",
|
||||
"active": "Esta ativo?",
|
||||
"name": "Nome",
|
||||
"type": "Tipo",
|
||||
"number": "Account number",
|
||||
"number": "N\u00famero de conta",
|
||||
"liability_type": "Tipo de responsabilidade",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"current_balance": "Saldo atual",
|
||||
"last_activity": "\u00daltima atividade",
|
||||
"amount_due": "Valor a pagar",
|
||||
"balance_difference": "Diferen\u00e7a de saldo",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
"title": "T\u00edtulo"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"drag_and_drop": "Arrastar e soltar",
|
||||
"active": "Est\u00e1 ativo?",
|
||||
"name": "Nome",
|
||||
"type": "Tipo",
|
||||
"number": "Account number",
|
||||
"number": "N\u00famero da conta",
|
||||
"liability_type": "Tipo de passivo",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"current_balance": "Saldo atual",
|
||||
"last_activity": "\u00daltima atividade",
|
||||
"amount_due": "Valor devido",
|
||||
"balance_difference": "Diferen\u00e7a de saldo",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
"title": "T\u00edtulo"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"drag_and_drop": "Arrastar e soltar",
|
||||
"active": "Esta ativo?",
|
||||
"name": "Nome",
|
||||
"type": "Tipo",
|
||||
"number": "Account number",
|
||||
"number": "N\u00famero de conta",
|
||||
"liability_type": "Tipo de responsabilidade",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"current_balance": "Saldo atual",
|
||||
"last_activity": "\u00daltima atividade",
|
||||
"amount_due": "Valor a pagar",
|
||||
"balance_difference": "Diferen\u00e7a de saldo",
|
||||
"menu": "Menu"
|
||||
},
|
||||
"validation": {
|
||||
|
||||
@@ -10,17 +10,17 @@
|
||||
"title": "Naslov"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"drag_and_drop": "Povleci in spusti",
|
||||
"active": "Aktiviran?",
|
||||
"name": "ime",
|
||||
"type": "Vrsta",
|
||||
"number": "Account number",
|
||||
"number": "\u0160tevilka ra\u010duna",
|
||||
"liability_type": "Vrsta obveznost",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
"current_balance": "Trenutno stanje",
|
||||
"last_activity": "Zadnja aktivnost",
|
||||
"amount_due": "Dolgovani znesek",
|
||||
"balance_difference": "Bilan\u010dna razlika",
|
||||
"menu": "Meni"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Na podlagi tega izvornega ra\u010duna Firefly III ne more dolo\u010diti vrste transakcije.",
|
||||
|
||||
@@ -10,17 +10,17 @@
|
||||
"title": "Naslov"
|
||||
},
|
||||
"list": {
|
||||
"drag_and_drop": "Drag and drop",
|
||||
"drag_and_drop": "Povleci in spusti",
|
||||
"active": "Aktiviran?",
|
||||
"name": "ime",
|
||||
"type": "Vrsta",
|
||||
"number": "Account number",
|
||||
"number": "\u0160tevilka ra\u010duna",
|
||||
"liability_type": "Vrsta obveznost",
|
||||
"current_balance": "Current balance",
|
||||
"last_activity": "Last activity",
|
||||
"amount_due": "Amount due",
|
||||
"balance_difference": "Balance difference",
|
||||
"menu": "Menu"
|
||||
"current_balance": "Trenutno stanje",
|
||||
"last_activity": "Zadnja aktivnost",
|
||||
"amount_due": "Dolgovani znesek",
|
||||
"balance_difference": "Bilan\u010dna razlika",
|
||||
"menu": "Meni"
|
||||
},
|
||||
"validation": {
|
||||
"bad_type_source": "Na podlagi tega izvornega ra\u010duna Firefly III ne more dolo\u010diti vrste transakcije.",
|
||||
|
||||
@@ -4,20 +4,16 @@
|
||||
"/build/create_transaction.js": "/build/create_transaction.js",
|
||||
"/build/edit_transaction.js": "/build/edit_transaction.js",
|
||||
"/build/profile.js": "/build/profile.js",
|
||||
"/build/index.js": "/build/index.js",
|
||||
"/build/create.js": "/build/create.js",
|
||||
"/build/edit.js": "/build/edit.js",
|
||||
"/build/show.js": "/build/show.js",
|
||||
"/build/webhooks/index.js": "/build/webhooks/index.js",
|
||||
"/build/webhooks/create.js": "/build/webhooks/create.js",
|
||||
"/build/webhooks/edit.js": "/build/webhooks/edit.js",
|
||||
"/build/webhooks/show.js": "/build/webhooks/show.js",
|
||||
"/public/v1/js/app.js": "/public/v1/js/app.js",
|
||||
"/public/v1/js/app.js.LICENSE.txt": "/public/v1/js/app.js.LICENSE.txt",
|
||||
"/public/v1/js/app_vue.js": "/public/v1/js/app_vue.js",
|
||||
"/public/v1/js/app_vue.js.LICENSE.txt": "/public/v1/js/app_vue.js.LICENSE.txt",
|
||||
"/public/v1/js/create.js": "/public/v1/js/create.js",
|
||||
"/public/v1/js/create.js.LICENSE.txt": "/public/v1/js/create.js.LICENSE.txt",
|
||||
"/public/v1/js/create_transaction.js": "/public/v1/js/create_transaction.js",
|
||||
"/public/v1/js/create_transaction.js.LICENSE.txt": "/public/v1/js/create_transaction.js.LICENSE.txt",
|
||||
"/public/v1/js/edit.js": "/public/v1/js/edit.js",
|
||||
"/public/v1/js/edit.js.LICENSE.txt": "/public/v1/js/edit.js.LICENSE.txt",
|
||||
"/public/v1/js/edit_transaction.js": "/public/v1/js/edit_transaction.js",
|
||||
"/public/v1/js/edit_transaction.js.LICENSE.txt": "/public/v1/js/edit_transaction.js.LICENSE.txt",
|
||||
"/public/v1/js/ff/accounts/create.js": "/public/v1/js/ff/accounts/create.js",
|
||||
@@ -88,8 +84,6 @@
|
||||
"/public/v1/js/ff/transactions/mass/edit-bulk.js": "/public/v1/js/ff/transactions/mass/edit-bulk.js",
|
||||
"/public/v1/js/ff/transactions/mass/edit.js": "/public/v1/js/ff/transactions/mass/edit.js",
|
||||
"/public/v1/js/ff/transactions/show.js": "/public/v1/js/ff/transactions/show.js",
|
||||
"/public/v1/js/index.js": "/public/v1/js/index.js",
|
||||
"/public/v1/js/index.js.LICENSE.txt": "/public/v1/js/index.js.LICENSE.txt",
|
||||
"/public/v1/js/lib/Chart.bundle.min.js": "/public/v1/js/lib/Chart.bundle.min.js",
|
||||
"/public/v1/js/lib/accounting.min.js": "/public/v1/js/lib/accounting.min.js",
|
||||
"/public/v1/js/lib/bootstrap-multiselect.js": "/public/v1/js/lib/bootstrap-multiselect.js",
|
||||
@@ -148,6 +142,12 @@
|
||||
"/public/v1/js/lib/vue.js": "/public/v1/js/lib/vue.js",
|
||||
"/public/v1/js/profile.js": "/public/v1/js/profile.js",
|
||||
"/public/v1/js/profile.js.LICENSE.txt": "/public/v1/js/profile.js.LICENSE.txt",
|
||||
"/public/v1/js/show.js": "/public/v1/js/show.js",
|
||||
"/public/v1/js/show.js.LICENSE.txt": "/public/v1/js/show.js.LICENSE.txt"
|
||||
"/public/v1/js/webhooks/create.js": "/public/v1/js/webhooks/create.js",
|
||||
"/public/v1/js/webhooks/create.js.LICENSE.txt": "/public/v1/js/webhooks/create.js.LICENSE.txt",
|
||||
"/public/v1/js/webhooks/edit.js": "/public/v1/js/webhooks/edit.js",
|
||||
"/public/v1/js/webhooks/edit.js.LICENSE.txt": "/public/v1/js/webhooks/edit.js.LICENSE.txt",
|
||||
"/public/v1/js/webhooks/index.js": "/public/v1/js/webhooks/index.js",
|
||||
"/public/v1/js/webhooks/index.js.LICENSE.txt": "/public/v1/js/webhooks/index.js.LICENSE.txt",
|
||||
"/public/v1/js/webhooks/show.js": "/public/v1/js/webhooks/show.js",
|
||||
"/public/v1/js/webhooks/show.js.LICENSE.txt": "/public/v1/js/webhooks/show.js.LICENSE.txt"
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ mix.js('src/edit_transaction.js', 'build').vue({version: 2});
|
||||
mix.js('src/profile.js', 'build').vue({version: 2});
|
||||
//
|
||||
// // webhooks
|
||||
mix.js('src/webhooks/index.js', 'build').vue({version: 2});
|
||||
mix.js('src/webhooks/create.js', 'build').vue({version: 2});
|
||||
mix.js('src/webhooks/edit.js', 'build').vue({version: 2});
|
||||
mix.js('src/webhooks/show.js', 'build').vue({version: 2}).copy('build','../../../public/v1/js')
|
||||
mix.js('src/webhooks/index.js', 'build/webhooks').vue({version: 2});
|
||||
mix.js('src/webhooks/create.js', 'build/webhooks').vue({version: 2});
|
||||
mix.js('src/webhooks/edit.js', 'build/webhooks').vue({version: 2});
|
||||
mix.js('src/webhooks/show.js', 'build/webhooks').vue({version: 2}).copy('build','../../../public/v1/js')
|
||||
|
||||
@@ -486,13 +486,15 @@ let transactions = function () {
|
||||
// addedSplit, is called from the HTML
|
||||
// for source account
|
||||
const renderAccount = function (item, b, c) {
|
||||
return item.name_with_balance + '<br><small class="text-muted">' + i18next.t('firefly.account_type_' + item.type) + '</small>';
|
||||
return item.title + '<br><small class="text-muted">' + i18next.t('firefly.account_type_' + item.meta.type) + '</small>';
|
||||
};
|
||||
addAutocomplete({
|
||||
selector: 'input.ac-source',
|
||||
serverUrl: urls.account,
|
||||
// filters: this.filters.source,
|
||||
// onRenderItem: renderAccount,
|
||||
onRenderItem: renderAccount,
|
||||
valueField: 'id',
|
||||
labelField: 'title',
|
||||
onChange: changeSourceAccount,
|
||||
onSelectItem: selectSourceAccount,
|
||||
hiddenValue: this.entries[count].source_account.alpine_name
|
||||
@@ -500,7 +502,9 @@ let transactions = function () {
|
||||
addAutocomplete({
|
||||
selector: 'input.ac-dest',
|
||||
serverUrl: urls.account,
|
||||
filters: this.filters.destination,
|
||||
account_types: this.filters.destination,
|
||||
valueField: 'id',
|
||||
labelField: 'title',
|
||||
onRenderItem: renderAccount,
|
||||
onChange: changeDestinationAccount,
|
||||
onSelectItem: selectDestinationAccount
|
||||
|
||||
@@ -200,20 +200,23 @@ let transactions = function () {
|
||||
// addedSplit, is called from the HTML
|
||||
// for source account
|
||||
const renderAccount = function (item, b, c) {
|
||||
return item.name_with_balance + '<br><small class="text-muted">' + i18next.t('firefly.account_type_' + item.type) + '</small>';
|
||||
console.log(item);
|
||||
return item.title + '<br><small class="text-muted">' + i18next.t('firefly.account_type_' + item.meta.type) + '</small>';
|
||||
};
|
||||
addAutocomplete({
|
||||
selector: 'input.ac-source',
|
||||
serverUrl: urls.account,
|
||||
filters: this.filters.source,
|
||||
account_types: this.filters.source,
|
||||
onRenderItem: renderAccount,
|
||||
valueField: 'id',
|
||||
labelField: 'title',
|
||||
onChange: changeSourceAccount,
|
||||
onSelectItem: selectSourceAccount
|
||||
});
|
||||
addAutocomplete({
|
||||
selector: 'input.ac-dest',
|
||||
serverUrl: urls.account,
|
||||
filters: this.filters.destination,
|
||||
account_types: this.filters.destination,
|
||||
onRenderItem: renderAccount,
|
||||
onChange: changeDestinationAccount,
|
||||
onSelectItem: selectDestinationAccount
|
||||
@@ -222,7 +225,7 @@ let transactions = function () {
|
||||
selector: 'input.ac-category',
|
||||
serverUrl: urls.category,
|
||||
valueField: 'id',
|
||||
labelField: 'name',
|
||||
labelField: 'title',
|
||||
onChange: changeCategory,
|
||||
onSelectItem: changeCategory
|
||||
});
|
||||
|
||||
@@ -38,13 +38,14 @@ export function addAutocomplete(options) {
|
||||
'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content
|
||||
}
|
||||
},
|
||||
queryParam: 'filter[query]',
|
||||
hiddenInput: true,
|
||||
// preventBrowserAutocomplete: true,
|
||||
highlightTyped: true,
|
||||
liveServer: true,
|
||||
};
|
||||
if (typeof options.filters !== 'undefined' && options.filters.length > 0) {
|
||||
params.serverParams.types = options.filters;
|
||||
if (typeof options.account_types !== 'undefined' && options.account_types.length > 0) {
|
||||
params.serverParams['filter[account_types]'] = options.account_types;
|
||||
}
|
||||
if (typeof options.onRenderItem !== 'undefined' && null !== options.onRenderItem) {
|
||||
params.onRenderItem = options.onRenderItem;
|
||||
|
||||
@@ -55,13 +55,12 @@ export function changeDestinationAccount(item, ac) {
|
||||
export function selectDestinationAccount(item, ac) {
|
||||
const index = parseInt(ac._searchInput.attributes['data-index'].value);
|
||||
document.querySelector('#form')._x_dataStack[0].$data.entries[index].destination_account = {
|
||||
id: item.id, name: item.name, alpine_name: item.name, type: item.type, currency_code: item.currency_code,
|
||||
id: item.id, name: item.title, alpine_name: item.title, type: item.meta.type, currency_code: item.meta.currency_code,
|
||||
};
|
||||
document.querySelector('#form')._x_dataStack[0].changedDestinationAccount();
|
||||
}
|
||||
|
||||
export function changeSourceAccount(item, ac) {
|
||||
// console.log('changeSourceAccount');
|
||||
if (typeof item === 'undefined') {
|
||||
const index = parseInt(ac._searchInput.attributes['data-index'].value);
|
||||
let source = document.querySelector('#form')._x_dataStack[0].$data.entries[index].source_account;
|
||||
@@ -79,7 +78,7 @@ export function changeSourceAccount(item, ac) {
|
||||
export function selectSourceAccount(item, ac) {
|
||||
const index = parseInt(ac._searchInput.attributes['data-index'].value);
|
||||
document.querySelector('#form')._x_dataStack[0].$data.entries[index].source_account = {
|
||||
id: item.id, name: item.name, alpine_name: item.name, type: item.type, currency_code: item.currency_code,
|
||||
id: item.id, name: item.title, alpine_name: item.title, type: item.meta.type, currency_code: item.meta.currency_code,
|
||||
};
|
||||
document.querySelector('#form')._x_dataStack[0].changedSourceAccount();
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'IP адресът, свързан с тази грешка, е: :ip',
|
||||
'error_url' => 'URL адресът е: :url',
|
||||
'error_user_agent' => 'Брaузър агент: :userAgent',
|
||||
'error_stacktrace' => 'Пълният стак на грешката е отдолу. Ако смятате, че това е грешка в Firefly III, можете да препратите това съобщение до <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a>. Това може да помогне за отстраняване на грешката, която току-що срещнахте.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Ако предпочитате, можете също да отворите нов проблем на <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Ако предпочитате, можете също да отворите нов проблем на https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'Пълният stacktrace е отдолу:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'L\'adreça IP d\'aquest error és: :ip',
|
||||
'error_url' => 'L\'URL és: :url',
|
||||
'error_user_agent' => 'Agent d\'usuari: :userAgent',
|
||||
'error_stacktrace' => 'La traça completa és a continuació. Si creus que és un error de Firefly III, pots reenviar aquest missatge a <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a>. Podria ajudar a solucionar l\'error que acabes de trobar.',
|
||||
'error_stacktrace' => 'La traça completa és a continuació. Si creus que és un error de Firefly III, pots reenviar aquest missatge a <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. Podria ajudar a solucionar l\'error que acabes de trobar.',
|
||||
'error_github_html' => 'Si ho prefereixes, també pots obrir un nou issue a <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Si ho prefereixes, també pots obrir un nou issue a https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'La traça completa és a continuació:',
|
||||
|
||||
@@ -1961,19 +1961,19 @@ return [
|
||||
'interest_calc_quarterly' => 'Per quadrimestre',
|
||||
'initial_balance_account' => 'Compte de balanç inicial de :account',
|
||||
'list_options' => 'Llista opcions',
|
||||
'account_column_opt_drag_and_drop' => 'Drag and drop',
|
||||
'account_column_opt_active' => 'Active',
|
||||
'account_column_opt_name' => 'Name',
|
||||
'account_column_opt_type' => 'Type',
|
||||
'account_column_opt_liability_type' => 'Liability type',
|
||||
'account_column_opt_liability_direction' => 'Liability direction',
|
||||
'account_column_opt_liability_interest' => 'Liability interest',
|
||||
'account_column_opt_number' => 'Account number',
|
||||
'account_column_opt_current_balance' => 'Current balance',
|
||||
'account_column_opt_amount_due' => 'Amount due',
|
||||
'account_column_opt_last_activity' => 'Last activity',
|
||||
'account_column_opt_balance_difference' => 'Balance difference',
|
||||
'account_column_opt_menu' => 'Menu',
|
||||
'account_column_opt_drag_and_drop' => 'Arrossega i deixa anar',
|
||||
'account_column_opt_active' => 'Actiu',
|
||||
'account_column_opt_name' => 'Nom',
|
||||
'account_column_opt_type' => 'Tipus',
|
||||
'account_column_opt_liability_type' => 'Tipus de passiu',
|
||||
'account_column_opt_liability_direction' => 'Direcció del passiu',
|
||||
'account_column_opt_liability_interest' => 'Interés del passiu',
|
||||
'account_column_opt_number' => 'Número de compte',
|
||||
'account_column_opt_current_balance' => 'Balanç actual',
|
||||
'account_column_opt_amount_due' => 'Import pendent',
|
||||
'account_column_opt_last_activity' => 'Darrera activitat',
|
||||
'account_column_opt_balance_difference' => 'Diferència de saldo',
|
||||
'account_column_opt_menu' => 'Menú',
|
||||
|
||||
// categories:
|
||||
'new_category' => 'Nova categoria',
|
||||
@@ -2157,7 +2157,7 @@ return [
|
||||
'logout' => 'Tanca la sessió',
|
||||
'logout_other_sessions' => 'Tanca les altres sessions',
|
||||
'toggleNavigation' => 'Alternar navegació',
|
||||
'toggle_dropdown' => 'Toggle dropdown',
|
||||
'toggle_dropdown' => 'Commutar desplegable',
|
||||
'searchPlaceholder' => 'Cerca...',
|
||||
'version' => 'Versió',
|
||||
'dashboard' => 'Panell de control',
|
||||
@@ -2401,13 +2401,13 @@ return [
|
||||
|
||||
// page settings and wizard dialogs
|
||||
|
||||
'page_settings_header' => 'Page settings',
|
||||
'visible_columns' => 'Visible columns',
|
||||
'accounts_to_show' => 'Accounts to show',
|
||||
'active_accounts_only' => 'Active accounts only',
|
||||
'in_active_accounts_only' => 'Inactive accounts only',
|
||||
'show_all_accounts' => 'Show all accounts',
|
||||
'group_accounts' => 'Group accounts',
|
||||
'page_settings_header' => 'Configuració de pàgina',
|
||||
'visible_columns' => 'Columnes visibles',
|
||||
'accounts_to_show' => 'Comptes a mostrar',
|
||||
'active_accounts_only' => 'Només comptes actius',
|
||||
'in_active_accounts_only' => 'Només comptes inactius',
|
||||
'show_all_accounts' => 'Mostra tots els comptes',
|
||||
'group_accounts' => 'Agrupa comptes',
|
||||
|
||||
// piggy banks:
|
||||
'event_history' => 'Historial d\'esdeveniments',
|
||||
|
||||
@@ -37,7 +37,7 @@ return [
|
||||
// new user:
|
||||
'bank_name' => 'Nom del banc',
|
||||
'bank_balance' => 'Saldo',
|
||||
'current_balance' => 'Current balance',
|
||||
'current_balance' => 'Balanç actual',
|
||||
'savings_balance' => 'Saldo d\'estalvis',
|
||||
'credit_card_limit' => 'Límit de la targeta de crèdit',
|
||||
'automatch' => 'Coincidir automàticament',
|
||||
|
||||
@@ -67,13 +67,13 @@ return [
|
||||
'source' => 'Origen',
|
||||
'next_expected_match' => 'Pròxima coincidència esperada',
|
||||
'automatch' => 'Cercar coincidència automàticament?',
|
||||
'drag_and_drop' => 'Drag and drop',
|
||||
'number' => 'Account number',
|
||||
'current_balance' => 'Current balance',
|
||||
'last_activity' => 'Last activity',
|
||||
'amount_due' => 'Amount due',
|
||||
'balance_difference' => 'Balance difference',
|
||||
'menu' => 'Menu',
|
||||
'drag_and_drop' => 'Arrossega i deixa anar',
|
||||
'number' => 'Número de compte',
|
||||
'current_balance' => 'Balanç actual',
|
||||
'last_activity' => 'Darrera activitat',
|
||||
'amount_due' => 'Import pendent',
|
||||
'balance_difference' => 'Diferència de saldo',
|
||||
'menu' => 'Menú',
|
||||
|
||||
/*
|
||||
* PLEASE DO NOT EDIT THIS FILE DIRECTLY.
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'IP adresa související s touto chybou je: :ip',
|
||||
'error_url' => 'Adresa URL je: :url',
|
||||
'error_user_agent' => 'User agent: :userAgent',
|
||||
'error_stacktrace' => 'Úplný zásobník je uveden níže. Pokud si myslíte, že se jedná o chybu ve Firefly III, můžete tuto zprávu přeposlat na <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii. rg</a>. To může pomoci opravit chybu, na kterou jste právě narazili.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Pokud chcete, můžete vytvořit hlášení problému na <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Pokud chcete, můžete vytvořit hlášení problému na https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'Celý zásobník je níže:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'IP-adressen relateret til denne fejl er: :ip',
|
||||
'error_url' => 'URL er: :url',
|
||||
'error_user_agent' => 'Brugeragent: :userAgent',
|
||||
'error_stacktrace' => 'Den fulde stacktrace er nedenfor. Hvis du tror, at dette er en fejl i Firefly III, kan du videresende denne meddelelse til <a href="mailto:james@firefly-iii.org?subject=BUG!">james@ firefly-iii. rg</a>. Dette kan være behjælpeligt med at rette den fejl, du lige er stødt på.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Hvis du foretrækker det, kan du også rapportere et nyt problem på <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Hvis du foretrækker det, kan du også rapportere et nyt problem på https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'Den fulde stacktrace er nedenfor:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'Die IP-Adresse bezogen auf diesen Fehler lautet: :ip',
|
||||
'error_url' => 'URL ist: :url',
|
||||
'error_user_agent' => 'User Agent: :userAgent',
|
||||
'error_stacktrace' => 'Der vollständige Stacktrace ist unten. Wenn Sie denken, dass dies ein Fehler in Firefly III ist, können Sie diese Nachricht an <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii weiterleiten. rg</a>. Dies kann helfen, den Fehler zu beheben, den Sie gerade gefunden haben.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Wenn Sie es bevorzugen, können Sie auch einen Fehlerbericht auf <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a> eröffnen.',
|
||||
'error_github_text' => 'Wenn Sie es bevorzugen, können Sie auch einen Fehlerbericht auf https://github.com/firefly-iii/firefly-iii/issues eröffnen.',
|
||||
'error_stacktrace_below' => 'Der vollständige Stacktrace ist unten:',
|
||||
|
||||
@@ -2401,13 +2401,13 @@ return [
|
||||
|
||||
// page settings and wizard dialogs
|
||||
|
||||
'page_settings_header' => 'Page settings',
|
||||
'visible_columns' => 'Visible columns',
|
||||
'accounts_to_show' => 'Accounts to show',
|
||||
'active_accounts_only' => 'Active accounts only',
|
||||
'in_active_accounts_only' => 'Inactive accounts only',
|
||||
'show_all_accounts' => 'Show all accounts',
|
||||
'group_accounts' => 'Group accounts',
|
||||
'page_settings_header' => 'Seiteneinstellungen',
|
||||
'visible_columns' => 'Sichtbare Spalten',
|
||||
'accounts_to_show' => 'Anzuzeigende Konten',
|
||||
'active_accounts_only' => 'Nur aktive Konten',
|
||||
'in_active_accounts_only' => 'Nur inaktive Konten',
|
||||
'show_all_accounts' => 'Alle Konten anzeigen',
|
||||
'group_accounts' => 'Konten gruppieren',
|
||||
|
||||
// piggy banks:
|
||||
'event_history' => 'Ereignisverlauf',
|
||||
|
||||
@@ -37,7 +37,7 @@ return [
|
||||
// new user:
|
||||
'bank_name' => 'Name der Bank',
|
||||
'bank_balance' => 'Kontostand',
|
||||
'current_balance' => 'Current balance',
|
||||
'current_balance' => 'Aktueller Kontostand',
|
||||
'savings_balance' => 'Sparguthaben',
|
||||
'credit_card_limit' => 'Kreditkartenlimit',
|
||||
'automatch' => 'Automatisch reagieren',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'Η διεύθυνση IP που σχετίζεται με αυτό το σφάλμα είναι: :ip',
|
||||
'error_url' => 'Το URL είναι: :url',
|
||||
'error_user_agent' => 'User agent: :userAgent',
|
||||
'error_stacktrace' => 'Το πλήρες stacktrace είναι παρακάτω. Αν νομίζετε ότι αυτό είναι ένα σφάλμα στο Firefly III, μπορείτε να προωθήσετε αυτό το μήνυμα στο <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a>. Αυτό μπορεί να βοηθήσει στη διόρθωση του σφάλματος που μόλις αντιμετωπίσατε.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Αν προτιμάτε, μπορείτε επίσης να ανοίξετε ένα νέο ζήτημα στο <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Αν προτιμάτε, μπορείτε επίσης να ανοίξετε ένα νέο ζήτημα στο https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'Το πλήρες stacktrace είναι παρακάτω:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'The IP address related to this error is: :ip',
|
||||
'error_url' => 'URL is: :url',
|
||||
'error_user_agent' => 'User agent: :userAgent',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'If you prefer, you can also open a new issue on <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'If you prefer, you can also open a new issue on https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'The full stacktrace is below:',
|
||||
|
||||
@@ -111,7 +111,7 @@ return [
|
||||
'error_ip' => 'The IP address related to this error is: :ip',
|
||||
'error_url' => 'URL is: :url',
|
||||
'error_user_agent' => 'User agent: :userAgent',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'If you prefer, you can also open a new issue on <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'If you prefer, you can also open a new issue on https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'The full stacktrace is below:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'La dirección IP relacionada con este error es: :ip',
|
||||
'error_url' => 'La URL es: :url',
|
||||
'error_user_agent' => 'Agente de usuario: :userAgent',
|
||||
'error_stacktrace' => 'El stacktrace completo está a continuación. Si cree que esto es un error en Firefly III, puede reenviar este mensaje a <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii. rg</a>. Esto puede ayudar a solucionar el error que acaba de encontrar.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Si prefiere, también puede abrir un nuevo issue en <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Si prefiere, también puedes abrir un nuevo problema en https://github.com/firefly-iiii/firefly-iiii/issues.',
|
||||
'error_stacktrace_below' => 'El stacktrace completo está a continuación:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'Tähän virheeseen liittyvä IP-osoite on: :ip',
|
||||
'error_url' => 'URL on: :url',
|
||||
'error_user_agent' => 'Käyttäjä-agentti: :userAgent',
|
||||
'error_stacktrace' => 'Täydellinen stack trace on alla. Jos tämä on bugi Firefly III:ssa, voit lähettää tämän viestin osoitteeseen <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-ii. rg</a>. Tämä voi auttaa korjaamaan juuri kohtaamasi virheen.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Jos haluat, voit myös avata uuden tiketin <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHubissa</a>.',
|
||||
'error_github_text' => 'Jos haluat, voit myös avata uuden tiketin osoitteessa https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'Täydellinen stack trace:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'L\'adresse IP liée à cette erreur est : :ip',
|
||||
'error_url' => 'L\'URL est : :url',
|
||||
'error_user_agent' => 'User agent : :userAgent',
|
||||
'error_stacktrace' => 'La stacktrace complète se trouve plus bas. Si vous pensez qu\'il s\'agit d\'un bogue dans Firefly III, vous pouvez transmettre ce message à <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a> (en anglais). Cela peut aider à corriger le bogue que vous venez de rencontrer.',
|
||||
'error_stacktrace' => 'La stacktrace complète se trouve plus bas. Si vous pensez qu\'il s\'agit d\'un bogue dans Firefly III, vous pouvez transmettre ce message à <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a> (en anglais). Cela peut aider à corriger le bogue que vous venez de rencontrer.',
|
||||
'error_github_html' => 'Si vous le préférez, vous pouvez également ouvrir un nouveau ticket sur <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a> (en anglais).',
|
||||
'error_github_text' => 'Si vous le préférez, vous pouvez également ouvrir un nouveau ticket sur https://github.com/firefly-ii/firefly-iii/issues (en anglais).',
|
||||
'error_stacktrace_below' => 'La stacktrace complète se trouve ci-dessous :',
|
||||
|
||||
@@ -2402,11 +2402,11 @@ return [
|
||||
// page settings and wizard dialogs
|
||||
|
||||
'page_settings_header' => 'Page settings',
|
||||
'visible_columns' => 'Visible columns',
|
||||
'accounts_to_show' => 'Accounts to show',
|
||||
'active_accounts_only' => 'Active accounts only',
|
||||
'in_active_accounts_only' => 'Inactive accounts only',
|
||||
'show_all_accounts' => 'Show all accounts',
|
||||
'visible_columns' => 'Colonnes visibles',
|
||||
'accounts_to_show' => 'Comptes à afficher',
|
||||
'active_accounts_only' => 'Comptes actifs uniquement',
|
||||
'in_active_accounts_only' => 'Comptes inactifs uniquement',
|
||||
'show_all_accounts' => 'Afficher tous les comptes',
|
||||
'group_accounts' => 'Group accounts',
|
||||
|
||||
// piggy banks:
|
||||
|
||||
@@ -37,7 +37,7 @@ return [
|
||||
// new user:
|
||||
'bank_name' => 'Nom de la banque',
|
||||
'bank_balance' => 'Solde',
|
||||
'current_balance' => 'Current balance',
|
||||
'current_balance' => 'Solde actuel',
|
||||
'savings_balance' => 'Solde de l\'épargne',
|
||||
'credit_card_limit' => 'Limite de carte de crédit',
|
||||
'automatch' => 'Correspondre automatiquement',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'The IP address related to this error is: :ip',
|
||||
'error_url' => 'URL is: :url',
|
||||
'error_user_agent' => 'User agent: :userAgent',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'If you prefer, you can also open a new issue on <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'If you prefer, you can also open a new issue on https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'The full stacktrace is below:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'Alamat IP yang berhubungan dengan kesalahan ini adalah: :ip',
|
||||
'error_url' => 'URL adalah: :url',
|
||||
'error_user_agent' => 'User agent: :userAgent',
|
||||
'error_stacktrace' => 'Jejak tumpukan lengkap ada di bawah. Jika Anda merasa ada kutu di Firefly III, Anda dapat meneruskan pesan ini ke <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a>. Hal ini dapat membantu memperbaiki kutu yang baru saja Anda alami.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Jika Anda mau, Anda juga dapat membuka isu baru di <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Jika Anda mau, Anda juga dapat membuka isu baru di https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'Jejak tumpukan lengkap ada di bawah:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'L\'indirizzo IP relativo a questo errore è: :ip',
|
||||
'error_url' => 'L\'URL è: :url',
|
||||
'error_user_agent' => 'User agent: :userAgent',
|
||||
'error_stacktrace' => 'Lo stacktrace completo è qui sotto. Se pensi che questo sia un bug in Firefly III, puoi inoltrare questo messaggio a <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii. rg</a>. Questo può aiutare a risolvere il bug che hai appena incontrato.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Se preferisci puoi anche aprire una nuova issue su <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Se preferisci puoi anche aprire una nuova issue su https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'Lo stacktrace completo è qui sotto:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'このエラーに関連する IP アドレス: :ip',
|
||||
'error_url' => 'URL: :url',
|
||||
'error_user_agent' => 'ユーザーエージェント: :userAgent',
|
||||
'error_stacktrace' => '完全なスタックトレースは以下の通りです。これがバグだと考えるなら、このメッセージを<a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a>に届けることができます。これは先ほど遭遇したバグの修正に役立ちます。',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'ご希望の場合は、<a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>で新しいissueを作ることもできます。',
|
||||
'error_github_text' => 'ご希望の場合は、https://github.com/fofoflifly-iii/firelify-ii/issuesで新しいissueを作ることもできます。',
|
||||
'error_stacktrace_below' => '完全なスタックトレースは以下の通りです:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => '이 오류와 관련된 IP 주소: :ip',
|
||||
'error_url' => 'URL: :url',
|
||||
'error_user_agent' => '유저 에이전트: :userAgent',
|
||||
'error_stacktrace' => '전체 스택 추적은 다음과 같습니다. Firefly III의 버그라고 생각되면 이 메시지를 <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a> 으로 전달해 주세요. 방금 발생한 버그를 수정하는 데 도움이 될 수 있습니다.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => '원한다면 <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>에 새로운 이슈를 오픈할 수 도 있습니다.',
|
||||
'error_github_text' => '원한다면 https://github.com/firefly-iii/firefly-iii/issues 에 새로운 이슈를 오픈할 수도 있습니다.',
|
||||
'error_stacktrace_below' => '전체 스택 추적은 다음과 같습니다:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'IP-adressen relatert til denne feilen er: :ip',
|
||||
'error_url' => 'URL er: :url',
|
||||
'error_user_agent' => 'Brukeragent: :userAgent',
|
||||
'error_stacktrace' => 'Hele informasjonen er under. Hvis du tror dette er en feil i Firefly III, kan du videresende denne meldingen til <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-ii. rg</a>. Dette kan hjelpe med å rette opp feilen du nettopp har funnet.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Hvis du foretrekker, kan du også åpne et nytt problem på <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Hvis du foretrekker, kan du også åpne et nytt problem på https://github.com/firefly-ii/firefly-ii/issues.',
|
||||
'error_stacktrace_below' => 'Hele informasjonen er:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'Het IP-adres met betrekking tot deze fout is: :ip',
|
||||
'error_url' => 'URL is: :url',
|
||||
'error_user_agent' => 'User agent: :userAgent',
|
||||
'error_stacktrace' => 'De volledige stacktrace staat hieronder. Als je denkt dat dit een bug in Firefly III is, kun je dit bericht doorsturen naar <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii.org</a>. Dit kan helpen om de fout te verhelpen waar je net tegenaan bent gelopen.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Als je wilt, kun je ook een nieuw issue openen op <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Als je wilt, kun je ook een nieuw issue openen op https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'De volledige stacktrace staat hieronder:',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'IP-adressa relatert til denne feilen er: :ip',
|
||||
'error_url' => 'URL er: :url',
|
||||
'error_user_agent' => 'Brukaragent: :userAgent',
|
||||
'error_stacktrace' => 'Hele informasjonen er under. Om du trur dette er ein feil i Firefly III, kan du videresende denne meldinga til <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-ii. rg</a>. Dette kan hjelpa med å rette opp feilen du nettopp har funne.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Om du føretrekk, kan du òg åpne eit nytt problem på <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Om du føretrekk, kan du òg åpne eit nytt problem på https://github.com/firefly-ii/firefly-ii/issues.',
|
||||
'error_stacktrace_below' => 'Hele informasjonen er:',
|
||||
|
||||
@@ -40,7 +40,7 @@ return [
|
||||
'month_js' => 'MMMM YYYY',
|
||||
|
||||
// 'month_and_day' => '%B %e, %Y',
|
||||
'month_and_day_moment_js' => 'MMM D, YYYY',
|
||||
'month_and_day_moment_js' => 'D MMM YYYY',
|
||||
'month_and_day_fns' => 'd MMMM y',
|
||||
'month_and_day_js' => 'D MMMM YYYY',
|
||||
|
||||
@@ -64,7 +64,7 @@ return [
|
||||
// 'date_time' => '%B %e, %Y, @ %T',
|
||||
'date_time_js' => 'D MMMM YYYY [o] HH:mm:ss',
|
||||
'date_time_fns' => 'do MMMM yyyy @ HH:mm:ss',
|
||||
'date_time_fns_short' => 'MMMM do, yyyy @ HH:mm',
|
||||
'date_time_fns_short' => 'D MMMM yyyy [o] HH:mm',
|
||||
|
||||
// 'specific_day' => '%e %B %Y',
|
||||
'specific_day_js' => 'D MMMM YYYY',
|
||||
|
||||
@@ -36,7 +36,7 @@ declare(strict_types=1);
|
||||
return [
|
||||
// common items
|
||||
'greeting' => 'Cześć,',
|
||||
'closing' => 'Jestę robotę',
|
||||
'closing' => 'Bip bip,',
|
||||
'signature' => 'Robot pocztowy Firefly III',
|
||||
'footer_ps' => 'PS: Ta wiadomość została wysłana, ponieważ została wywołana przez żądanie z adresu IP :ipAddress .',
|
||||
|
||||
@@ -138,7 +138,7 @@ return [
|
||||
'error_ip' => 'Adres IP związany z tym błędem to: :ip',
|
||||
'error_url' => 'Adres URL to: :url',
|
||||
'error_user_agent' => 'Agent użytkownika: :userAgent',
|
||||
'error_stacktrace' => 'Pełny opis błędu znajduje się poniżej. Jeśli uważasz, że jest to błąd w Firefly III, możesz przesłać tę wiadomość do <a href="mailto:james@firefly-iii.org?subject=BUG!">james@firefly-iii. rg</a>. To może pomóc naprawić napotkany właśnie błąd.',
|
||||
'error_stacktrace' => 'The full stacktrace is below. If you think this is a bug in Firefly III, you can forward this message to <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_github_html' => 'Jeśli wolisz, możesz również otworzyć nowy problem na <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Jeśli wolisz, możesz również otworzyć nowy problem na https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'Pełny opis błędu znajduje się poniżej:',
|
||||
|
||||
@@ -42,7 +42,7 @@ return [
|
||||
'fatal_error' => 'Wystąpił błąd krytyczny. Sprawdź pliki dziennika w "storage/logs" lub użyj "docker logs -f [container]", aby zobaczyć co się dzieje.',
|
||||
'maintenance_mode' => 'Firefly III jest w trybie konserwacji.',
|
||||
'be_right_back' => 'Zaraz wracam!',
|
||||
'check_back' => 'Firefly III is down for some necessary maintenance. Please check back in a second. If you happen to see this message on the demo site, just wait a few minutes. The database is reset every few hours.',
|
||||
'check_back' => 'Firefly III jest wyłączony na czas koniecznej konserwacji. Sprawdź ponownie za sekundę. Jeśli ta wiadomość pojawiła się na stronie demo, poczekaj kilka minut. Baza danych jest resetowana co kilka godzin.',
|
||||
'error_occurred' => 'Ups! Wystąpił błąd.',
|
||||
'db_error_occurred' => 'Ups! Wystąpił błąd bazy danych.',
|
||||
'error_not_recoverable' => 'Niestety, nie mogliśmy się pozbierać po tym błędzie :(. Firefly III się popsuło. Błąd to:',
|
||||
|
||||
@@ -1203,7 +1203,7 @@ return [
|
||||
'rule_trigger_not_exists' => 'Transakcja nie istnieje',
|
||||
'rule_trigger_not_has_attachments' => 'Transakcja nie ma załączników',
|
||||
'rule_trigger_not_has_any_category' => 'Transakcja nie ma kategorii',
|
||||
'rule_trigger_not_has_any_budget' => 'Transaction has no budget',
|
||||
'rule_trigger_not_has_any_budget' => 'Transakcja bez budżetu',
|
||||
'rule_trigger_not_has_any_bill' => 'Transakcja bez rachunku',
|
||||
'rule_trigger_not_has_any_tag' => 'Transakcja bez tagów',
|
||||
'rule_trigger_not_any_notes' => 'Transakcja bez notatek',
|
||||
@@ -1286,8 +1286,8 @@ return [
|
||||
'rule_action_append_notes_to_descr' => 'Dołącz notatki do opisu',
|
||||
'rule_action_move_descr_to_notes' => 'Zastąp notatki opisem',
|
||||
'rule_action_move_notes_to_descr' => 'Zastąp opis notatkami',
|
||||
'rule_action_set_amount_choice' => 'Set amount to ..',
|
||||
'rule_action_set_amount' => 'Set amount to ":action_value"',
|
||||
'rule_action_set_amount_choice' => 'Ustaw kwotę na ..',
|
||||
'rule_action_set_amount' => 'Ustaw kwotę na ":action_value"',
|
||||
'rule_action_set_destination_to_cash_choice' => 'Ustaw konto docelowe na konto gotówkowe',
|
||||
'rule_action_set_source_to_cash_choice' => 'Ustaw konto źródłowe na konto gotówkowe',
|
||||
'rulegroup_for_bills_title' => 'Grupa reguł dla rachunków',
|
||||
@@ -1421,10 +1421,10 @@ return [
|
||||
'administrations_index_menu' => 'Zarządzanie finansami',
|
||||
'administrations_breadcrumb' => 'Financial administrations',
|
||||
'administrations_page_title' => 'Financial administrations',
|
||||
'administrations_page_sub_title' => 'Overview',
|
||||
'administrations_page_sub_title' => 'Przegląd',
|
||||
'create_administration' => 'Create new administration',
|
||||
'administration_owner' => 'Administration owner: {{email}}',
|
||||
'administration_you' => 'Your role: {{role}}',
|
||||
'administration_you' => 'Twoja rola: {{role}}',
|
||||
'other_users_in_admin' => 'Other users in this administration',
|
||||
'administrations_create_breadcrumb' => 'Create new financial administration',
|
||||
'administrations_page_create_sub_title' => 'Create new financial administration',
|
||||
@@ -1434,19 +1434,19 @@ return [
|
||||
'administrations_page_edit_sub_title' => 'Edit financial administration ":title"',
|
||||
|
||||
// roles
|
||||
'administration_role_owner' => 'Owner',
|
||||
'administration_role_ro' => 'Read-only',
|
||||
'administration_role_mng_trx' => 'Manage transactions',
|
||||
'administration_role_mng_meta' => 'Manage classification and meta-data',
|
||||
'administration_role_mng_budgets' => 'Manage budgets',
|
||||
'administration_role_mng_piggies' => 'Manage piggy banks',
|
||||
'administration_role_mng_subscriptions' => 'Manage subscriptions',
|
||||
'administration_role_mng_rules' => 'Manage rules',
|
||||
'administration_role_mng_recurring' => 'Manage recurring transactions ',
|
||||
'administration_role_owner' => 'Właściciel',
|
||||
'administration_role_ro' => 'Tylko odczyt',
|
||||
'administration_role_mng_trx' => 'Zarządzanie transakcjami',
|
||||
'administration_role_mng_meta' => 'Zarządzanie klasyfikacją i meta-danymi',
|
||||
'administration_role_mng_budgets' => 'Zarządzanie budżetami',
|
||||
'administration_role_mng_piggies' => 'Zarządzanie skarbonkami',
|
||||
'administration_role_mng_subscriptions' => 'Zarządzanie subskrypcjami',
|
||||
'administration_role_mng_rules' => 'Zarządzanie regułami',
|
||||
'administration_role_mng_recurring' => 'Zarządzanie transakcjami cyklicznymi ',
|
||||
'administration_role_mng_webhooks' => 'Manage webhooks',
|
||||
'administration_role_mng_currencies' => 'Manage currencies',
|
||||
'administration_role_view_reports' => 'View reports',
|
||||
'administration_role_full' => 'Full access',
|
||||
'administration_role_mng_currencies' => 'Zarządzanie walutami',
|
||||
'administration_role_view_reports' => 'Przeglądanie raportów',
|
||||
'administration_role_full' => 'Pełny dostęp',
|
||||
|
||||
// profile:
|
||||
'purge_data_title' => 'Wyczyść dane z Firefly III',
|
||||
@@ -1775,7 +1775,7 @@ return [
|
||||
'auto_budget_help' => 'Możesz przeczytać więcej o tej funkcji w pomocy. Kliknij ikonę (?) u góry prawej strony.',
|
||||
'auto_budget_reset_icon' => 'Ten budżet będzie okresowo ustalany',
|
||||
'auto_budget_rollover_icon' => 'Kwota budżetu będzie okresowo rosła',
|
||||
'auto_budget_adjusted_icon' => 'The budget amount will increase periodically and will correct for overspending',
|
||||
'auto_budget_adjusted_icon' => 'Kwota budżetu będzie okresowo wzrastać i korygować się o nadmierne wydatki',
|
||||
'remove_budgeted_amount' => 'Usuń zabudżetowaną kwotę w :currency',
|
||||
|
||||
// bills:
|
||||
@@ -1961,18 +1961,18 @@ return [
|
||||
'interest_calc_quarterly' => 'Kwartalnie',
|
||||
'initial_balance_account' => 'Początkowe saldo konta :account',
|
||||
'list_options' => 'Opcje listy',
|
||||
'account_column_opt_drag_and_drop' => 'Drag and drop',
|
||||
'account_column_opt_active' => 'Active',
|
||||
'account_column_opt_name' => 'Name',
|
||||
'account_column_opt_type' => 'Type',
|
||||
'account_column_opt_liability_type' => 'Liability type',
|
||||
'account_column_opt_drag_and_drop' => 'Przeciągnij i upuść',
|
||||
'account_column_opt_active' => 'Aktywne',
|
||||
'account_column_opt_name' => 'Nazwa',
|
||||
'account_column_opt_type' => 'Rodzaj',
|
||||
'account_column_opt_liability_type' => 'Rodzaj zobowiązania',
|
||||
'account_column_opt_liability_direction' => 'Liability direction',
|
||||
'account_column_opt_liability_interest' => 'Liability interest',
|
||||
'account_column_opt_number' => 'Account number',
|
||||
'account_column_opt_current_balance' => 'Current balance',
|
||||
'account_column_opt_amount_due' => 'Amount due',
|
||||
'account_column_opt_last_activity' => 'Last activity',
|
||||
'account_column_opt_balance_difference' => 'Balance difference',
|
||||
'account_column_opt_liability_interest' => 'Odsetki od zobowiązań',
|
||||
'account_column_opt_number' => 'Numer konta',
|
||||
'account_column_opt_current_balance' => 'Bieżące saldo',
|
||||
'account_column_opt_amount_due' => 'Do zapłaty',
|
||||
'account_column_opt_last_activity' => 'Ostatnia aktywność',
|
||||
'account_column_opt_balance_difference' => 'Różnica salda',
|
||||
'account_column_opt_menu' => 'Menu',
|
||||
|
||||
// categories:
|
||||
@@ -2005,12 +2005,12 @@ return [
|
||||
|
||||
// transactions:
|
||||
'wait_loading_transaction' => 'Poczekaj na załadowanie formularza',
|
||||
'wait_loading_data' => 'Please wait for your information to load...',
|
||||
'wait_attachments' => 'Please wait for the attachments to upload.',
|
||||
'wait_loading_data' => 'Proszę poczekać na załadowanie informacji...',
|
||||
'wait_attachments' => 'Proszę poczekać na przesłanie załączników.',
|
||||
'errors_upload' => 'The upload has failed. Please check your browser console for the error.',
|
||||
'amount_foreign_if' => 'Amount in foreign currency, if any',
|
||||
'amount_destination_account' => 'Amount in the currency of the destination account',
|
||||
'edit_transaction_title' => 'Edit transaction ":description"',
|
||||
'edit_transaction_title' => 'Edytuj transakcję ":description"',
|
||||
'unreconcile' => 'Cofnij uzgodnienie',
|
||||
'update_withdrawal' => 'Modyfikuj wypłatę',
|
||||
'update_deposit' => 'Modyfikuj wpłatę',
|
||||
@@ -2030,7 +2030,7 @@ return [
|
||||
'deleted_transfer' => 'Pomyślnie usunięto transfer ":description"',
|
||||
'deleted_reconciliation' => 'Pomyślnie usunięto transakcję uzgadniania ":description"',
|
||||
'stored_journal' => 'Pomyślnie utworzono nową transakcję ":description"',
|
||||
'stored_journal_js' => 'Successfully created new transaction "{{description}}"',
|
||||
'stored_journal_js' => 'Pomyślnie utworzono nową transakcję "{{description}}"',
|
||||
'stored_journal_no_descr' => 'Pomyślnie utworzono nową transakcję',
|
||||
'updated_journal_no_descr' => 'Pomyślnie zaktualizowano Twoją transakcję',
|
||||
'select_transactions' => 'Wybierz transakcje',
|
||||
@@ -2339,7 +2339,7 @@ return [
|
||||
'description' => 'Opis',
|
||||
'sum_of_period' => 'Suma dla tego okresu',
|
||||
'average_in_period' => 'Średnia dla tego okresu',
|
||||
'no_account_role' => '(no role)',
|
||||
'no_account_role' => '(brak roli)',
|
||||
'account_role_defaultAsset' => 'Domyślne konto aktywów',
|
||||
'account_role_sharedAsset' => 'Współdzielone konto aktywów',
|
||||
'account_role_savingAsset' => 'Konto oszczędnościowe',
|
||||
@@ -2401,12 +2401,12 @@ return [
|
||||
|
||||
// page settings and wizard dialogs
|
||||
|
||||
'page_settings_header' => 'Page settings',
|
||||
'visible_columns' => 'Visible columns',
|
||||
'page_settings_header' => 'Ustawienia strony',
|
||||
'visible_columns' => 'Widoczne kolumny',
|
||||
'accounts_to_show' => 'Accounts to show',
|
||||
'active_accounts_only' => 'Active accounts only',
|
||||
'in_active_accounts_only' => 'Inactive accounts only',
|
||||
'show_all_accounts' => 'Show all accounts',
|
||||
'active_accounts_only' => 'Tylko aktywne konta',
|
||||
'in_active_accounts_only' => 'Tylko nieaktywne konta',
|
||||
'show_all_accounts' => 'Pokaż wszystkie konta',
|
||||
'group_accounts' => 'Group accounts',
|
||||
|
||||
// piggy banks:
|
||||
@@ -2824,7 +2824,7 @@ return [
|
||||
'ale_action_add_to_piggy' => 'Skarbonka',
|
||||
'ale_action_remove_from_piggy' => 'Skarbonka',
|
||||
'ale_action_add_tag' => 'Dodano tag',
|
||||
'ale_action_update_amount' => 'Updated amount',
|
||||
'ale_action_update_amount' => 'Zaktualizowano kwotę',
|
||||
|
||||
// dashboard
|
||||
'enable_auto_convert' => 'Włącz przeliczenie walut',
|
||||
|
||||
@@ -37,7 +37,7 @@ return [
|
||||
// new user:
|
||||
'bank_name' => 'Nazwa banku',
|
||||
'bank_balance' => 'Saldo',
|
||||
'current_balance' => 'Current balance',
|
||||
'current_balance' => 'Bieżące saldo',
|
||||
'savings_balance' => 'Saldo konta oszczędnościowego',
|
||||
'credit_card_limit' => 'Limit karty kredytowej',
|
||||
'automatch' => 'Dopasuj automatycznie',
|
||||
|
||||
@@ -78,7 +78,7 @@ return [
|
||||
'reports_index_intro' => 'Skorzystaj z tych raportów, aby uzyskać szczegółowe informacje o swoich finansach.',
|
||||
'reports_index_inputReportType' => 'Wybierz typ raportu. Sprawdź stronę pomocy, aby zobaczyć, co pokazuje każdy raport.',
|
||||
'reports_index_inputAccountsSelect' => 'Możesz wykluczyć lub uwzględnić konta zasobów według własnego uznania.',
|
||||
'reports_index_inputDateRange' => 'The selected date range is entirely up to you: from one day to 10 years or more.',
|
||||
'reports_index_inputDateRange' => 'Wybrany zakres dat zależy wyłącznie od Ciebie: od jednego dnia do 10 lub więcej lat.',
|
||||
'reports_index_extra-options-box' => 'W zależności od wybranego raportu możesz wybrać dodatkowe filtry i opcje tutaj. Obserwuj to pole, gdy zmieniasz typy raportów.',
|
||||
|
||||
// reports (reports)
|
||||
|
||||
@@ -67,12 +67,12 @@ return [
|
||||
'source' => 'Źródło',
|
||||
'next_expected_match' => 'Następne oczekiwane dopasowanie',
|
||||
'automatch' => 'Auto dopasowanie?',
|
||||
'drag_and_drop' => 'Drag and drop',
|
||||
'number' => 'Account number',
|
||||
'current_balance' => 'Current balance',
|
||||
'last_activity' => 'Last activity',
|
||||
'amount_due' => 'Amount due',
|
||||
'balance_difference' => 'Balance difference',
|
||||
'drag_and_drop' => 'Przeciągnij i upuść',
|
||||
'number' => 'Numer konta',
|
||||
'current_balance' => 'Bieżące saldo',
|
||||
'last_activity' => 'Ostatnia aktywność',
|
||||
'amount_due' => 'Do zapłaty',
|
||||
'balance_difference' => 'Różnica salda',
|
||||
'menu' => 'Menu',
|
||||
|
||||
/*
|
||||
|
||||
@@ -70,5 +70,5 @@ return [
|
||||
'cannot_find_budget' => 'Firefly III nie może znaleźć budżetu ":name"',
|
||||
'cannot_find_category' => 'Firefly III nie może znaleźć kategorii ":name"',
|
||||
'cannot_set_budget' => 'Firefly III nie może ustawić budżetu ":name" dla transakcji typu ":type"',
|
||||
'journal_invalid_amount' => 'Firefly III can\'t set amount ":amount" because it is not a valid number.',
|
||||
'journal_invalid_amount' => 'Firefly III nie może ustawić kwoty ":amount", ponieważ nie jest to prawidłowa liczba.',
|
||||
];
|
||||
|
||||
@@ -45,8 +45,8 @@ return [
|
||||
'invalid_query_currency' => 'Twoje zapytanie zawiera konta, które mają różne ustawienia walutowe, co jest niedozwolone.',
|
||||
'iban' => 'To nie jest prawidłowy IBAN.',
|
||||
'zero_or_more' => 'Wartość nie może być ujemna.',
|
||||
'more_than_zero' => 'The value must be more than zero.',
|
||||
'more_than_zero_correct' => 'The value must be zero or more.',
|
||||
'more_than_zero' => 'Wartość musi być większa niż zero.',
|
||||
'more_than_zero_correct' => 'Wartość musi wynosić zero lub więcej.',
|
||||
'no_asset_account' => 'To nie jest konto aktywów.',
|
||||
'date_or_time' => 'Wartość musi być prawidłową datą lub czasem (ISO 8601).',
|
||||
'source_equals_destination' => 'Konto źródłowe jest równe kontu docelowemu.',
|
||||
@@ -55,11 +55,11 @@ return [
|
||||
'reconciled_forbidden_field' => 'Ta transakcja jest już uzgodniona, nie można zmienić ":field"',
|
||||
'deleted_user' => 'Ze względu na zabezpieczenia nie możesz się zarejestrować używając tego adresu e-mail.',
|
||||
'rule_trigger_value' => 'Ta wartość jest nieprawidłowa dla wybranego wyzwalacza.',
|
||||
'rule_action_expression' => 'Invalid expression. :error',
|
||||
'rule_action_expression' => 'Nieprawidłowe wyrażenie. :error',
|
||||
'rule_action_value' => 'Ta wartość jest nieprawidłowa dla wybranej akcji.',
|
||||
'file_already_attached' => 'Przesłany plik ":name" jest już dołączony do tego obiektu.',
|
||||
'file_attached' => 'Pomyślnie wgrano plik ":name".',
|
||||
'file_zero' => 'The file is zero bytes in size.',
|
||||
'file_zero' => 'Plik ma rozmiar zero bajtów.',
|
||||
'must_exist' => 'Identyfikator w polu :attribute nie istnieje w bazie danych.',
|
||||
'all_accounts_equal' => 'Wszystkie konta w tym polu muszą być takie same.',
|
||||
'group_title_mandatory' => 'Tytuł grupy jest obowiązkowy, gdy istnieje więcej niż jedna transakcja.',
|
||||
@@ -68,7 +68,7 @@ return [
|
||||
'invalid_selection' => 'Twój wybór jest nieprawidłowy.',
|
||||
'belongs_user' => 'Ta wartość jest powiązana z obiektem, który nie istnieje.',
|
||||
'belongs_user_or_user_group' => 'This value is linked to an object that does not seem to exist in your current financial administration.',
|
||||
'no_access_group' => 'The user has no access to this user group.',
|
||||
'no_access_group' => 'Użytkownik nie ma dostępu do tej grupy użytkowników.',
|
||||
'no_accepted_roles_defined' => 'No access roles have been defined for this endpoint, access denied.',
|
||||
'at_least_one_transaction' => 'Wymaga co najmniej jednej transakcji.',
|
||||
'recurring_transaction_id' => 'Wymaga co najmniej jednej transakcji.',
|
||||
@@ -199,7 +199,7 @@ return [
|
||||
*
|
||||
*/
|
||||
|
||||
'secure_password' => 'This is not a secure password. Please try again. For more information, visit https://bit.ly/FF3-password',
|
||||
'secure_password' => 'To hasło nie jest bezpieczne. Proszę spróbować ponownie. Aby uzyskać więcej informacji odwiedź https://bit.ly/FF3-password',
|
||||
'valid_recurrence_rep_type' => 'Nieprawidłowy typ powtórzeń dla cyklicznych transakcji.',
|
||||
'valid_recurrence_rep_moment' => 'Nieprawidłowy moment powtórzenia dla tego typu powtórzenia.',
|
||||
'invalid_account_info' => 'Nieprawidłowe informacje o koncie.',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user