mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-29 06:31:21 +00:00
Compare commits
21 Commits
develop-20
...
develop-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb5d856769 | ||
|
|
04fe5d1fc4 | ||
|
|
45e9d4f8de | ||
|
|
73fdbb6202 | ||
|
|
e49dbefddd | ||
|
|
fc5143337a | ||
|
|
4b3eb6dace | ||
|
|
c741b2a819 | ||
|
|
cebfaa32bf | ||
|
|
d356d39d43 | ||
|
|
7d9f22d3f4 | ||
|
|
c6c8f282e2 | ||
|
|
6a64420721 | ||
|
|
fcde4e2488 | ||
|
|
aa5c4c20e9 | ||
|
|
794e31e487 | ||
|
|
16bf186312 | ||
|
|
45c722e786 | ||
|
|
36d9e5c3fe | ||
|
|
8d614de67f | ||
|
|
d17da670ab |
24
.ci/php-cs-fixer/composer.lock
generated
24
.ci/php-cs-fixer/composer.lock
generated
@@ -160,16 +160,16 @@
|
||||
},
|
||||
{
|
||||
"name": "composer/xdebug-handler",
|
||||
"version": "3.0.4",
|
||||
"version": "3.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/xdebug-handler.git",
|
||||
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255"
|
||||
"reference": "6c1925561632e83d60a44492e0b344cf48ab85ef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||
"reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef",
|
||||
"reference": "6c1925561632e83d60a44492e0b344cf48ab85ef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -206,7 +206,7 @@
|
||||
"support": {
|
||||
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||
"issues": "https://github.com/composer/xdebug-handler/issues",
|
||||
"source": "https://github.com/composer/xdebug-handler/tree/3.0.4"
|
||||
"source": "https://github.com/composer/xdebug-handler/tree/3.0.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -222,20 +222,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-03-26T18:29:49+00:00"
|
||||
"time": "2024-05-06T16:37:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.55.0",
|
||||
"version": "v3.56.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "c9eeacb559bfa0bcc7f778cfb7b42715c83d2c7e"
|
||||
"reference": "69c6168ae8bc96dc656c7f6c7271120a68ae5903"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/c9eeacb559bfa0bcc7f778cfb7b42715c83d2c7e",
|
||||
"reference": "c9eeacb559bfa0bcc7f778cfb7b42715c83d2c7e",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/69c6168ae8bc96dc656c7f6c7271120a68ae5903",
|
||||
"reference": "69c6168ae8bc96dc656c7f6c7271120a68ae5903",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -307,7 +307,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.55.0"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.56.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -315,7 +315,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-06T00:10:15+00:00"
|
||||
"time": "2024-05-10T11:31:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -74,6 +75,7 @@ class IndexController extends Controller
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
40
app/Console/Commands/Correction/CorrectAccountBalance.php
Normal file
40
app/Console/Commands/Correction/CorrectAccountBalance.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Correction;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Support\Models\AccountBalanceCalculator;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
foreach (TransactionJournal::all() as $journal) {
|
||||
Log::debug(sprintf('Recalculating account balances for journal #%d', $journal->id));
|
||||
foreach ($journal->transactions as $transaction) {
|
||||
AccountBalanceCalculator::recalculate($transaction->account, $journal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,22 @@ 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::recalculate($transaction->account, null);
|
||||
if ((float)$transaction->amount > 0) {
|
||||
AccountBalanceCalculator::recalculateByJournal($transaction->transactionJournal);
|
||||
}
|
||||
}
|
||||
|
||||
public function created(Transaction $transaction): void
|
||||
{
|
||||
app('log')->debug('Observe "created" of a transaction.');
|
||||
AccountBalanceCalculator::recalculate($transaction->account, null);
|
||||
if ((float)$transaction->amount > 0) {
|
||||
AccountBalanceCalculator::recalculateByJournal($transaction->transactionJournal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
133
app/Support/Models/AccountBalanceCalculator.php
Normal file
133
app/Support/Models/AccountBalanceCalculator.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?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
|
||||
{
|
||||
public static function recalculate(?Account $account, ?TransactionJournal $transactionJournal): void
|
||||
{
|
||||
// first collect normal amounts (in whatever currency), and set them.
|
||||
|
||||
// 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
|
||||
$query = Transaction::groupBy(['transactions.account_id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id']);
|
||||
$title = 'balance';
|
||||
if (null !== $account) {
|
||||
$query->where('transactions.account_id', $account->id);
|
||||
}
|
||||
if (null !== $transactionJournal) {
|
||||
$query->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id');
|
||||
$query->where('transaction_journals.date', '<=', $transactionJournal->date);
|
||||
$title = 'balance_after_journal';
|
||||
}
|
||||
|
||||
$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::resetAccountBalances($title, $account, $transactionJournal);
|
||||
|
||||
/** @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::getBalance($title, $account, $transactionCurrency, $transactionJournal?->id);
|
||||
$entry->balance = bcadd($entry->balance, $sumAmount);
|
||||
$entry->transaction_journal_id = $transactionJournal?->id;
|
||||
$entry->save();
|
||||
Log::debug(sprintf('Set balance entry "%s" #%d to amount %s', $title, $entry->id, $entry->balance));
|
||||
|
||||
// then do foreign amount, if present:
|
||||
if ($foreignCurrency > 0) {
|
||||
$entry = self::getBalance($title, $account, $foreignCurrency, $transactionJournal?->id);
|
||||
$entry->balance = bcadd($entry->balance, $sumForeignAmount);
|
||||
$entry->transaction_journal_id = $transactionJournal?->id;
|
||||
$entry->save();
|
||||
Log::debug(sprintf('Set balance entry "%s" #%d to amount %s', $title, $entry->id, $entry->balance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function getBalance(string $title, int $account, int $currency, ?int $journal): AccountBalance
|
||||
{
|
||||
$query = AccountBalance::where('title', $title)->where('account_id', $account)->where('transaction_currency_id', $currency);
|
||||
|
||||
if (null !== $journal) {
|
||||
$query->where('transaction_journal_id', $journal);
|
||||
}
|
||||
|
||||
$entry = $query->first();
|
||||
if (null !== $entry) {
|
||||
Log::debug(sprintf('Found account balance "%s" for account #%d and currency #%d: %s', $title, $account, $currency, $entry->balance));
|
||||
|
||||
return $entry;
|
||||
}
|
||||
$entry = new AccountBalance();
|
||||
$entry->title = $title;
|
||||
$entry->account_id = $account;
|
||||
$entry->transaction_currency_id = $currency;
|
||||
$entry->transaction_journal_id = $journal;
|
||||
$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 resetAccountBalances(string $title, ?Account $account, ?TransactionJournal $transactionJournal): void
|
||||
{
|
||||
if (null === $account && null === $transactionJournal) {
|
||||
AccountBalance::whereNotNull('updated_at')->where('title', $title)->update(['balance' => '0']);
|
||||
Log::debug('Set ALL balances to zero.');
|
||||
|
||||
return;
|
||||
}
|
||||
if (null !== $account && null === $transactionJournal) {
|
||||
AccountBalance::where('account_id', $account->id)->where('title', $title)->update(['balance' => '0']);
|
||||
Log::debug(sprintf('Set balances of account #%d to zero.', $account->id));
|
||||
|
||||
return;
|
||||
}
|
||||
AccountBalance::where('account_id', $account->id)->where('transaction_journal_id', $transactionJournal->id)->where('title', $title)->update(['balance' => '0']);
|
||||
Log::debug(sprintf('Set balances of account #%d + journal #%d to zero.', $account->id, $transactionJournal->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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,8 @@ 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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
800
composer.lock
generated
800
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "be35d14f371e7f8bc178ae6f7a615e5c",
|
||||
"content-hash": "64e54540b9a552493f83b9a46ac22b4e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@@ -1674,17 +1674,628 @@
|
||||
"time": "2022-03-31T05:55:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v11.6.0",
|
||||
"name": "laravel-json-api/core",
|
||||
"version": "v4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "e090ee638ebd4ce221d8bad43b49bbf59ea70ae5"
|
||||
"url": "https://github.com/laravel-json-api/core.git",
|
||||
"reference": "5dbf042c69ce02dc0699676d6f3fe1fe9c82ad49"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/e090ee638ebd4ce221d8bad43b49bbf59ea70ae5",
|
||||
"reference": "e090ee638ebd4ce221d8bad43b49bbf59ea70ae5",
|
||||
"url": "https://api.github.com/repos/laravel-json-api/core/zipball/5dbf042c69ce02dc0699676d6f3fe1fe9c82ad49",
|
||||
"reference": "5dbf042c69ce02dc0699676d6f3fe1fe9c82ad49",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/contracts": "^11.0",
|
||||
"illuminate/http": "^11.0",
|
||||
"illuminate/support": "^11.0",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LaravelJsonApi\\Core\\": "src/Core",
|
||||
"LaravelJsonApi\\Contracts\\": "src/Contracts"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cloud Creativity Ltd",
|
||||
"email": "info@cloudcreativity.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Christopher Gammie",
|
||||
"email": "contact@gammie.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Contracts and support classes for Laravel JSON:API packages.",
|
||||
"homepage": "https://github.com/laravel-json-api/core",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"jsonapi",
|
||||
"jsonapi.org",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel-json-api/core/issues",
|
||||
"source": "https://github.com/laravel-json-api/core/tree/v4.0.0"
|
||||
},
|
||||
"time": "2024-03-12T18:36:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-json-api/eloquent",
|
||||
"version": "v4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-json-api/eloquent.git",
|
||||
"reference": "3794011500b045d076c0ec33aff0c470e200ab3d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-json-api/eloquent/zipball/3794011500b045d076c0ec33aff0c470e200ab3d",
|
||||
"reference": "3794011500b045d076c0ec33aff0c470e200ab3d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/database": "^11.0",
|
||||
"illuminate/support": "^11.0",
|
||||
"laravel-json-api/core": "^4.0",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^9.0",
|
||||
"phpunit/phpunit": "^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LaravelJsonApi\\Eloquent\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cloud Creativity Ltd",
|
||||
"email": "info@cloudcreativity.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Christopher Gammie",
|
||||
"email": "contact@gammie.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Serialize Eloquent models as JSON:API resources.",
|
||||
"homepage": "https://github.com/laravel-json-api/eloquent",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"jsonapi",
|
||||
"jsonapi.org",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel-json-api/eloquent/issues",
|
||||
"source": "https://github.com/laravel-json-api/eloquent/tree/v4.0.0"
|
||||
},
|
||||
"time": "2024-03-12T21:05:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-json-api/encoder-neomerx",
|
||||
"version": "v4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-json-api/encoder-neomerx.git",
|
||||
"reference": "032b155f6221c0cd24331f59bfee6d78b26cd291"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-json-api/encoder-neomerx/zipball/032b155f6221c0cd24331f59bfee6d78b26cd291",
|
||||
"reference": "032b155f6221c0cd24331f59bfee6d78b26cd291",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/contracts": "^11.0",
|
||||
"illuminate/support": "^11.0",
|
||||
"laravel-json-api/core": "^4.0",
|
||||
"laravel-json-api/neomerx-json-api": "^5.0.1",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "4.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"LaravelJsonApi\\Encoder\\Neomerx\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LaravelJsonApi\\Encoder\\Neomerx\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cloud Creativity Ltd",
|
||||
"email": "info@cloudcreativity.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Christopher Gammie",
|
||||
"email": "contact@gammie.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Encode JSON:API resources using the neomerx/json-api package.",
|
||||
"homepage": "https://github.com/laravel-json-api/encoder-neomerx",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"jsonapi",
|
||||
"jsonapi.org",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel-json-api/encoder-neomerx/issues",
|
||||
"source": "https://github.com/laravel-json-api/encoder-neomerx/tree/v4.0.0"
|
||||
},
|
||||
"time": "2024-03-14T17:32:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-json-api/exceptions",
|
||||
"version": "v3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-json-api/exceptions.git",
|
||||
"reference": "72b308cd6bb0d99a5ceaa81b1539c193b233eb02"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-json-api/exceptions/zipball/72b308cd6bb0d99a5ceaa81b1539c193b233eb02",
|
||||
"reference": "72b308cd6bb0d99a5ceaa81b1539c193b233eb02",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/contracts": "^11.0",
|
||||
"illuminate/pipeline": "^11.0",
|
||||
"laravel-json-api/core": "^4.0",
|
||||
"laravel-json-api/validation": "^4.0",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel-json-api/testing": "^3.0",
|
||||
"orchestra/testbench": "^9.0",
|
||||
"phpunit/phpunit": "^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LaravelJsonApi\\Exceptions\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cloud Creativity Ltd",
|
||||
"email": "info@cloudcreativity.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Christopher Gammie",
|
||||
"email": "contact@gammie.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "JSON:API exception parsing for Laravel applications.",
|
||||
"homepage": "https://github.com/laravel-json-api/exceptions",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"jsonapi",
|
||||
"jsonapi.org",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel-json-api/exceptions/issues",
|
||||
"source": "https://github.com/laravel-json-api/exceptions/tree/v3.0.0"
|
||||
},
|
||||
"time": "2024-03-12T20:41:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-json-api/laravel",
|
||||
"version": "v4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-json-api/laravel.git",
|
||||
"reference": "013380ff3cadecb75b4adaaf27685b83473615af"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-json-api/laravel/zipball/013380ff3cadecb75b4adaaf27685b83473615af",
|
||||
"reference": "013380ff3cadecb75b4adaaf27685b83473615af",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"laravel-json-api/core": "^4.0",
|
||||
"laravel-json-api/eloquent": "^4.0",
|
||||
"laravel-json-api/encoder-neomerx": "^4.0",
|
||||
"laravel-json-api/exceptions": "^3.0",
|
||||
"laravel-json-api/spec": "^3.0",
|
||||
"laravel-json-api/validation": "^4.0",
|
||||
"laravel/framework": "^11.0",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel-json-api/testing": "^3.0",
|
||||
"orchestra/testbench": "^9.0",
|
||||
"phpunit/phpunit": "^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "4.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"aliases": {
|
||||
"JsonApi": "LaravelJsonApi\\Core\\Facades\\JsonApi",
|
||||
"JsonApiRoute": "LaravelJsonApi\\Laravel\\Facades\\JsonApiRoute"
|
||||
},
|
||||
"providers": [
|
||||
"LaravelJsonApi\\Laravel\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LaravelJsonApi\\Laravel\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cloud Creativity Ltd",
|
||||
"email": "info@cloudcreativity.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Christopher Gammie",
|
||||
"email": "contact@gammie.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "JSON:API for Laravel applications.",
|
||||
"homepage": "https://github.com/laravel-json-api/laravel",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"jsonapi",
|
||||
"jsonapi.org",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel-json-api/laravel/issues",
|
||||
"source": "https://github.com/laravel-json-api/laravel/tree/v4.0.0"
|
||||
},
|
||||
"time": "2024-03-14T18:09:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-json-api/neomerx-json-api",
|
||||
"version": "v5.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-json-api/neomerx-json-api.git",
|
||||
"reference": "00841feae83ab95f4490c6f2086f02f298293381"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-json-api/neomerx-json-api/zipball/00841feae83ab95f4490c6f2086f02f298293381",
|
||||
"reference": "00841feae83ab95f4490c6f2086f02f298293381",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.4|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.17",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"phpmd/phpmd": "^2.11.1",
|
||||
"phpunit/phpunit": "^9.5.10",
|
||||
"scrutinizer/ocular": "^1.8",
|
||||
"squizlabs/php_codesniffer": "^3.6.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "5.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/I18n/format.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Neomerx\\JsonApi\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "neomerx",
|
||||
"email": "info@neomerx.com"
|
||||
},
|
||||
{
|
||||
"name": "Christopher Gammie",
|
||||
"email": "contact@gammie.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Framework agnostic JSON API (jsonapi.org) implementation",
|
||||
"homepage": "https://github.com/neomerx/json-api",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"api",
|
||||
"json",
|
||||
"jsonapi",
|
||||
"jsonapi.org",
|
||||
"neomerx"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/neomerx/json-api/issues",
|
||||
"source": "https://github.com/laravel-json-api/neomerx-json-api/tree/v5.0.2"
|
||||
},
|
||||
"time": "2023-05-29T14:50:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-json-api/non-eloquent",
|
||||
"version": "v4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-json-api/non-eloquent.git",
|
||||
"reference": "ecc3da0630e92b285a953c4793f21bbdd7cc66dd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-json-api/non-eloquent/zipball/ecc3da0630e92b285a953c4793f21bbdd7cc66dd",
|
||||
"reference": "ecc3da0630e92b285a953c4793f21bbdd7cc66dd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"laravel-json-api/core": "^4.0",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^9.0",
|
||||
"phpunit/phpunit": "^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LaravelJsonApi\\NonEloquent\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cloud Creativity Ltd",
|
||||
"email": "info@cloudcreativity.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Christopher Gammie",
|
||||
"email": "contact@gammie.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Construct JSON:API resources for non-Eloquent classes.",
|
||||
"homepage": "https://github.com/laravel-json-api/non-eloquent",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"jsonapi",
|
||||
"jsonapi.org",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel-json-api/non-eloquent/issues",
|
||||
"source": "https://github.com/laravel-json-api/non-eloquent/tree/v4.0.0"
|
||||
},
|
||||
"time": "2024-03-14T17:57:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-json-api/spec",
|
||||
"version": "v3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-json-api/spec.git",
|
||||
"reference": "7f0972b3ed742779daf49662c7f8cca03582a727"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-json-api/spec/zipball/7f0972b3ed742779daf49662c7f8cca03582a727",
|
||||
"reference": "7f0972b3ed742779daf49662c7f8cca03582a727",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/contracts": "^11.0",
|
||||
"illuminate/pipeline": "^11.0",
|
||||
"illuminate/support": "^11.0",
|
||||
"laravel-json-api/core": "^4.0",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^9.0",
|
||||
"phpunit/phpunit": "^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "3.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"LaravelJsonApi\\Spec\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LaravelJsonApi\\Spec\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cloud Creativity Ltd",
|
||||
"email": "info@cloudcreativity.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Christopher Gammie",
|
||||
"email": "contact@gammie.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Validate JSON documents for compliance with the JSON:API specification.",
|
||||
"homepage": "https://github.com/laravel-json-api/spec",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"jsonapi",
|
||||
"jsonapi.org",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel-json-api/spec/issues",
|
||||
"source": "https://github.com/laravel-json-api/spec/tree/v3.0.0"
|
||||
},
|
||||
"time": "2024-03-14T17:46:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-json-api/validation",
|
||||
"version": "v4.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-json-api/validation.git",
|
||||
"reference": "9004657962e5c4ea0c833c96c6d2bbcca60876b7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-json-api/validation/zipball/9004657962e5c4ea0c833c96c6d2bbcca60876b7",
|
||||
"reference": "9004657962e5c4ea0c833c96c6d2bbcca60876b7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/contracts": "^11.0",
|
||||
"illuminate/support": "^11.0",
|
||||
"laravel-json-api/core": "^4.0",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^9.0",
|
||||
"phpunit/phpunit": "^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "4.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"LaravelJsonApi\\Validation\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LaravelJsonApi\\Validation\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cloud Creativity Ltd",
|
||||
"email": "info@cloudcreativity.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Christopher Gammie",
|
||||
"email": "contact@gammie.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Laravel validation for JSON:API resources.",
|
||||
"homepage": "https://github.com/laravel-json-api/validation",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"jsonapi",
|
||||
"jsonapi.org",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel-json-api/validation/issues",
|
||||
"source": "https://github.com/laravel-json-api/validation/tree/v4.1.0"
|
||||
},
|
||||
"time": "2024-03-23T11:26:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v11.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "e5ac72f513f635f208024aa76b8a04efc1b47f93"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/e5ac72f513f635f208024aa76b8a04efc1b47f93",
|
||||
"reference": "e5ac72f513f635f208024aa76b8a04efc1b47f93",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1876,7 +2487,7 @@
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2024-04-30T13:30:08+00:00"
|
||||
"time": "2024-05-07T13:41:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/passport",
|
||||
@@ -3889,16 +4500,16 @@
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v2.6.3",
|
||||
"version": "v2.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/constant_time_encoding.git",
|
||||
"reference": "58c3f47f650c94ec05a151692652a868995d2938"
|
||||
"reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938",
|
||||
"reference": "58c3f47f650c94ec05a151692652a868995d2938",
|
||||
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/52a0d99e69f56b9ec27ace92ba56897fe6993105",
|
||||
"reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3952,7 +4563,7 @@
|
||||
"issues": "https://github.com/paragonie/constant_time_encoding/issues",
|
||||
"source": "https://github.com/paragonie/constant_time_encoding"
|
||||
},
|
||||
"time": "2022-06-14T06:56:20+00:00"
|
||||
"time": "2024-05-08T12:18:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
@@ -4685,20 +5296,20 @@
|
||||
},
|
||||
{
|
||||
"name": "psr/http-factory",
|
||||
"version": "1.0.2",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-factory.git",
|
||||
"reference": "e616d01114759c4c489f93b099585439f795fe35"
|
||||
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35",
|
||||
"reference": "e616d01114759c4c489f93b099585439f795fe35",
|
||||
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
|
||||
"reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"php": ">=7.1",
|
||||
"psr/http-message": "^1.0 || ^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
@@ -4722,7 +5333,7 @@
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interfaces for PSR-7 HTTP message factories",
|
||||
"description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
|
||||
"keywords": [
|
||||
"factory",
|
||||
"http",
|
||||
@@ -4734,9 +5345,9 @@
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-factory/tree/1.0.2"
|
||||
"source": "https://github.com/php-fig/http-factory"
|
||||
},
|
||||
"time": "2023-04-10T20:10:41+00:00"
|
||||
"time": "2024-04-15T12:06:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
@@ -9137,6 +9748,64 @@
|
||||
},
|
||||
"time": "2023-06-14T05:06:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "cloudcreativity/json-api-testing",
|
||||
"version": "v6.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cloudcreativity/json-api-testing.git",
|
||||
"reference": "7634cd00e6e493fb7b6e4cc5056153cfe08933a5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cloudcreativity/json-api-testing/zipball/7634cd00e6e493fb7b6e4cc5056153cfe08933a5",
|
||||
"reference": "7634cd00e6e493fb7b6e4cc5056153cfe08933a5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/contracts": "^10.0|^11.0",
|
||||
"illuminate/support": "^10.0|^11.0",
|
||||
"php": "^8.2",
|
||||
"phpunit/phpunit": "^10.5|^11.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "6.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"CloudCreativity\\JsonApi\\Testing\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cloud Creativity Ltd",
|
||||
"email": "info@cloudcreativity.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "PHPUnit test helpers to check JSON API documents.",
|
||||
"homepage": "https://github.com/cloudcreativity/json-api",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"api",
|
||||
"cloudcreativity",
|
||||
"json",
|
||||
"jsonapi",
|
||||
"jsonapi.org"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/cloudcreativity/json-api/issues",
|
||||
"source": "https://github.com/cloudcreativity/json-api-testing/tree/v6.0.0"
|
||||
},
|
||||
"time": "2024-03-12T20:19:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/class-map-generator",
|
||||
"version": "1.1.1",
|
||||
@@ -9516,16 +10185,16 @@
|
||||
},
|
||||
{
|
||||
"name": "larastan/larastan",
|
||||
"version": "v2.9.5",
|
||||
"version": "v2.9.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/larastan/larastan.git",
|
||||
"reference": "101f1a4470f87326f4d3995411d28679d8800abe"
|
||||
"reference": "93d5b95d2e29cdb8203363d44abfdbc0bc7ef57f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/larastan/larastan/zipball/101f1a4470f87326f4d3995411d28679d8800abe",
|
||||
"reference": "101f1a4470f87326f4d3995411d28679d8800abe",
|
||||
"url": "https://api.github.com/repos/larastan/larastan/zipball/93d5b95d2e29cdb8203363d44abfdbc0bc7ef57f",
|
||||
"reference": "93d5b95d2e29cdb8203363d44abfdbc0bc7ef57f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9594,7 +10263,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/larastan/larastan/issues",
|
||||
"source": "https://github.com/larastan/larastan/tree/v2.9.5"
|
||||
"source": "https://github.com/larastan/larastan/tree/v2.9.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9614,7 +10283,72 @@
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2024-04-16T19:13:34+00:00"
|
||||
"time": "2024-05-09T11:53:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-json-api/testing",
|
||||
"version": "v3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-json-api/testing.git",
|
||||
"reference": "1ada998d2087479351e01dd22ca13a00a96b4118"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-json-api/testing/zipball/1ada998d2087479351e01dd22ca13a00a96b4118",
|
||||
"reference": "1ada998d2087479351e01dd22ca13a00a96b4118",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"cloudcreativity/json-api-testing": "^6.0",
|
||||
"ext-json": "*",
|
||||
"illuminate/http": "^11.0",
|
||||
"illuminate/support": "^11.0",
|
||||
"illuminate/testing": "^11.0",
|
||||
"php": "^8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/framework": "^11.0",
|
||||
"phpunit/phpunit": "^10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LaravelJsonApi\\Testing\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cloud Creativity Ltd",
|
||||
"email": "info@cloudcreativity.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Christopher Gammie",
|
||||
"email": "contact@gammie.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Test helpers for JSON:API compliant APIs.",
|
||||
"homepage": "https://github.com/laravel-json-api/testing",
|
||||
"keywords": [
|
||||
"JSON-API",
|
||||
"jsonapi",
|
||||
"jsonapi.org",
|
||||
"laravel"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel-json-api/testing/issues",
|
||||
"source": "https://github.com/laravel-json-api/testing/tree/v3.0.0"
|
||||
},
|
||||
"time": "2024-03-12T20:30:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maximebf/debugbar",
|
||||
@@ -10247,16 +10981,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpdoc-parser",
|
||||
"version": "1.28.0",
|
||||
"version": "1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||
"reference": "cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb"
|
||||
"reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb",
|
||||
"reference": "cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/536889f2b340489d328f5ffb7b02bb6b183ddedc",
|
||||
"reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -10288,9 +11022,9 @@
|
||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.28.0"
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.0"
|
||||
},
|
||||
"time": "2024-04-03T18:51:33+00:00"
|
||||
"time": "2024-05-06T12:04:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
|
||||
@@ -117,7 +117,7 @@ return [
|
||||
'expression_engine' => false,
|
||||
// see cer.php for exchange rates feature flag.
|
||||
],
|
||||
'version' => 'develop/2024-05-06',
|
||||
'version' => 'develop/2024-05-13',
|
||||
'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');
|
||||
}
|
||||
};
|
||||
117
package-lock.json
generated
117
package-lock.json
generated
@@ -2847,9 +2847,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.12.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz",
|
||||
"integrity": "sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==",
|
||||
"version": "20.12.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.11.tgz",
|
||||
"integrity": "sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
@@ -2943,39 +2943,39 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.4.26",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.26.tgz",
|
||||
"integrity": "sha512-N9Vil6Hvw7NaiyFUFBPXrAyETIGlQ8KcFMkyk6hW1Cl6NvoqvP+Y8p1Eqvx+UdqsnrnI9+HMUEJegzia3mhXmQ==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz",
|
||||
"integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.24.4",
|
||||
"@vue/shared": "3.4.26",
|
||||
"@vue/shared": "3.4.27",
|
||||
"entities": "^4.5.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-dom": {
|
||||
"version": "3.4.26",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.26.tgz",
|
||||
"integrity": "sha512-4CWbR5vR9fMg23YqFOhr6t6WB1Fjt62d6xdFPyj8pxrYub7d+OgZaObMsoxaF9yBUHPMiPFK303v61PwAuGvZA==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz",
|
||||
"integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.4.26",
|
||||
"@vue/shared": "3.4.26"
|
||||
"@vue/compiler-core": "3.4.27",
|
||||
"@vue/shared": "3.4.27"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc": {
|
||||
"version": "3.4.26",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.26.tgz",
|
||||
"integrity": "sha512-It1dp+FAOCgluYSVYlDn5DtZBxk1NCiJJfu2mlQqa/b+k8GL6NG/3/zRbJnHdhV2VhxFghaDq5L4K+1dakW6cw==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz",
|
||||
"integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.24.4",
|
||||
"@vue/compiler-core": "3.4.26",
|
||||
"@vue/compiler-dom": "3.4.26",
|
||||
"@vue/compiler-ssr": "3.4.26",
|
||||
"@vue/shared": "3.4.26",
|
||||
"@vue/compiler-core": "3.4.27",
|
||||
"@vue/compiler-dom": "3.4.27",
|
||||
"@vue/compiler-ssr": "3.4.27",
|
||||
"@vue/shared": "3.4.27",
|
||||
"estree-walker": "^2.0.2",
|
||||
"magic-string": "^0.30.10",
|
||||
"postcss": "^8.4.38",
|
||||
@@ -2983,13 +2983,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.4.26",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.26.tgz",
|
||||
"integrity": "sha512-FNwLfk7LlEPRY/g+nw2VqiDKcnDTVdCfBREekF8X74cPLiWHUX6oldktf/Vx28yh4STNy7t+/yuLoMBBF7YDiQ==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz",
|
||||
"integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.4.26",
|
||||
"@vue/shared": "3.4.26"
|
||||
"@vue/compiler-dom": "3.4.27",
|
||||
"@vue/shared": "3.4.27"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/component-compiler-utils": {
|
||||
@@ -3064,9 +3064,9 @@
|
||||
"integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA=="
|
||||
},
|
||||
"node_modules/@vue/shared": {
|
||||
"version": "3.4.26",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.26.tgz",
|
||||
"integrity": "sha512-Fg4zwR0GNnjzodMt3KRy2AWGMKQXByl56+4HjN87soxLNU9P5xcJkstAlIeEF3cU6UYOzmJl1tV0dVPGIljCnQ==",
|
||||
"version": "3.4.27",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
|
||||
"integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@webassemblyjs/ast": {
|
||||
@@ -4020,9 +4020,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001616",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001616.tgz",
|
||||
"integrity": "sha512-RHVYKov7IcdNjVHJFNY/78RdG4oGVjbayxv8u5IO74Wv7Hlq4PnJE6mo/OjFijjVFNy5ijnCt6H3IIo4t+wfEw==",
|
||||
"version": "1.0.30001617",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001617.tgz",
|
||||
"integrity": "sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -4163,9 +4163,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cli-table3": {
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz",
|
||||
"integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==",
|
||||
"version": "0.6.5",
|
||||
"resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz",
|
||||
"integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0"
|
||||
@@ -5095,9 +5095,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.756",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.756.tgz",
|
||||
"integrity": "sha512-RJKZ9+vEBMeiPAvKNWyZjuYyUqMndcP1f335oHqn3BEQbs2NFtVrnK5+6Xg5wSM9TknNNpWghGDUCKGYF+xWXw==",
|
||||
"version": "1.4.763",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.763.tgz",
|
||||
"integrity": "sha512-k4J8NrtJ9QrvHLRo8Q18OncqBCB7tIUyqxRcJnlonQ0ioHKYB988GcDFF3ZePmnb8eHEopDs/wPHR/iGAFgoUQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/elliptic": {
|
||||
@@ -5146,9 +5146,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.16.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz",
|
||||
"integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==",
|
||||
"version": "5.16.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz",
|
||||
"integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
@@ -6275,9 +6275,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/i18next": {
|
||||
"version": "23.11.3",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.3.tgz",
|
||||
"integrity": "sha512-Pq/aSKowir7JM0rj+Wa23Kb6KKDUGno/HjG+wRQu0PxoTbpQ4N89MAT0rFGvXmLkRLNMb1BbBOKGozl01dabzg==",
|
||||
"version": "23.11.4",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.4.tgz",
|
||||
"integrity": "sha512-CCUjtd5TfaCl+mLUzAA0uPSN+AVn4fP/kWCYt/hocPUwusTpMVczdrRyOBUwk6N05iH40qiKx6q1DoNJtBIwdg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -9074,9 +9074,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.76.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.76.0.tgz",
|
||||
"integrity": "sha512-nc3LeqvF2FNW5xGF1zxZifdW3ffIz5aBb7I7tSvOoNu7z1RQ6pFt9MBuiPtjgaI62YWrM/txjWlOCFiGtf2xpw==",
|
||||
"version": "1.77.1",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.77.1.tgz",
|
||||
"integrity": "sha512-OMEyfirt9XEfyvocduUIOlUSkWOXS/LAt6oblR/ISXCTukyavjex+zQNm51pPCOiFKY1QpWvEH1EeCkgyV3I6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
@@ -9128,13 +9128,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
@@ -9142,24 +9139,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/semver/node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/semver/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/send": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"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"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"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"
|
||||
|
||||
@@ -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": "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": {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -138,7 +138,8 @@ return [
|
||||
'error_ip' => 'O endereço de IP associado a este erro é: :ip',
|
||||
'error_url' => 'O URL é: :url',
|
||||
'error_user_agent' => 'Agente de utilizador: :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=I%20found%20a%20bug!">james@firefly-iii.org</a>. This can help fix the bug you just encountered.',
|
||||
'error_stacktrace' => 'O stacktrace completo encontra-se abaixo. Se julga ser um erro no Firefly III, pode reencaminhar este email para <a href="mailto:james@firefly-iii.org?subject=I%20found%20a%20bug!">james@firefly-iii.org</a>.
|
||||
Isto pode ajudar a corrigir o erro que acabou de encontrar.',
|
||||
'error_github_html' => 'Se preferir, pode também abrir uma nova questão no <a href="https://github.com/firefly-iii/firefly-iii/issues">GitHub</a>.',
|
||||
'error_github_text' => 'Se preferir, pode também abrir uma nova questão em https://github.com/firefly-iii/firefly-iii/issues.',
|
||||
'error_stacktrace_below' => 'O rastreamento da pilha completo é:',
|
||||
|
||||
@@ -42,7 +42,7 @@ return [
|
||||
'fatal_error' => 'Aconteceu um erro fatal. Por favor, verifique os ficheiros de log em "storage/logs" ou use "docker logs -f [container]" para verificar o que se passa.',
|
||||
'maintenance_mode' => 'O Firefly III está em modo de manutenção.',
|
||||
'be_right_back' => 'Volto já!',
|
||||
'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 encontra-se desligado para alguma manutenção necessária. Volte a tentar daqui a uns segundos. Se acontecer de ver esta mensagem no site de demonstração, espere alguns minutos. A base de dados é reiniciada a cada algumas horas.',
|
||||
'error_occurred' => 'Oops! Ocorreu um erro.',
|
||||
'db_error_occurred' => 'Oops! Ocorreu um erro na base de dados.',
|
||||
'error_not_recoverable' => 'Infelizmente, este erro não era recuperável :(. Firefly III avariou. O erro é:',
|
||||
|
||||
@@ -37,7 +37,7 @@ return [
|
||||
// new user:
|
||||
'bank_name' => 'Nome do banco',
|
||||
'bank_balance' => 'Saldo',
|
||||
'current_balance' => 'Current balance',
|
||||
'current_balance' => 'Saldo atual',
|
||||
'savings_balance' => 'Saldo nas poupanças',
|
||||
'credit_card_limit' => 'Limite do cartão de crédito',
|
||||
'automatch' => 'Corresponder automaticamente',
|
||||
|
||||
@@ -67,12 +67,12 @@ return [
|
||||
'source' => 'Origem',
|
||||
'next_expected_match' => 'Próxima correspondência esperada',
|
||||
'automatch' => 'Auto correspondência?',
|
||||
'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' => 'Arrastar e soltar',
|
||||
'number' => 'Número de conta',
|
||||
'current_balance' => 'Saldo atual',
|
||||
'last_activity' => 'Última atividade',
|
||||
'amount_due' => 'Valor a pagar',
|
||||
'balance_difference' => 'Diferença de saldo',
|
||||
'menu' => 'Menu',
|
||||
|
||||
/*
|
||||
|
||||
@@ -27,7 +27,7 @@ return [
|
||||
'find_or_create_tag_failed' => 'Não foi possível encontrar ou criar a etiqueta ":tag"',
|
||||
'tag_already_added' => 'A etiqueta ":tag" já está vinculada a esta transação',
|
||||
'inspect_transaction' => 'Inspecionar transação ":title" @ Firefly III',
|
||||
'inspect_rule' => 'Inspect rule ":title" @ Firefly III',
|
||||
'inspect_rule' => 'Inspecionar regra ":title" @ Firefly III',
|
||||
'journal_other_user' => 'Esta transação não pertence ao utilizador',
|
||||
'no_such_journal' => 'Esta transação não existe',
|
||||
'journal_already_no_budget' => 'Esta transação não tem orçamento, então não pode ser removido',
|
||||
@@ -47,28 +47,28 @@ return [
|
||||
'unsupported_transaction_type_transfer' => 'Firefly III não pode converter um ":type" para uma transferência',
|
||||
'already_has_source_asset' => 'Esta transação já tem ":name" como a conta do ativo de origem',
|
||||
'already_has_destination_asset' => 'Esta transação já tem ":name" como a conta de ativo de destino',
|
||||
'already_has_destination' => 'This transaction already has ":name" as the destination account',
|
||||
'already_has_source' => 'This transaction already has ":name" as the source account',
|
||||
'already_linked_to_subscription' => 'The transaction is already linked to subscription ":name"',
|
||||
'already_linked_to_category' => 'The transaction is already linked to category ":name"',
|
||||
'already_linked_to_budget' => 'The transaction is already linked to budget ":name"',
|
||||
'cannot_find_subscription' => 'Firefly III can\'t find subscription ":name"',
|
||||
'no_notes_to_move' => 'The transaction has no notes to move to the description field',
|
||||
'no_tags_to_remove' => 'The transaction has no tags to remove',
|
||||
'not_withdrawal' => 'The transaction is not a withdrawal',
|
||||
'not_deposit' => 'The transaction is not a deposit',
|
||||
'cannot_find_tag' => 'Firefly III can\'t find tag ":tag"',
|
||||
'cannot_find_asset' => 'Firefly III can\'t find asset account ":name"',
|
||||
'cannot_find_accounts' => 'Firefly III can\'t find the source or destination account',
|
||||
'cannot_find_source_transaction' => 'Firefly III can\'t find the source transaction',
|
||||
'cannot_find_destination_transaction' => 'Firefly III can\'t find the destination transaction',
|
||||
'cannot_find_source_transaction_account' => 'Firefly III can\'t find the source transaction account',
|
||||
'cannot_find_destination_transaction_account' => 'Firefly III can\'t find the destination transaction account',
|
||||
'cannot_find_piggy' => 'Firefly III can\'t find a piggy bank named ":name"',
|
||||
'no_link_piggy' => 'This transaction\'s accounts are not linked to the piggy bank, so no action will be taken',
|
||||
'cannot_unlink_tag' => 'Tag ":tag" isn\'t linked to this transaction',
|
||||
'cannot_find_budget' => 'Firefly III can\'t find budget ":name"',
|
||||
'cannot_find_category' => 'Firefly III can\'t find category ":name"',
|
||||
'cannot_set_budget' => 'Firefly III can\'t set budget ":name" to a transaction of type ":type"',
|
||||
'journal_invalid_amount' => 'Firefly III can\'t set amount ":amount" because it is not a valid number.',
|
||||
'already_has_destination' => 'Esta transação já tem ":name" como conta de destino',
|
||||
'already_has_source' => 'Esta transação já tem ":name" como a conta de origem',
|
||||
'already_linked_to_subscription' => 'A transação já está vinculada à subscrição ":name"',
|
||||
'already_linked_to_category' => 'A transação já está vinculada à categoria ":name"',
|
||||
'already_linked_to_budget' => 'A transação já está vinculada ao orçamento ":name"',
|
||||
'cannot_find_subscription' => 'Firefly III não consegue encontrar a subscrição ":name"',
|
||||
'no_notes_to_move' => 'A transação não tem notas para mover para o campo de descrição',
|
||||
'no_tags_to_remove' => 'A transação não tem etiquetas para remover',
|
||||
'not_withdrawal' => 'A transação não é um levantamento',
|
||||
'not_deposit' => 'A transação não é um depósito',
|
||||
'cannot_find_tag' => 'Firefly III não consegue encontrar a etiqueta ":tag"',
|
||||
'cannot_find_asset' => 'Firefly III não consegue encontrar a conta de ativos ":name"',
|
||||
'cannot_find_accounts' => 'Firefly III não conseguiu encontrar a conta de origem ou de destino',
|
||||
'cannot_find_source_transaction' => 'Firefly III não conseguiu encontrar a transação de origem',
|
||||
'cannot_find_destination_transaction' => 'Firefly III não conseguiu encontrar a transação de destino',
|
||||
'cannot_find_source_transaction_account' => 'Firefly III não conseguiu encontrar a conta de origem da transação',
|
||||
'cannot_find_destination_transaction_account' => 'Firefly III não conseguiu encontrar a conta de destino da transação',
|
||||
'cannot_find_piggy' => 'Firefly III não conseguiu encontrar nenhum mealheiro chamado ":name"',
|
||||
'no_link_piggy' => 'As contas desta transação não estão ligadas ao mealheiro, logo nenhuma ação será tomada',
|
||||
'cannot_unlink_tag' => 'Etiqueta ":tag" não está vinculada a esta transação',
|
||||
'cannot_find_budget' => 'Firefly III não consegue encontrar o orçamento ":name"',
|
||||
'cannot_find_category' => 'Firefly III não consegue encontrar a categoria ":name"',
|
||||
'cannot_set_budget' => 'Firefly III não pode definir o orçamento ":name" para uma transação do tipo ":type"',
|
||||
'journal_invalid_amount' => 'Firefly III não pode definir a quantidade ":amount" porque não é um número válido.',
|
||||
];
|
||||
|
||||
@@ -2402,13 +2402,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' => '页面设置',
|
||||
'visible_columns' => '可见列',
|
||||
'accounts_to_show' => '显示账户',
|
||||
'active_accounts_only' => '仅活动账户',
|
||||
'in_active_accounts_only' => '仅非活动账户',
|
||||
'show_all_accounts' => '显示全部账户',
|
||||
'group_accounts' => '群组账户',
|
||||
|
||||
// piggy banks:
|
||||
'event_history' => '事件历史',
|
||||
|
||||
@@ -37,7 +37,7 @@ return [
|
||||
// new user:
|
||||
'bank_name' => '银行名称',
|
||||
'bank_balance' => '余额',
|
||||
'current_balance' => 'Current balance',
|
||||
'current_balance' => '当前余额',
|
||||
'savings_balance' => '储蓄余额',
|
||||
'credit_card_limit' => '信用卡额度',
|
||||
'automatch' => '自动匹配',
|
||||
|
||||
@@ -22,6 +22,45 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use FireflyIII\Http\Controllers\Api\V3\Controllers\AccountController;
|
||||
use LaravelJsonApi\Laravel\Facades\JsonApiRoute;
|
||||
use LaravelJsonApi\Laravel\Http\Controllers\JsonApiController;
|
||||
use LaravelJsonApi\Laravel\Routing\ActionRegistrar;
|
||||
use LaravelJsonApi\Laravel\Routing\Relationships;
|
||||
use LaravelJsonApi\Laravel\Routing\ResourceRegistrar;
|
||||
|
||||
// V2 auto complete controller(s)
|
||||
Route::group(
|
||||
[
|
||||
'namespace' => 'FireflyIII\Api\V2\Controllers\Autocomplete',
|
||||
'prefix' => 'v2/autocomplete',
|
||||
'as' => 'api.v2.autocomplete.',
|
||||
],
|
||||
static function (): void {
|
||||
// Auto complete routes
|
||||
Route::get('accounts', ['uses' => 'AccountController@accounts', 'as' => 'accounts']);
|
||||
Route::get('transaction-descriptions', ['uses' => 'TransactionController@transactionDescriptions', 'as' => 'transaction-descriptions']);
|
||||
Route::get('categories', ['uses' => 'CategoryController@categories', 'as' => 'categories']);
|
||||
Route::get('tags', ['uses' => 'TagController@tags', 'as' => 'tags']);
|
||||
}
|
||||
);
|
||||
|
||||
// JsonApiRoute::server('v3')
|
||||
// ->prefix('v3')
|
||||
// ->resources(function (ResourceRegistrar $server) {
|
||||
// $server->resource('accounts', AccountController::class)->readOnly()->relationships(function (Relationships $relations) {
|
||||
// $relations->hasOne('user')->readOnly();
|
||||
// //$relations->hasMany('account_balances')->readOnly();
|
||||
// })
|
||||
// ->actions(function (ActionRegistrar $actions) {
|
||||
// $actions->withId()->get('account-balances', 'readAccountBalances'); // non-eloquent pseudo relation
|
||||
// });
|
||||
// $server->resource('users', JsonApiController::class)->readOnly()->relationships(function (Relationships $relations) {
|
||||
// $relations->hasMany('accounts')->readOnly();
|
||||
// });
|
||||
// $server->resource('account-balances', JsonApiController::class);
|
||||
// });
|
||||
|
||||
// V2 API route for Summary boxes
|
||||
// BASIC
|
||||
Route::group(
|
||||
@@ -54,20 +93,6 @@ Route::group(
|
||||
);
|
||||
|
||||
// V2 API routes for auto complete
|
||||
Route::group(
|
||||
[
|
||||
'namespace' => 'FireflyIII\Api\V2\Controllers\Autocomplete',
|
||||
'prefix' => 'v2/autocomplete',
|
||||
'as' => 'api.v2.autocomplete.',
|
||||
],
|
||||
static function (): void {
|
||||
// Auto complete routes
|
||||
Route::get('accounts', ['uses' => 'AccountController@accounts', 'as' => 'accounts']);
|
||||
Route::get('transaction-descriptions', ['uses' => 'TransactionController@transactionDescriptions', 'as' => 'transaction-descriptions']);
|
||||
Route::get('categories', ['uses' => 'CategoryController@categories', 'as' => 'categories']);
|
||||
Route::get('tags', ['uses' => 'TagController@tags', 'as' => 'tags']);
|
||||
}
|
||||
);
|
||||
|
||||
// V2 API route for net worth endpoint(s);
|
||||
Route::group(
|
||||
|
||||
Reference in New Issue
Block a user