mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-29 17:25:20 +00:00
Compare commits
102 Commits
develop-20
...
develop-20
Author | SHA1 | Date | |
---|---|---|---|
|
6946a815e2 | ||
|
4a84e94022 | ||
|
5ba5d1f90e | ||
|
beb2bbcdc9 | ||
|
805fd5ae08 | ||
|
96093e313a | ||
|
afe9e88f9a | ||
|
b43048c674 | ||
|
11c38a599b | ||
|
0ce245f480 | ||
|
aef15cf3d3 | ||
|
d1880de30e | ||
|
9d900a69ed | ||
|
1653f77b15 | ||
|
9418436d51 | ||
|
1c9a6a194a | ||
|
11cfb5a962 | ||
|
7d21467447 | ||
|
5ce9f32deb | ||
|
337440259f | ||
|
c483e0768f | ||
|
fd9b0d9417 | ||
|
c3165f4937 | ||
|
a5c9adc872 | ||
|
59cc007931 | ||
|
8b0b12b521 | ||
|
6ae1cfd82e | ||
|
4d7eb27fd0 | ||
|
fe0b8d0128 | ||
|
04f0fcfbf7 | ||
|
7e182cf070 | ||
|
ad78c302ef | ||
|
36b4c69491 | ||
|
30bd0711f4 | ||
|
d847827584 | ||
|
786c1fcd58 | ||
|
90e7f0c0f7 | ||
|
63f334abe5 | ||
|
2466cd942f | ||
|
ea37db87f4 | ||
|
c168fb6960 | ||
|
03fb707b93 | ||
|
db226c2584 | ||
|
1c6ec82c91 | ||
|
40eb77ffde | ||
|
17ddb01cd1 | ||
|
ca56c7af70 | ||
|
55c428070f | ||
|
574eec1c08 | ||
|
15cde8173e | ||
|
ccb581b4ee | ||
|
c5f8db5b50 | ||
|
611748fbaf | ||
|
b57dfa9432 | ||
|
253982d579 | ||
|
94c7a19aa0 | ||
|
e9b360a721 | ||
|
ebf7f5932a | ||
|
4427f2fb99 | ||
|
6626dfbac3 | ||
|
093a6387a2 | ||
|
21ddde9e0d | ||
|
44d4e4e6da | ||
|
e34e53eeb3 | ||
|
07fb45bb34 | ||
|
d381669733 | ||
|
fb9eb15ae1 | ||
|
a2127c382b | ||
|
e10d39c093 | ||
|
a933b49e7c | ||
|
38bcd610df | ||
|
5beb476a28 | ||
|
3a43ce6546 | ||
|
c11fddb097 | ||
|
98f79cd9bf | ||
|
a3d3fe758b | ||
|
93587cf1b6 | ||
|
361e95f102 | ||
|
be212e7d1d | ||
|
003a30727f | ||
|
27b662e2dc | ||
|
0b4d7ad95e | ||
|
7acbfb230a | ||
|
b974310798 | ||
|
e391725eed | ||
|
f505580b33 | ||
|
270f932a48 | ||
|
b9afa908e3 | ||
|
6dcc78b9e5 | ||
|
7b0e7e8612 | ||
|
1ece4abd9d | ||
|
07c03b672b | ||
|
27ea50ec16 | ||
|
e1195e6663 | ||
|
faeb17f319 | ||
|
db91b1b127 | ||
|
b5b511c86b | ||
|
750019808c | ||
|
7f4510467f | ||
|
a46f8430df | ||
|
5e1ecb2b11 | ||
|
a3fcd636e7 |
36
.ci/php-cs-fixer/composer.lock
generated
36
.ci/php-cs-fixer/composer.lock
generated
@@ -406,16 +406,16 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.73.1",
|
||||
"version": "v3.75.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "ffcb8200a42045e65049af7910cfd022f631b064"
|
||||
"reference": "399a128ff2fdaf4281e4e79b755693286cdf325c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/ffcb8200a42045e65049af7910cfd022f631b064",
|
||||
"reference": "ffcb8200a42045e65049af7910cfd022f631b064",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/399a128ff2fdaf4281e4e79b755693286cdf325c",
|
||||
"reference": "399a128ff2fdaf4281e4e79b755693286cdf325c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -498,7 +498,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.73.1"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.75.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -506,7 +506,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-19T23:42:16+00:00"
|
||||
"time": "2025-03-31T18:40:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
@@ -1256,16 +1256,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.2.1",
|
||||
"version": "v7.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3"
|
||||
"reference": "e51498ea18570c062e7df29d05a7003585b19b88"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
|
||||
"reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/e51498ea18570c062e7df29d05a7003585b19b88",
|
||||
"reference": "e51498ea18570c062e7df29d05a7003585b19b88",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1329,7 +1329,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.1"
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1345,7 +1345,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-11T03:49:26+00:00"
|
||||
"time": "2025-03-12T08:11:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
@@ -2243,16 +2243,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v7.2.4",
|
||||
"version": "v7.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf"
|
||||
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf",
|
||||
"reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d",
|
||||
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2284,7 +2284,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v7.2.4"
|
||||
"source": "https://github.com/symfony/process/tree/v7.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2300,7 +2300,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-05T08:33:46+00:00"
|
||||
"time": "2025-03-13T12:21:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
|
@@ -164,6 +164,13 @@ MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_SENDMAIL_COMMAND=
|
||||
|
||||
#
|
||||
# If you use self-signed certificates for your STMP server, you can use the following settings.
|
||||
#
|
||||
MAIL_ALLOW_SELF_SIGNED=false
|
||||
MAIL_VERIFY_PEER=true
|
||||
MAIL_VERIFY_PEER_NAME=true
|
||||
|
||||
# Other mail drivers:
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
MAILGUN_DOMAIN=
|
||||
|
23
.github/workflows/release.yml
vendored
23
.github/workflows/release.yml
vendored
@@ -59,7 +59,28 @@ jobs:
|
||||
git config user.email release@firefly-iii.org
|
||||
git config advice.addIgnoredFile false
|
||||
git config push.autoSetupRemote true
|
||||
- name: crowdin action
|
||||
- name: Lint PHP
|
||||
run: |
|
||||
php_lint_file()
|
||||
{
|
||||
local php_file="$1"
|
||||
php -l "$php_file" &> /dev/null
|
||||
if [ "$?" -ne 0 ]
|
||||
then
|
||||
echo -e "[FAIL] $php_file"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
export -f php_lint_file
|
||||
|
||||
find . -path ./vendor -prune -o -name '*.php' | parallel -j 4 php_lint_file {}
|
||||
|
||||
if [ "$?" -ne 0 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
- name: Crowdin action
|
||||
uses: crowdin/github-action@v2
|
||||
with:
|
||||
upload_sources: true
|
||||
|
@@ -4,6 +4,7 @@ Over time, many people have contributed to Firefly III. Their efforts are not al
|
||||
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
|
||||
|
||||
## 2025
|
||||
- =
|
||||
- Lompi
|
||||
- Jose Diaz-Gonzalez
|
||||
- SoftBrix
|
||||
|
@@ -27,13 +27,16 @@ namespace FireflyIII\Api\V1\Controllers\Chart;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Data\DateRequest;
|
||||
use FireflyIII\Api\V1\Requests\Chart\ChartRequest;
|
||||
use FireflyIII\Enums\AccountTypeEnum;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Support\Chart\ChartData;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\Support\Http\Api\ApiSupport;
|
||||
use FireflyIII\Support\Http\Api\CollectsAccountsFromFilter;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
@@ -43,8 +46,10 @@ use Illuminate\Http\JsonResponse;
|
||||
class AccountController extends Controller
|
||||
{
|
||||
use ApiSupport;
|
||||
use CollectsAccountsFromFilter;
|
||||
|
||||
private AccountRepositoryInterface $repository;
|
||||
private ChartData $chartData;
|
||||
|
||||
/**
|
||||
* AccountController constructor.
|
||||
@@ -56,6 +61,7 @@ class AccountController extends Controller
|
||||
function ($request, $next) {
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$this->chartData = new ChartData();
|
||||
$this->repository = app(AccountRepositoryInterface::class);
|
||||
$this->repository->setUser($user);
|
||||
|
||||
@@ -64,6 +70,29 @@ class AccountController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO fix documentation
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function dashboard(ChartRequest $request): JsonResponse
|
||||
{
|
||||
$queryParameters = $request->getParameters();
|
||||
$accounts = $this->getAccountList($queryParameters);
|
||||
|
||||
// move date to end of day
|
||||
$queryParameters['start']->startOfDay();
|
||||
$queryParameters['end']->endOfDay();
|
||||
|
||||
// loop each account, and collect info:
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$this->renderAccountData($queryParameters, $account);
|
||||
}
|
||||
|
||||
return response()->json($this->chartData->render());
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint is documented at:
|
||||
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/charts/getChartAccountOverview
|
||||
@@ -133,4 +162,45 @@ class AccountController extends Controller
|
||||
|
||||
return response()->json($chartData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function renderAccountData(array $params, Account $account): void
|
||||
{
|
||||
$currency = $this->repository->getAccountCurrency($account);
|
||||
if (null === $currency) {
|
||||
$currency = $this->default;
|
||||
}
|
||||
$currentSet = [
|
||||
'label' => $account->name,
|
||||
|
||||
// the currency that belongs to the account.
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
|
||||
// the default currency of the user (could be the same!)
|
||||
'date' => $params['start']->toAtomString(),
|
||||
'start' => $params['start']->toAtomString(),
|
||||
'end' => $params['end']->toAtomString(),
|
||||
'period' => '1D',
|
||||
'entries' => [],
|
||||
];
|
||||
$currentStart = clone $params['start'];
|
||||
$range = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
|
||||
|
||||
$previous = array_values($range)[0]['balance'];
|
||||
while ($currentStart <= $params['end']) {
|
||||
$format = $currentStart->format('Y-m-d');
|
||||
$label = $currentStart->toAtomString();
|
||||
$balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
|
||||
$previous = $balance;
|
||||
|
||||
$currentStart->addDay();
|
||||
$currentSet['entries'][$label] = $balance;
|
||||
}
|
||||
$this->chartData->add($currentSet);
|
||||
}
|
||||
}
|
||||
|
260
app/Api/V1/Controllers/Chart/BudgetController.php
Normal file
260
app/Api/V1/Controllers/Chart/BudgetController.php
Normal file
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* BudgetController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers\Chart;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Generic\DateRequest;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class BudgetController
|
||||
*/
|
||||
class BudgetController extends Controller
|
||||
{
|
||||
use CleansChartData;
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||
|
||||
protected OperationsRepositoryInterface $opsRepository;
|
||||
private BudgetLimitRepositoryInterface $blRepository;
|
||||
private array $currencies = [];
|
||||
private TransactionCurrency $currency;
|
||||
private BudgetRepositoryInterface $repository;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->repository = app(BudgetRepositoryInterface::class);
|
||||
$this->blRepository = app(BudgetLimitRepositoryInterface::class);
|
||||
$this->opsRepository = app(OperationsRepositoryInterface::class);
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
$this->repository->setUserGroup($userGroup);
|
||||
$this->opsRepository->setUserGroup($userGroup);
|
||||
$this->blRepository->setUserGroup($userGroup);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO see autocomplete/accountcontroller
|
||||
*/
|
||||
public function dashboard(DateRequest $request): JsonResponse
|
||||
{
|
||||
$params = $request->getAll();
|
||||
|
||||
/** @var Carbon $start */
|
||||
$start = $params['start'];
|
||||
|
||||
/** @var Carbon $end */
|
||||
$end = $params['end'];
|
||||
|
||||
// code from FrontpageChartGenerator, but not in separate class
|
||||
$budgets = $this->repository->getActiveBudgets();
|
||||
$data = [];
|
||||
|
||||
/** @var Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
// could return multiple arrays, so merge.
|
||||
$data = array_merge($data, $this->processBudget($budget, $start, $end));
|
||||
}
|
||||
|
||||
return response()->json($this->clean($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function processBudget(Budget $budget, Carbon $start, Carbon $end): array
|
||||
{
|
||||
// get all limits:
|
||||
$limits = $this->blRepository->getBudgetLimits($budget, $start, $end);
|
||||
$rows = [];
|
||||
|
||||
// if no limits
|
||||
if (0 === $limits->count()) {
|
||||
// return as a single item in an array
|
||||
$rows = $this->noBudgetLimits($budget, $start, $end);
|
||||
}
|
||||
if ($limits->count() > 0) {
|
||||
$rows = $this->budgetLimits($budget, $limits);
|
||||
}
|
||||
// is always an array
|
||||
$return = [];
|
||||
foreach ($rows as $row) {
|
||||
$current = [
|
||||
'label' => $budget->name,
|
||||
'currency_id' => (string) $row['currency_id'],
|
||||
'currency_code' => $row['currency_code'],
|
||||
'currency_name' => $row['currency_name'],
|
||||
'currency_decimal_places' => $row['currency_decimal_places'],
|
||||
'period' => null,
|
||||
'start' => $row['start'],
|
||||
'end' => $row['end'],
|
||||
'entries' => [
|
||||
'spent' => $row['spent'],
|
||||
'left' => $row['left'],
|
||||
'overspent' => $row['overspent'],
|
||||
],
|
||||
];
|
||||
$return[] = $current;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* When no budget limits are present, the expenses of the whole period are collected and grouped.
|
||||
* This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
|
||||
|
||||
return $this->processExpenses($budget->id, $spent, $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return
|
||||
* its info.
|
||||
*
|
||||
* @param array<int, array<int, string>> $array
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function processExpenses(int $budgetId, array $array, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$return = [];
|
||||
|
||||
/**
|
||||
* This array contains the expenses in this budget. Grouped per currency.
|
||||
* The grouping is on the main currency only.
|
||||
*
|
||||
* @var int $currencyId
|
||||
* @var array $block
|
||||
*/
|
||||
foreach ($array as $currencyId => $block) {
|
||||
$this->currencies[$currencyId] ??= TransactionCurrency::find($currencyId);
|
||||
$return[$currencyId] ??= [
|
||||
'currency_id' => (string) $currencyId,
|
||||
'currency_code' => $block['currency_code'],
|
||||
'currency_name' => $block['currency_name'],
|
||||
'currency_symbol' => $block['currency_symbol'],
|
||||
'currency_decimal_places' => (int) $block['currency_decimal_places'],
|
||||
'start' => $start->toAtomString(),
|
||||
'end' => $end->toAtomString(),
|
||||
'spent' => '0',
|
||||
'left' => '0',
|
||||
'overspent' => '0',
|
||||
];
|
||||
$currentBudgetArray = $block['budgets'][$budgetId];
|
||||
|
||||
// var_dump($return);
|
||||
/** @var array $journal */
|
||||
foreach ($currentBudgetArray['transaction_journals'] as $journal) {
|
||||
$return[$currencyId]['spent'] = bcadd($return[$currencyId]['spent'], $journal['amount']);
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that processes each budget limit (per budget).
|
||||
*
|
||||
* If you have a budget limit in EUR, only transactions in EUR will be considered.
|
||||
* If you have a budget limit in GBP, only transactions in GBP will be considered.
|
||||
*
|
||||
* If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function budgetLimits(Budget $budget, Collection $limits): array
|
||||
{
|
||||
app('log')->debug(sprintf('Now in budgetLimits(#%d)', $budget->id));
|
||||
$data = [];
|
||||
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($limits as $limit) {
|
||||
$data = array_merge($data, $this->processLimit($budget, $limit));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function processLimit(Budget $budget, BudgetLimit $limit): array
|
||||
{
|
||||
Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
|
||||
$end = clone $limit->end_date;
|
||||
$end->endOfDay();
|
||||
$spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget]));
|
||||
$limitCurrencyId = $limit->transaction_currency_id;
|
||||
$filtered = [];
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($spent as $currencyId => $entry) {
|
||||
// only spent the entry where the entry's currency matches the budget limit's currency
|
||||
// so $filtered will only have 1 or 0 entries
|
||||
if ($entry['currency_id'] === $limitCurrencyId) {
|
||||
$filtered[$currencyId] = $entry;
|
||||
}
|
||||
}
|
||||
$result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
|
||||
if (1 === count($result)) {
|
||||
$compare = bccomp($limit->amount, app('steam')->positive($result[$limitCurrencyId]['spent']));
|
||||
if (1 === $compare) {
|
||||
// convert this amount into the native currency:
|
||||
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, $result[$limitCurrencyId]['spent']);
|
||||
}
|
||||
if ($compare <= 0) {
|
||||
$result[$limitCurrencyId]['overspent'] = app('steam')->positive(bcadd($limit->amount, $result[$limitCurrencyId]['spent']));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
128
app/Api/V1/Controllers/Chart/CategoryController.php
Normal file
128
app/Api/V1/Controllers/Chart/CategoryController.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* CategoryController.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Controllers\Chart;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Api\V2\Controllers\Controller;
|
||||
use FireflyIII\Api\V2\Request\Generic\DateRequest;
|
||||
use FireflyIII\Enums\AccountTypeEnum;
|
||||
use FireflyIII\Enums\TransactionTypeEnum;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class BudgetController
|
||||
*/
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
use CleansChartData;
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
private AccountRepositoryInterface $accountRepos;
|
||||
private CurrencyRepositoryInterface $currencyRepos;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->accountRepos = app(AccountRepositoryInterface::class);
|
||||
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
$userGroup = $this->validateUserGroup($request);
|
||||
$this->accountRepos->setUserGroup($userGroup);
|
||||
$this->currencyRepos->setUserGroup($userGroup);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO may be worth to move to a handler but the data is simple enough.
|
||||
* TODO see autoComplete/account controller
|
||||
*
|
||||
* @throws FireflyException
|
||||
*
|
||||
* @SuppressWarnings("PHPMD.UnusedFormalParameter")
|
||||
*/
|
||||
public function dashboard(DateRequest $request): JsonResponse
|
||||
{
|
||||
/** @var Carbon $start */
|
||||
$start = $this->parameters->get('start');
|
||||
|
||||
/** @var Carbon $end */
|
||||
$end = $this->parameters->get('end');
|
||||
$accounts = $this->accountRepos->getAccountsByType([AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value]);
|
||||
$currencies = [];
|
||||
$return = [];
|
||||
|
||||
// get journals for entire period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setRange($start, $end)->withAccountInformation();
|
||||
$collector->setXorAccounts($accounts)->withCategoryInformation();
|
||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::RECONCILIATION->value]);
|
||||
$journals = $collector->getExtractedJournals();
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||
$currencies[$currencyId] = $currency;
|
||||
$categoryName = null === $journal['category_name'] ? (string) trans('firefly.no_category') : $journal['category_name'];
|
||||
$amount = app('steam')->positive($journal['amount']);
|
||||
$key = sprintf('%s-%s', $categoryName, $currency->code);
|
||||
// create arrays
|
||||
$return[$key] ??= [
|
||||
'label' => $categoryName,
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_name' => $currency->name,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'period' => null,
|
||||
'start' => $start->toAtomString(),
|
||||
'end' => $end->toAtomString(),
|
||||
'amount' => '0',
|
||||
];
|
||||
|
||||
// add monies
|
||||
$return[$key]['amount'] = bcadd($return[$key]['amount'], $amount);
|
||||
}
|
||||
$return = array_values($return);
|
||||
|
||||
// order by amount
|
||||
usort($return, static function (array $a, array $b) {
|
||||
return (float) $a['amount'] < (float) $b['amount'] ? 1 : -1;
|
||||
});
|
||||
|
||||
return response()->json($this->clean($return));
|
||||
}
|
||||
}
|
@@ -39,6 +39,8 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use FireflyIII\Support\Report\Summarizer\TransactionSummarizer;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@@ -97,10 +99,9 @@ class BasicController extends Controller
|
||||
$start = $dates['start'];
|
||||
$end = $dates['end'];
|
||||
$code = $request->get('currency_code');
|
||||
|
||||
// balance information:
|
||||
$balanceData = $this->getBalanceInformation($start, $end);
|
||||
$billData = $this->getBillInformation($start, $end);
|
||||
$billData = $this->getSubscriptionInformation($start, $end);
|
||||
$spentData = $this->getLeftToSpendInfo($start, $end);
|
||||
$netWorthData = $this->getNetWorthInfo($end);
|
||||
// $balanceData = [];
|
||||
@@ -122,6 +123,7 @@ class BasicController extends Controller
|
||||
|
||||
private function getBalanceInformation(Carbon $start, Carbon $end): array
|
||||
{
|
||||
Log::debug('getBalanceInformation');
|
||||
// some config settings
|
||||
$convertToNative = Amount::convertToNative();
|
||||
$default = Amount::getNativeCurrency();
|
||||
@@ -130,47 +132,110 @@ class BasicController extends Controller
|
||||
$expenses = [];
|
||||
$sums = [];
|
||||
$return = [];
|
||||
$currencies = [
|
||||
$default->id => $default,
|
||||
];
|
||||
|
||||
// collect income of user using the new group collector.
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
||||
$summarizer = new TransactionSummarizer();
|
||||
$set = $collector->setRange($start, $end)->setTypes([TransactionTypeEnum::DEPOSIT->value])->getExtractedJournals();
|
||||
$incomes = $summarizer->groupByCurrencyId($set, 'positive', false);
|
||||
|
||||
$set = $collector->getExtractedJournals();
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($set as $journal) {
|
||||
$currencyId = $convertToNative ? $default->id : (int) $journal['currency_id'];
|
||||
$amount = Amount::getAmountFromJournal($journal);
|
||||
$incomes[$currencyId] ??= '0';
|
||||
$incomes[$currencyId] = bcadd(
|
||||
$incomes[$currencyId],
|
||||
bcmul($amount, '-1')
|
||||
);
|
||||
$sums[$currencyId] ??= '0';
|
||||
$sums[$currencyId] = bcadd($sums[$currencyId], bcmul($amount, '-1'));
|
||||
}
|
||||
|
||||
// collect expenses of user.
|
||||
// collect expenses of user using the new group collector.
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
$set = $collector->getExtractedJournals();
|
||||
$set = $collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->getExtractedJournals();
|
||||
$expenses = $summarizer->groupByCurrencyId($set, 'negative', false);
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($set as $journal) {
|
||||
$currencyId = $convertToNative ? $default->id : (int) $journal['currency_id'];
|
||||
$amount = Amount::getAmountFromJournal($journal);
|
||||
$expenses[$currencyId] ??= '0';
|
||||
$expenses[$currencyId] = bcadd($expenses[$currencyId], $amount);
|
||||
$sums[$currencyId] ??= '0';
|
||||
$sums[$currencyId] = bcadd($sums[$currencyId], $amount);
|
||||
// if convert to native, do so right now.
|
||||
if ($convertToNative) {
|
||||
$newExpenses = [
|
||||
$default->id => [
|
||||
'currency_id' => $default->id,
|
||||
'currency_code' => $default->code,
|
||||
'currency_symbol' => $default->symbol,
|
||||
'currency_decimal_places' => $default->decimal_places,
|
||||
'sum' => '0',
|
||||
],
|
||||
];
|
||||
$newIncomes = [
|
||||
$default->id => [
|
||||
'currency_id' => $default->id,
|
||||
'currency_code' => $default->code,
|
||||
'currency_symbol' => $default->symbol,
|
||||
'currency_decimal_places' => $default->decimal_places,
|
||||
'sum' => '0',
|
||||
],
|
||||
];
|
||||
$sums = [
|
||||
$default->id => [
|
||||
'currency_id' => $default->id,
|
||||
'currency_code' => $default->code,
|
||||
'currency_symbol' => $default->symbol,
|
||||
'currency_decimal_places' => $default->decimal_places,
|
||||
'sum' => '0',
|
||||
],
|
||||
];
|
||||
|
||||
$converter = new ExchangeRateConverter();
|
||||
// loop over income and expenses
|
||||
foreach ([$expenses, $incomes] as $index => $array) {
|
||||
|
||||
// loop over either one.
|
||||
foreach ($array as $entry) {
|
||||
|
||||
// if it is the native currency already.
|
||||
if ($entry['currency_id'] === $default->id) {
|
||||
$sums[$default->id]['sum'] = bcadd($entry['sum'], $sums[$default->id]['sum']);
|
||||
|
||||
// don't forget to add it to newExpenses and newIncome
|
||||
if (0 === $index) {
|
||||
$newExpenses[$default->id]['sum'] = bcadd($newExpenses[$default->id]['sum'], $entry['sum']);
|
||||
}
|
||||
if (1 === $index) {
|
||||
$newIncomes[$default->id]['sum'] = bcadd($newIncomes[$default->id]['sum'], $entry['sum']);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$currencies[$entry['currency_id']] ??= $this->currencyRepos->find($entry['currency_id']);
|
||||
$convertedSum = $converter->convert($currencies[$entry['currency_id']], $default, $start, $entry['sum']);
|
||||
$sums[$default->id]['sum'] = bcadd($sums[$default->id]['sum'], $convertedSum);
|
||||
if (0 === $index) {
|
||||
$newExpenses[$default->id]['sum'] = bcadd($newExpenses[$default->id]['sum'], $convertedSum);
|
||||
}
|
||||
if (1 === $index) {
|
||||
$newIncomes[$default->id]['sum'] = bcadd($newIncomes[$default->id]['sum'], $convertedSum);
|
||||
}
|
||||
}
|
||||
}
|
||||
$incomes = $newIncomes;
|
||||
$expenses = $newExpenses;
|
||||
}
|
||||
if (!$convertToNative) {
|
||||
foreach ([$expenses, $incomes] as $array) {
|
||||
foreach ($array as $entry) {
|
||||
$currencyId = $entry['currency_id'];
|
||||
$sums[$currencyId] ??= [
|
||||
'currency_id' => $entry['currency_id'],
|
||||
'currency_code' => $entry['currency_code'],
|
||||
'currency_symbol' => $entry['currency_symbol'],
|
||||
'currency_decimal_places' => $entry['currency_decimal_places'],
|
||||
'sum' => '0',
|
||||
];
|
||||
$sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], $entry['sum']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// format amounts:
|
||||
$keys = array_keys($sums);
|
||||
foreach ($keys as $currencyId) {
|
||||
$currency = $this->currencyRepos->find($currencyId);
|
||||
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
|
||||
if (null === $currency) {
|
||||
continue;
|
||||
}
|
||||
@@ -178,37 +243,37 @@ class BasicController extends Controller
|
||||
$return[] = [
|
||||
'key' => sprintf('balance-in-%s', $currency->code),
|
||||
'title' => trans('firefly.box_balance_in_currency', ['currency' => $currency->symbol]),
|
||||
'monetary_value' => $sums[$currencyId] ?? '0',
|
||||
'monetary_value' => $sums[$currencyId]['sum'] ?? '0',
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'value_parsed' => app('amount')->formatAnything($currency, $sums[$currencyId] ?? '0', false),
|
||||
'value_parsed' => app('amount')->formatAnything($currency, $sums[$currencyId]['sum'] ?? '0', false),
|
||||
'local_icon' => 'balance-scale',
|
||||
'sub_title' => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false)
|
||||
.' + '.app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false),
|
||||
'sub_title' => app('amount')->formatAnything($currency, $expenses[$currencyId]['sum'] ?? '0', false)
|
||||
.' + '.app('amount')->formatAnything($currency, $incomes[$currencyId]['sum'] ?? '0', false),
|
||||
];
|
||||
$return[] = [
|
||||
'key' => sprintf('spent-in-%s', $currency->code),
|
||||
'title' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
|
||||
'monetary_value' => $expenses[$currencyId] ?? '0',
|
||||
'monetary_value' => $expenses[$currencyId]['sum'] ?? '0',
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'value_parsed' => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false),
|
||||
'value_parsed' => app('amount')->formatAnything($currency, $expenses[$currencyId]['sum'] ?? '0', false),
|
||||
'local_icon' => 'balance-scale',
|
||||
'sub_title' => '',
|
||||
];
|
||||
$return[] = [
|
||||
'key' => sprintf('earned-in-%s', $currency->code),
|
||||
'title' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
|
||||
'monetary_value' => $incomes[$currencyId] ?? '0',
|
||||
'monetary_value' => $incomes[$currencyId]['sum'] ?? '0',
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'value_parsed' => app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false),
|
||||
'value_parsed' => app('amount')->formatAnything($currency, $incomes[$currencyId]['sum'] ?? '0', false),
|
||||
'local_icon' => 'balance-scale',
|
||||
'sub_title' => '',
|
||||
];
|
||||
@@ -227,7 +292,7 @@ class BasicController extends Controller
|
||||
'value_parsed' => app('amount')->formatAnything($currency, '0', false),
|
||||
'local_icon' => 'balance-scale',
|
||||
'sub_title' => app('amount')->formatAnything($currency, '0', false)
|
||||
.' + '.app('amount')->formatAnything($currency, '0', false),
|
||||
.' + '.app('amount')->formatAnything($currency, '0', false),
|
||||
];
|
||||
$return[] = [
|
||||
'key' => sprintf('spent-in-%s', $currency->code),
|
||||
@@ -258,15 +323,72 @@ class BasicController extends Controller
|
||||
return $return;
|
||||
}
|
||||
|
||||
private function getBillInformation(Carbon $start, Carbon $end): array
|
||||
private function getSubscriptionInformation(Carbon $start, Carbon $end): array
|
||||
{
|
||||
app('log')->debug(sprintf('Now in getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-')));
|
||||
Log::debug(sprintf('Now in getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-')));
|
||||
/*
|
||||
* Since both this method and the chart use the exact same data, we can suffice
|
||||
* with calling the one method in the bill repository that will get this amount.
|
||||
*/
|
||||
$paidAmount = $this->billRepository->sumPaidInRange($start, $end);
|
||||
$unpaidAmount = $this->billRepository->sumUnpaidInRange($start, $end);
|
||||
$currencies = [
|
||||
$this->nativeCurrency->id => $this->nativeCurrency,
|
||||
];
|
||||
|
||||
if ($this->convertToNative) {
|
||||
$converter = new ExchangeRateConverter();
|
||||
$newPaidAmount = [[
|
||||
'id' => $this->nativeCurrency->id,
|
||||
'name' => $this->nativeCurrency->name,
|
||||
'symbol' => $this->nativeCurrency->symbol,
|
||||
'code' => $this->nativeCurrency->code,
|
||||
'decimal_places' => $this->nativeCurrency->decimal_places,
|
||||
'sum' => '0',
|
||||
]];
|
||||
|
||||
$newUnpaidAmount = [[
|
||||
'id' => $this->nativeCurrency->id,
|
||||
'name' => $this->nativeCurrency->name,
|
||||
'symbol' => $this->nativeCurrency->symbol,
|
||||
'code' => $this->nativeCurrency->code,
|
||||
'decimal_places' => $this->nativeCurrency->decimal_places,
|
||||
'sum' => '0',
|
||||
]];
|
||||
foreach ([$paidAmount, $unpaidAmount] as $index => $array) {
|
||||
foreach ($array as $item) {
|
||||
$currencyId = (int) $item['id'];
|
||||
if (0 === $index) {
|
||||
// paid amount
|
||||
if ($currencyId === $this->nativeCurrency->id) {
|
||||
$newPaidAmount[0]['sum'] = bcadd($newPaidAmount[0]['sum'], $item['sum']);
|
||||
|
||||
continue;
|
||||
}
|
||||
$currencies[$currencyId] ??= $this->currencyRepos->find($currencyId);
|
||||
$convertedAmount = $converter->convert($currencies[$currencyId], $this->nativeCurrency, $start, $item['sum']);
|
||||
$newPaidAmount[0]['sum'] = bcadd($newPaidAmount[0]['sum'], $convertedAmount);
|
||||
|
||||
continue;
|
||||
}
|
||||
// unpaid amount
|
||||
if ($currencyId === $this->nativeCurrency->id) {
|
||||
$newUnpaidAmount[0]['sum'] = bcadd($newUnpaidAmount[0]['sum'], $item['sum']);
|
||||
|
||||
continue;
|
||||
}
|
||||
$currencies[$currencyId] ??= $this->currencyRepos->find($currencyId);
|
||||
$convertedAmount = $converter->convert($currencies[$currencyId], $this->nativeCurrency, $start, $item['sum']);
|
||||
$newUnpaidAmount[0]['sum'] = bcadd($newUnpaidAmount[0]['sum'], $convertedAmount);
|
||||
}
|
||||
}
|
||||
$paidAmount = $newPaidAmount;
|
||||
$unpaidAmount = $newUnpaidAmount;
|
||||
}
|
||||
|
||||
// var_dump($paidAmount);
|
||||
// var_dump($unpaidAmount);
|
||||
// exit;
|
||||
|
||||
$return = [];
|
||||
|
||||
@@ -307,7 +429,7 @@ class BasicController extends Controller
|
||||
'sub_title' => '',
|
||||
];
|
||||
}
|
||||
app('log')->debug(sprintf('Done with getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-')));
|
||||
Log::debug(sprintf('Done with getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-')));
|
||||
|
||||
if (0 === count($return)) {
|
||||
$currency = $this->nativeCurrency;
|
||||
@@ -348,30 +470,60 @@ class BasicController extends Controller
|
||||
*/
|
||||
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
|
||||
{
|
||||
Log::debug(sprintf('Now in getLeftToSpendInfo("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||
$return = [];
|
||||
$today = today(config('app.timezone'));
|
||||
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
|
||||
$budgets = $this->budgetRepository->getActiveBudgets();
|
||||
$spent = $this->opsRepository->sumExpenses($start, $end, null, $budgets);
|
||||
$days = (int) $today->diffInDays($end, true) + 1;
|
||||
|
||||
Log::debug(sprintf('Now in getLeftToSpendInfo("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||
$return = [];
|
||||
$today = today(config('app.timezone'));
|
||||
$available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
|
||||
$budgets = $this->budgetRepository->getActiveBudgets();
|
||||
$spent = $this->opsRepository->sumExpenses($start, $end, null, $budgets);
|
||||
$days = (int) $today->diffInDays($end, true) + 1;
|
||||
$currencies = [];
|
||||
|
||||
// first, create an entry for each entry in the "available" array.
|
||||
/** @var array $availableBudget */
|
||||
foreach ($available as $currencyId => $availableBudget) {
|
||||
$currencies[$currencyId] ??= $this->currencyRepos->find($currencyId);
|
||||
$return[$currencyId] = [
|
||||
'key' => sprintf('left-to-spend-in-%s', $currencies[$currencyId]->code),
|
||||
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $currencies[$currencyId]->symbol]),
|
||||
'no_available_budgets' => false,
|
||||
'monetary_value' => $availableBudget,
|
||||
'currency_id' => (string) $currencies[$currencyId]->id,
|
||||
'currency_code' => $currencies[$currencyId]->code,
|
||||
'currency_symbol' => $currencies[$currencyId]->symbol,
|
||||
'currency_decimal_places' => $currencies[$currencyId]->decimal_places,
|
||||
'value_parsed' => app('amount')->formatFlat($currencies[$currencyId]->symbol, $currencies[$currencyId]->decimal_places, $availableBudget, false),
|
||||
'local_icon' => 'money',
|
||||
'sub_title' => app('amount')->formatFlat(
|
||||
$currencies[$currencyId]->symbol,
|
||||
$currencies[$currencyId]->decimal_places,
|
||||
$availableBudget,
|
||||
false
|
||||
),
|
||||
];
|
||||
}
|
||||
foreach ($spent as $row) {
|
||||
// either an amount was budgeted or 0 is available.
|
||||
$currencyId = $row['currency_id'];
|
||||
$amount = (string) ($available[$currencyId] ?? '0');
|
||||
$spentInCurrency = $row['sum'];
|
||||
$leftToSpend = bcadd($amount, $spentInCurrency);
|
||||
$perDay = '0';
|
||||
$currencyId = (int) $row['currency_id'];
|
||||
$amount = (string) ($available[$currencyId] ?? '0');
|
||||
if (0 === bccomp($amount, '0')) {
|
||||
// #9858 skip over currencies with no available budget.
|
||||
continue;
|
||||
}
|
||||
$spentInCurrency = $row['sum'];
|
||||
$leftToSpend = bcadd($amount, $spentInCurrency);
|
||||
$perDay = '0';
|
||||
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
|
||||
$perDay = bcdiv($leftToSpend, (string) $days);
|
||||
}
|
||||
|
||||
Log::debug(sprintf('Spent %s %s', $row['currency_code'], $row['sum']));
|
||||
|
||||
$return[] = [
|
||||
$return[$currencyId] = [
|
||||
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
|
||||
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
|
||||
'no_available_budgets' => false,
|
||||
'monetary_value' => $leftToSpend,
|
||||
'currency_id' => (string) $row['currency_id'],
|
||||
'currency_code' => $row['currency_code'],
|
||||
@@ -388,11 +540,12 @@ class BasicController extends Controller
|
||||
];
|
||||
}
|
||||
if (0 === count($return)) {
|
||||
$currency = $this->nativeCurrency;
|
||||
$return[] = [
|
||||
$currency = $this->nativeCurrency;
|
||||
$return[$currency->id] = [
|
||||
'key' => sprintf('left-to-spend-in-%s', $currency->code),
|
||||
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $currency->symbol]),
|
||||
'monetary_value' => '0',
|
||||
'no_available_budgets' => true,
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_code' => $currency->code,
|
||||
'currency_symbol' => $currency->symbol,
|
||||
@@ -408,7 +561,7 @@ class BasicController extends Controller
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
return array_values($return);
|
||||
}
|
||||
|
||||
private function getNetWorthInfo(Carbon $end): array
|
||||
|
91
app/Api/V1/Requests/Chart/ChartRequest.php
Normal file
91
app/Api/V1/Requests/Chart/ChartRequest.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DashboardChartRequest.php
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests\Chart;
|
||||
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
/**
|
||||
* Class ChartRequest
|
||||
*/
|
||||
class ChartRequest extends FormRequest
|
||||
{
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
use ValidatesUserGroupTrait;
|
||||
|
||||
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
|
||||
|
||||
public function getParameters(): array
|
||||
{
|
||||
return [
|
||||
'start' => $this->convertDateTime('start')?->startOfDay(),
|
||||
'end' => $this->convertDateTime('end')?->endOfDay(),
|
||||
'preselected' => $this->convertString('preselected', 'empty'),
|
||||
'period' => $this->convertString('period', '1M'),
|
||||
'accounts' => $this->arrayFromValue($this->get('accounts')),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'required|date|after:1900-01-01|before:2099-12-31|before_or_equal:end',
|
||||
'end' => 'required|date|after:1900-01-01|before:2099-12-31|after_or_equal:start',
|
||||
'preselected' => sprintf('nullable|in:%s', implode(',', config('firefly.preselected_accounts'))),
|
||||
'period' => sprintf('nullable|in:%s', implode(',', config('firefly.valid_view_ranges'))),
|
||||
'accounts.*' => 'exists:accounts,id',
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(
|
||||
static function (Validator $validator): void {
|
||||
// validate transaction query data.
|
||||
$data = $validator->getData();
|
||||
if (!array_key_exists('accounts', $data)) {
|
||||
// $validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
|
||||
return;
|
||||
}
|
||||
if (!is_array($data['accounts'])) {
|
||||
$validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
|
||||
}
|
||||
}
|
||||
);
|
||||
if ($validator->fails()) {
|
||||
Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
|
||||
}
|
||||
}
|
||||
}
|
62
app/Api/V1/Requests/Generic/DateRequest.php
Normal file
62
app/Api/V1/Requests/Generic/DateRequest.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DateRequest.php
|
||||
* Copyright (c) 2021 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests\Generic;
|
||||
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
/**
|
||||
* Request class for end points that require date parameters.
|
||||
*
|
||||
* Class DateRequest
|
||||
*/
|
||||
class DateRequest extends FormRequest
|
||||
{
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
return [
|
||||
'start' => $this->getCarbonDate('start')->startOfDay(),
|
||||
'end' => $this->getCarbonDate('end')->endOfDay(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'start' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||
'end' => 'required|date|after_or_equal:start|before:2099-12-31|after:1900-01-01',
|
||||
];
|
||||
}
|
||||
}
|
59
app/Api/V1/Requests/Generic/SingleDateRequest.php
Normal file
59
app/Api/V1/Requests/Generic/SingleDateRequest.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* DateRequest.php
|
||||
* Copyright (c) 2021 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Api\V1\Requests\Generic;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
/**
|
||||
* Request class for end points that require a date parameter.
|
||||
*
|
||||
* Class SingleDateRequest
|
||||
*/
|
||||
class SingleDateRequest extends FormRequest
|
||||
{
|
||||
use ChecksLogin;
|
||||
use ConvertsDataTypes;
|
||||
|
||||
/**
|
||||
* Get all data from the request.
|
||||
*/
|
||||
public function getDate(): Carbon
|
||||
{
|
||||
return $this->getCarbonDate('date');
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules that the incoming request must be matched against.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'date' => 'required|date|after:1900-01-01|before:2099-12-31',
|
||||
];
|
||||
}
|
||||
}
|
@@ -179,7 +179,7 @@ class BillController extends Controller
|
||||
}
|
||||
$amount = bcmul($journal['amount'], '-1');
|
||||
if ($this->convertToNative && $currencyId !== $journal['currency_id']) {
|
||||
$amount = bcmul($journal['native_amount'], '-1');
|
||||
$amount = bcmul($journal['native_amount'] ?? '0', '-1');
|
||||
}
|
||||
if ($this->convertToNative && $currencyId === $journal['foreign_currency_id']) {
|
||||
$amount = bcmul($journal['foreign_amount'], '-1');
|
||||
|
@@ -32,6 +32,7 @@ use FireflyIII\Support\Export\ExportDataGenerator;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Response as LaravelResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
@@ -71,6 +72,7 @@ class IndexController extends Controller
|
||||
|
||||
return redirect(route('export.index'));
|
||||
}
|
||||
Log::debug('Will export from the UI.');
|
||||
|
||||
/** @var ExportDataGenerator $generator */
|
||||
$generator = app(ExportDataGenerator::class);
|
||||
@@ -83,6 +85,7 @@ class IndexController extends Controller
|
||||
$firstDate->subYear();
|
||||
$journal = $this->journalRepository->firstNull();
|
||||
if (null !== $journal) {
|
||||
Log::debug('First journal is NULL, using today() - 1 year.');
|
||||
$firstDate = clone $journal->date;
|
||||
}
|
||||
$generator->setStart($firstDate);
|
||||
|
@@ -27,6 +27,7 @@ namespace FireflyIII\Notifications\Admin;
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
@@ -79,9 +80,10 @@ class UnknownUserLoginAttempt extends Notification
|
||||
{
|
||||
$settings = ReturnsSettings::getSettings('ntfy', 'owner', null);
|
||||
$message = new Message();
|
||||
$ip = Request::ip();
|
||||
$message->topic($settings['ntfy_topic']);
|
||||
$message->title((string) trans('email.unknown_user_subject'));
|
||||
$message->body((string) trans('email.unknown_user_message', ['address' => $this->address]));
|
||||
$message->body((string) trans('email.unknown_user_message', ['address' => $this->address, 'ip' => $ip]));
|
||||
|
||||
return $message;
|
||||
}
|
||||
@@ -91,7 +93,9 @@ class UnknownUserLoginAttempt extends Notification
|
||||
*/
|
||||
public function toPushover(OwnerNotifiable $notifiable): PushoverMessage
|
||||
{
|
||||
return PushoverMessage::create((string) trans('email.unknown_user_message', ['address' => $this->address]))
|
||||
$ip = Request::ip();
|
||||
|
||||
return PushoverMessage::create((string) trans('email.unknown_user_message', ['address' => $this->address, 'ip' => $ip]))
|
||||
->title((string) trans('email.unknown_user_subject'))
|
||||
;
|
||||
}
|
||||
@@ -101,8 +105,10 @@ class UnknownUserLoginAttempt extends Notification
|
||||
*/
|
||||
public function toSlack(OwnerNotifiable $notifiable): SlackMessage
|
||||
{
|
||||
$ip = Request::ip();
|
||||
|
||||
return new SlackMessage()->content(
|
||||
(string) trans('email.unknown_user_body', ['address' => $this->address])
|
||||
(string) trans('email.unknown_user_body', ['address' => $this->address, 'ip' => $ip])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -111,6 +117,12 @@ class UnknownUserLoginAttempt extends Notification
|
||||
*/
|
||||
public function via(OwnerNotifiable $notifiable): array
|
||||
{
|
||||
return ReturnsAvailableChannels::returnChannels('owner');
|
||||
$channels = ReturnsAvailableChannels::returnChannels('owner');
|
||||
$isDemoSite = FireflyConfig::get('is_demo_site', false)->data;
|
||||
if (true === $isDemoSite) {
|
||||
return array_diff($channels, ['mail']);
|
||||
}
|
||||
|
||||
return $channels;
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Notifications\Security;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
@@ -103,6 +104,12 @@ class UserFailedLoginAttempt extends Notification
|
||||
*/
|
||||
public function via(User $notifiable): array
|
||||
{
|
||||
return ReturnsAvailableChannels::returnChannels('user', $notifiable);
|
||||
$channels = ReturnsAvailableChannels::returnChannels('user', $notifiable);
|
||||
$isDemoSite = FireflyConfig::get('is_demo_site', false)->data;
|
||||
if (true === $isDemoSite) {
|
||||
return array_diff($channels, ['mail']);
|
||||
}
|
||||
|
||||
return $channels;
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Notifications\Test;
|
||||
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
@@ -63,6 +64,11 @@ class OwnerTestNotificationEmail extends Notification
|
||||
*/
|
||||
public function via(OwnerNotifiable $notifiable): array
|
||||
{
|
||||
$isDemoSite = FireflyConfig::get('is_demo_site', false)->data;
|
||||
if (true === $isDemoSite) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return ['mail'];
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Notifications\Test;
|
||||
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
@@ -60,6 +61,11 @@ class UserTestNotificationEmail extends Notification
|
||||
*/
|
||||
public function via(User $notifiable): array
|
||||
{
|
||||
$isDemoSite = FireflyConfig::get('is_demo_site', false)->data;
|
||||
if (true === $isDemoSite) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return ['mail'];
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Notifications\User;
|
||||
|
||||
use FireflyIII\Notifications\ReturnsAvailableChannels;
|
||||
use FireflyIII\Notifications\ReturnsSettings;
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
@@ -101,6 +102,12 @@ class NewAccessToken extends Notification
|
||||
*/
|
||||
public function via(User $notifiable): array
|
||||
{
|
||||
return ReturnsAvailableChannels::returnChannels('user', $notifiable);
|
||||
$channels = ReturnsAvailableChannels::returnChannels('user', $notifiable);
|
||||
$isDemoSite = FireflyConfig::get('is_demo_site', false)->data;
|
||||
if (true === $isDemoSite) {
|
||||
return array_diff($channels, ['mail']);
|
||||
}
|
||||
|
||||
return $channels;
|
||||
}
|
||||
}
|
||||
|
@@ -676,7 +676,7 @@ class AccountRepository implements AccountRepositoryInterface, UserGroupInterfac
|
||||
'foreign_currencies.code as foreign_currency_code',
|
||||
'foreign_currencies.name as foreign_currency_name',
|
||||
'foreign_currencies.symbol as foreign_currency_symbol',
|
||||
'foreign_currencies.decimal_places as foreign_decimal_places',
|
||||
'foreign_currencies.decimal_places as foreign_currency_decimal_places',
|
||||
|
||||
// fields
|
||||
'transaction_journals.date', 'transaction_types.type', 'transaction_journals.transaction_currency_id', 'transactions.amount'])
|
||||
|
@@ -138,7 +138,7 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface, U
|
||||
->where('end_date', $end->format('Y-m-d'))->get()
|
||||
;
|
||||
|
||||
Log::debug(sprintf('Found %d available budgets', $availableBudgets->count()));
|
||||
Log::debug(sprintf('Found %d available budgets (already converted)', $availableBudgets->count()));
|
||||
|
||||
// use native amount if necessary?
|
||||
$convertToNative = Amount::convertToNative($this->user);
|
||||
@@ -149,8 +149,9 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface, U
|
||||
$currencyId = $convertToNative && $availableBudget->transaction_currency_id !== $default->id ? $default->id : $availableBudget->transaction_currency_id;
|
||||
$field = $convertToNative && $availableBudget->transaction_currency_id !== $default->id ? 'native_amount' : 'amount';
|
||||
$return[$currencyId] ??= '0';
|
||||
$return[$currencyId] = bcadd($return[$currencyId], $availableBudget->{$field});
|
||||
Log::debug(sprintf('Add #%d %s (%s) for a total of %s', $currencyId, $availableBudget->{$field}, $field, $return[$currencyId]));
|
||||
$amount = '' === (string) $availableBudget->{$field} ? '0' : (string) $availableBudget->{$field};
|
||||
$return[$currencyId] = bcadd($return[$currencyId], $amount);
|
||||
Log::debug(sprintf('Add #%d %s (%s) for a total of %s', $currencyId, $amount, $field, $return[$currencyId]));
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
@@ -247,6 +247,6 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
}
|
||||
$summarizer = new TransactionSummarizer($this->user);
|
||||
|
||||
return $summarizer->groupByCurrencyId($journals);
|
||||
return $summarizer->groupByCurrencyId($journals, 'negative', false);
|
||||
}
|
||||
}
|
||||
|
@@ -55,6 +55,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
if (null !== $accounts && $accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
$collector->excludeDestinationAccounts($accounts); // to exclude withdrawals to liabilities.
|
||||
}
|
||||
if (null !== $categories && $categories->count() > 0) {
|
||||
$collector->setCategories($categories);
|
||||
@@ -132,6 +133,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
||||
if (null !== $accounts && $accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
$collector->excludeSourceAccounts($accounts); // to prevent income from liabilities.
|
||||
}
|
||||
if (null !== $categories && $categories->count() > 0) {
|
||||
$collector->setCategories($categories);
|
||||
|
@@ -46,7 +46,7 @@ class ChartData
|
||||
if (array_key_exists('native_currency_id', $data)) {
|
||||
$data['native_currency_id'] = (string) $data['native_currency_id'];
|
||||
}
|
||||
$required = ['start', 'date', 'end', 'entries', 'native_entries'];
|
||||
$required = ['start', 'date', 'end', 'entries'];
|
||||
foreach ($required as $field) {
|
||||
if (!array_key_exists($field, $data)) {
|
||||
throw new FireflyException(sprintf('Data-set is missing the "%s"-variable.', $field));
|
||||
|
@@ -45,8 +45,8 @@ class UpdateCheckCronjob extends AbstractCronjob
|
||||
Log::debug('Update check is not enabled.');
|
||||
// get stuff from job:
|
||||
$this->jobFired = false;
|
||||
$this->jobErrored = true;
|
||||
$this->jobSucceeded = false;
|
||||
$this->jobErrored = false;
|
||||
$this->jobSucceeded = true;
|
||||
$this->message = 'The update check is not enabled.';
|
||||
|
||||
return;
|
||||
@@ -61,8 +61,8 @@ class UpdateCheckCronjob extends AbstractCronjob
|
||||
if ($diff < 604800 && false === $this->force) {
|
||||
// get stuff from job:
|
||||
$this->jobFired = false;
|
||||
$this->jobErrored = true;
|
||||
$this->jobSucceeded = false;
|
||||
$this->jobErrored = false;
|
||||
$this->jobSucceeded = true;
|
||||
$this->message = sprintf('Checked for updates less than a week ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data));
|
||||
|
||||
return;
|
||||
|
@@ -731,6 +731,7 @@ class ExportDataGenerator
|
||||
*/
|
||||
private function exportTransactions(): string
|
||||
{
|
||||
Log::debug('Will now export transactions.');
|
||||
// TODO better place for keys?
|
||||
$header = ['user_id', 'group_id', 'journal_id', 'created_at', 'updated_at', 'group_title', 'type', 'currency_code', 'amount', 'foreign_currency_code', 'foreign_amount', 'native_currency_code', 'native_amount', 'native_foreign_amount', 'description', 'date', 'source_name', 'source_iban', 'source_type', 'destination_name', 'destination_iban', 'destination_type', 'reconciled', 'category', 'budget', 'bill', 'tags', 'notes'];
|
||||
|
||||
|
@@ -49,7 +49,7 @@ class TransactionSummarizer
|
||||
$this->convertToNative = Amount::convertToNative($user);
|
||||
}
|
||||
|
||||
public function groupByCurrencyId(array $journals, string $method = 'negative'): array
|
||||
public function groupByCurrencyId(array $journals, string $method = 'negative', bool $includeForeign = true): array
|
||||
{
|
||||
Log::debug(sprintf('Now in groupByCurrencyId(array, "%s")', $method));
|
||||
$array = [];
|
||||
@@ -94,10 +94,10 @@ class TransactionSummarizer
|
||||
}
|
||||
}
|
||||
if (!$this->convertToNative) {
|
||||
Log::debug(sprintf('Journal #%d also includes foreign amount (foreign is %s)', $journal['transaction_journal_id'], $journal['foreign_currency_code']));
|
||||
// use foreign amount?
|
||||
$foreignCurrencyId = (int) $journal['foreign_currency_id'];
|
||||
if (0 !== $foreignCurrencyId) {
|
||||
Log::debug(sprintf('Journal #%d also includes foreign amount (foreign is "%s")', $journal['transaction_journal_id'], $journal['foreign_currency_code']));
|
||||
$foreignCurrencyName = $journal['foreign_currency_name'];
|
||||
$foreignCurrencySymbol = $journal['foreign_currency_symbol'];
|
||||
$foreignCurrencyCode = $journal['foreign_currency_code'];
|
||||
@@ -124,7 +124,7 @@ class TransactionSummarizer
|
||||
}
|
||||
|
||||
// then process foreign amount, if it exists.
|
||||
if (0 !== $foreignCurrencyId) {
|
||||
if (0 !== $foreignCurrencyId && true === $includeForeign) {
|
||||
$amount = (string) ($journal['foreign_amount'] ?? '0');
|
||||
$array[$foreignCurrencyId] ??= [
|
||||
'sum' => '0',
|
||||
|
@@ -84,7 +84,7 @@
|
||||
"bacon/bacon-qr-code": "^2",
|
||||
"diglactic/laravel-breadcrumbs": "^10",
|
||||
"gdbots/query-parser": "^3.0",
|
||||
"guzzlehttp/guzzle": "^7.8",
|
||||
"guzzlehttp/guzzle": "^7.9",
|
||||
"jc5/google2fa-laravel": "^2.0",
|
||||
"jc5/recovery": "^2",
|
||||
"laravel-notification-channels/pushover": "^4.0",
|
||||
|
413
composer.lock
generated
413
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -28,48 +28,53 @@ return [
|
||||
'download_enabled' => env('ENABLE_EXTERNAL_RATES', false),
|
||||
|
||||
// if currencies are added, default rates must be added as well!
|
||||
// last exchange rate update: 2024-12-30
|
||||
// source: https://www.xe.com/currencyconverter/
|
||||
'date' => '2024-12-30',
|
||||
'date' => '2025-04-15',
|
||||
|
||||
// all rates are from EUR to $currency:
|
||||
'rates' => [
|
||||
// europa
|
||||
'EUR' => 1,
|
||||
'HUF' => 410.79798,
|
||||
'GBP' => 0.82858703,
|
||||
'UAH' => 43.485934,
|
||||
'PLN' => 4.2708542,
|
||||
'TRY' => 36.804124,
|
||||
'GBP' => 0.86003261,
|
||||
'UAH' => 46.867455,
|
||||
'PLN' => 4.2802098,
|
||||
'TRY' => 43.180054,
|
||||
'DKK' => 7.4591,
|
||||
'RON' => 4.9768699,
|
||||
'RON' => 7.4648336,
|
||||
|
||||
// Americas
|
||||
'USD' => 1.0430046,
|
||||
'BRL' => 6.4639113,
|
||||
'CAD' => 1.5006908,
|
||||
'MXN' => 21.249542,
|
||||
'USD' => 1.1349044,
|
||||
'BRL' => 6.6458518,
|
||||
'CAD' => 1.575105,
|
||||
'MXN' => 22.805278,
|
||||
|
||||
// Oceania currencies
|
||||
'IDR' => 16860.057,
|
||||
'AUD' => 1.6705648,
|
||||
'NZD' => 1.8436945,
|
||||
'IDR' => 19070.382,
|
||||
'AUD' => 1.787202,
|
||||
'NZD' => 1.9191078,
|
||||
|
||||
// africa
|
||||
'EGP' => 53.038174,
|
||||
'MAD' => 10.521629,
|
||||
'ZAR' => 19.460263,
|
||||
'EGP' => 57.874172,
|
||||
'MAD' => 10.549438,
|
||||
'ZAR' => 21.444356,
|
||||
|
||||
// asia
|
||||
'JPY' => 164.74767,
|
||||
'RMB' => 7.6138994,
|
||||
'CNY' => 7.6138994,
|
||||
'RUB' => 108.56771,
|
||||
'INR' => 89.157391,
|
||||
'JPY' => 162.47195,
|
||||
'RMB' => 8.2849977,
|
||||
'CNY' => 8.2849977,
|
||||
'RUB' => 93.34423,
|
||||
'INR' => 97.572815,
|
||||
|
||||
// int
|
||||
'ILS' => 3.8428028,
|
||||
'CHF' => 0.94044969,
|
||||
'ILS' => 4.1801786,
|
||||
'CHF' => 0.92683126,
|
||||
'HRK' => 7.5345, // replaced by EUR
|
||||
|
||||
'ISK' => 145.10532,
|
||||
'NOK' => 11.980824,
|
||||
'SEK' => 11.08809,
|
||||
'HKD' => 8.8046322,
|
||||
'CZK' => 25.092213,
|
||||
],
|
||||
];
|
||||
|
@@ -78,7 +78,7 @@ return [
|
||||
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
||||
// see cer.php for exchange rates feature flag.
|
||||
],
|
||||
'version' => 'develop/2025-03-24',
|
||||
'version' => 'develop/2025-04-19',
|
||||
'api_version' => '2.1.0', // field is no longer used.
|
||||
'db_version' => 25,
|
||||
|
||||
@@ -184,6 +184,7 @@ return [
|
||||
'currencyPreference' => 'EUR',
|
||||
'language' => 'en_US',
|
||||
'locale' => 'equal',
|
||||
'convertToNative' => false,
|
||||
],
|
||||
'default_currency' => 'EUR',
|
||||
'default_language' => envNonEmpty('DEFAULT_LANGUAGE', 'en_US'),
|
||||
|
@@ -37,14 +37,19 @@ return [
|
||||
|
||||
'mailers' => [
|
||||
'smtp' => [
|
||||
'transport' => 'smtp',
|
||||
'host' => envNonEmpty('MAIL_HOST', 'smtp.mailtrap.io'),
|
||||
'port' => (int) env('MAIL_PORT', 2525),
|
||||
'encryption' => envNonEmpty('MAIL_ENCRYPTION', 'tls'),
|
||||
'username' => envNonEmpty('MAIL_USERNAME', 'user@example.com'),
|
||||
'password' => envNonEmpty('MAIL_PASSWORD', 'password'),
|
||||
'timeout' => null,
|
||||
'verify_peer' => null !== env('MAIL_ENCRYPTION'),
|
||||
'transport' => 'smtp',
|
||||
'host' => envNonEmpty('MAIL_HOST', 'smtp.mailtrap.io'),
|
||||
'port' => (int) env('MAIL_PORT', 2525),
|
||||
'encryption' => envNonEmpty('MAIL_ENCRYPTION', 'tls'),
|
||||
'username' => envNonEmpty('MAIL_USERNAME', 'user@example.com'),
|
||||
'password' => envNonEmpty('MAIL_PASSWORD', 'password'),
|
||||
'timeout' => null,
|
||||
'scheme' => env('MAIL_SCHEME'),
|
||||
'url' => env('MAIL_URL'),
|
||||
'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url(env('APP_URL', 'http://localhost'), PHP_URL_HOST)),
|
||||
'verify_peer' => env('MAIL_VERIFY_PEER', true),
|
||||
'allow_self_signed' => env('MAIL_ALLOW_SELF_SIGNED', false),
|
||||
'verify_peer_name' => env('MAIL_VERIFY_PEER_NAME', true),
|
||||
],
|
||||
'mailersend' => [
|
||||
'transport' => 'mailersend',
|
||||
|
@@ -139,6 +139,7 @@ return [
|
||||
'firefly' => [
|
||||
'administrations_page_title',
|
||||
'administrations_index_menu',
|
||||
'expires_at',
|
||||
'temp_administrations_introduction',
|
||||
'administration_currency_form_help',
|
||||
'administrations_page_edit_sub_title_js',
|
||||
|
@@ -69,10 +69,14 @@ class TransactionCurrencySeeder extends Seeder
|
||||
$currencies[] = ['code' => 'RUB', 'name' => 'Russian ruble', 'symbol' => '₽', 'decimal_places' => 2];
|
||||
$currencies[] = ['code' => 'INR', 'name' => 'Indian rupee', 'symbol' => '₹', 'decimal_places' => 2];
|
||||
|
||||
// PLEASE ADD NEW CURRENCIES BELOW THIS LINE
|
||||
// ALL NEW CURRENCIES BELOW THIS LINE
|
||||
$currencies[] = ['code' => 'ILS', 'name' => 'Israeli new shekel', 'symbol' => '₪', 'decimal_places' => 2];
|
||||
$currencies[] = ['code' => 'CHF', 'name' => 'Swiss franc', 'symbol' => 'CHF', 'decimal_places' => 2];
|
||||
$currencies[] = ['code' => 'HRK', 'name' => 'Croatian kuna', 'symbol' => 'kn', 'decimal_places' => 2];
|
||||
$currencies[] = ['code' => 'HKD', 'name' => 'Hong Kong dollar', 'symbol' => 'HK$', 'decimal_places' => 2];
|
||||
$currencies[] = ['code' => 'CHF', 'name' => 'Swiss franc', 'symbol' => 'CHF', 'decimal_places' => 2];
|
||||
$currencies[] = ['code' => 'NOK', 'name' => 'Norwegian krone', 'symbol' => 'kr.', 'decimal_places' => 2];
|
||||
$currencies[] = ['code' => 'CZK', 'name' => 'Czech koruna', 'symbol' => 'Kč', 'decimal_places' => 2];
|
||||
|
||||
foreach ($currencies as $currency) {
|
||||
if (null === TransactionCurrency::where('code', $currency['code'])->first()) {
|
||||
|
753
package-lock.json
generated
753
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -80,11 +80,18 @@ function drawChart() {
|
||||
|
||||
// left to spend
|
||||
if (key.substring(0, 17) === 'left-to-spend-in-') {
|
||||
left_to_spend_top.push(data[key].value_parsed);
|
||||
left_to_spend_bottom.push(data[key].sub_title);
|
||||
if (parseFloat(data[key].monetary_value) > 0) {
|
||||
if(true === data[key].no_available_budgets) {
|
||||
left_to_spend_top.push('---');
|
||||
left_to_spend_bottom.push('---');
|
||||
keepGreen = true;
|
||||
}
|
||||
if(false === data[key].no_available_budgets) {
|
||||
left_to_spend_top.push(data[key].value_parsed);
|
||||
left_to_spend_bottom.push(data[key].sub_title);
|
||||
if (parseFloat(data[key].monetary_value) > 0) {
|
||||
keepGreen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// net worth
|
||||
|
@@ -47,6 +47,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{{ $t('firefly.name') }}</th>
|
||||
<th scope="col">{{ $t('firefly.expires_at') }}</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -57,6 +58,10 @@
|
||||
<td style="vertical-align: middle;">
|
||||
{{ token.name }}
|
||||
</td>
|
||||
<!-- expires at -->
|
||||
<td style="vertical-align: middle;">
|
||||
{{ new Date(token.expires_at).toLocaleString() }}
|
||||
</td>
|
||||
|
||||
<!-- Delete Button -->
|
||||
<td style="vertical-align: middle;">
|
||||
@@ -232,7 +237,7 @@ export default {
|
||||
},
|
||||
|
||||
/**
|
||||
* Get all of the available scopes.
|
||||
* Get all the available scopes.
|
||||
*/
|
||||
getScopes() {
|
||||
axios.get('./oauth/scopes')
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
@@ -103,7 +104,7 @@
|
||||
"profile_oauth_confidential": "Soukrom\u00e1 aplikace",
|
||||
"profile_oauth_confidential_help": "Po\u017eadovat aby se klienti autorizovali. Soukrom\u00e9 aplikace mohou bezpe\u010dn\u011b pracovat s p\u0159\u00edstupov\u00fdmi \u00fadaji bez toho aby je zve\u0159ejnily. Ve\u0159ejn\u00e9 aplikace, nativn\u00ed nebo JavaScriptov\u00e9 SPA, toho schopn\u00e9 nejsou.",
|
||||
"multi_account_warning_unknown": "Depending on the type of transaction you create, the source and\/or destination account of subsequent splits may be overruled by whatever is defined in the first split of the transaction.",
|
||||
"multi_account_warning_withdrawal": "Zdrojov\u00fd \u00fa\u010del v\u0161ech n\u00e1sleduj\u00edc\u00edch rozd\u011blen\u00ed je ovl\u00e1dan\u00fd zdrojov\u00fdm \u00fa\u010dtem prvn\u00edho rozd\u011blen\u00ed transakce.",
|
||||
"multi_account_warning_withdrawal": "Zdrojov\u00fd \u00fa\u010det cel\u00e9 transakce je ovl\u00e1dan\u00fd prvn\u00edm rozd\u011blen\u00edm.",
|
||||
"multi_account_warning_deposit": "C\u00edlov\u00fd \u00fa\u010del v\u0161ech n\u00e1sleduj\u00edc\u00edch rozd\u011blen\u00ed je ovl\u00e1dan\u00fd c\u00edlov\u00fdm \u00fa\u010dtem prvn\u00edho rozd\u011blen\u00ed transakce.",
|
||||
"multi_account_warning_transfer": "Zdrojov\u00fd i c\u00edlov\u00fd \u00fa\u010det v\u0161ech n\u00e1sleduj\u00edc\u00edch rozd\u011blen\u00ed jsou ovl\u00e1d\u00e1ny zdrojov\u00fdm a c\u00edlov\u00fdm \u00fa\u010dtem prvn\u00edho rozd\u011blen\u00ed transakce.",
|
||||
"webhook_trigger_STORE_TRANSACTION": "Po vytvo\u0159en\u00ed transakce",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Finanzverwaltungen",
|
||||
"administrations_index_menu": "Finanzverwaltung",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III wird bald die M\u00f6glichkeit erhalten, mehrere Finanzverwaltungen zu verwalten. Im Moment verf\u00fcgen Sie nur \u00fcber eine. Sie k\u00f6nnen den Titel dieser Verwaltung und ihre eigene W\u00e4hrung festlegen. Dies ersetzt die bisherige Einstellung, bei der Sie Ihre \u201eStandardw\u00e4hrung\u201c festlegen konnten. Diese Einstellung ist jetzt an die Finanzverwaltung gebunden und kann f\u00fcr jede Verwaltung unterschiedlich sein.",
|
||||
"administration_currency_form_help": "Es kann l\u00e4nger dauern, bis die Seite geladen ist, wenn Sie die Landesw\u00e4hrung \u00e4ndern, da die Buchungen m\u00f6glicherweise in Ihre (neue) Landesw\u00e4hrung umgerechnet werden m\u00fcssen.",
|
||||
"administrations_page_edit_sub_title_js": "Finanzverwaltung \u201e{title}\u201c bearbeiten",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
@@ -46,7 +47,7 @@
|
||||
"tags": "Etiquetas",
|
||||
"no_budget": "(sin presupuesto)",
|
||||
"no_bill": "(no subscription)",
|
||||
"category": "Categoria",
|
||||
"category": "Categor\u00eda",
|
||||
"attachments": "Archivos adjuntos",
|
||||
"notes": "Notas",
|
||||
"external_url": "URL externa",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Administrations financi\u00e8res",
|
||||
"administrations_index_menu": "Administrations financi\u00e8res",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III aura bient\u00f4t la possibilit\u00e9 de g\u00e9rer plusieurs administrations financi\u00e8res. Pour le moment, vous n'en avez qu'une. Vous pouvez d\u00e9finir le titre de cette administration et de sa devise locale. Cela remplace le param\u00e8tre pr\u00e9c\u00e9dent o\u00f9 vous d\u00e9finissiez votre \"devise par d\u00e9faut\". Ce param\u00e8tre est d\u00e9sormais li\u00e9 \u00e0 l'administration financi\u00e8re et peut \u00eatre diff\u00e9rent par administration.",
|
||||
"administration_currency_form_help": "La page peut mettre longtemps \u00e0 charger si vous modifiez la devise locale, car des op\u00e9rations peuvent n\u00e9cessiter une conversion vers votre (nouvelle) devise locale.",
|
||||
"administrations_page_edit_sub_title_js": "Modifier l'administration financi\u00e8re \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Amministrazioni finanziarie",
|
||||
"administrations_index_menu": "Amministrazioni finanziarie",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III avr\u00e0 presto la possibilit\u00e0 di gestire pi\u00f9 amministrazioni finanziarie. In questo momento, hai solo il titolo. Puoi impostare il titolo di questa amministrazione e la sua valuta nativa. Questo sostituisce l'impostazione precedente, in cui si impostava la \"valuta predefinita\". Questa situazione \u00e8 ora legata all'amministrazione finanziaria e pu\u00f2 essere diversa per amministrazione.",
|
||||
"administration_currency_form_help": "Se modifichi la valuta nativa, il caricamento della pagina potrebbe richiedere molto tempo, poich\u00e9 potrebbe essere necessario convertire la transazione nella (nuova) valuta nativa.",
|
||||
"administrations_page_edit_sub_title_js": "Modifica amministrazione finanziaria \"{title}\"",
|
||||
@@ -30,7 +31,7 @@
|
||||
"apply_rules_checkbox": "Applica le regole",
|
||||
"fire_webhooks_checkbox": "Esegui webhook",
|
||||
"no_budget_pointer": "Sembra che tu non abbia ancora dei budget. Dovresti crearne alcuni nella pagina dei <a href=\"budgets\">budget<\/a>. I budget possono aiutarti a tenere traccia delle spese.",
|
||||
"no_bill_pointer": "Sembra che tu non abbia ancora un abbonamento. Dovresti crearne alcuni sulla pagina <a href=\"subscriptions\">abbonamento<\/a>. Gli abbonamenti possono aiutarti a tenere traccia delle spese.",
|
||||
"no_bill_pointer": "Sembra che tu non abbia ancora un pagamento ricorrente. Dovresti crearne alcuni sulla pagina <a href=\"subscriptions\">pagamenti ricorrenti<\/a>. I pagamenti ricorrenti possono aiutarti a tenere traccia delle spese.",
|
||||
"source_account": "Conto di origine",
|
||||
"hidden_fields_preferences": "Puoi abilitare maggiori opzioni per le transazioni nelle tue <a href=\"preferences\">impostazioni<\/a>.",
|
||||
"destination_account": "Conto destinazione",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
@@ -153,7 +154,7 @@
|
||||
"url": "URL",
|
||||
"active": "\ud65c\uc131",
|
||||
"interest_date": "\uc774\uc790 \ub0a0\uc9dc",
|
||||
"administration_currency": "Native currency",
|
||||
"administration_currency": "\uc790\uad6d \ud1b5\ud654",
|
||||
"title": "\uc81c\ubaa9",
|
||||
"date": "\ub0a0\uc9dc",
|
||||
"book_date": "\uc608\uc57d\uc77c",
|
||||
@@ -173,7 +174,7 @@
|
||||
"list": {
|
||||
"title": "\uc81c\ubaa9",
|
||||
"active": "\ud65c\uc131 \uc0c1\ud0dc\uc785\ub2c8\uae4c?",
|
||||
"native_currency": "Native currency",
|
||||
"native_currency": "\uc790\uad6d \ud1b5\ud654",
|
||||
"trigger": "\ud2b8\ub9ac\uac70",
|
||||
"response": "\uc751\ub2f5",
|
||||
"delivery": "\uc804\ub2ec",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Grootboeken",
|
||||
"administrations_index_menu": "Grootboeken",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III krijgt binnenkort het vermogen om meerdere grootboeken te beheren. Op dit moment kan dat nog niet. Je kan de titel van dit grootboek instellen en de basisvaluta. Dit vervangt de voorgaande manier waarop je je \"standaardvaluta\" zou instellen. Deze instelling is nu gekoppeld aan dit grootboek, en kan per grootboek verschillend zijn.",
|
||||
"administration_currency_form_help": "Het wijzigen van deze instelling betekent dat heel veel transacties omgerekend moeten worden naar je nieuwe basisvaluta en dat kan lang duren.",
|
||||
"administrations_page_edit_sub_title_js": "Wijzig grootboek \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Ustawienia finansowe",
|
||||
"administrations_index_menu": "Ustawienia finansowe",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III wkr\u00f3tce uzyska mo\u017cliwo\u015b\u0107 zarz\u0105dzania wieloma ustawieniami finansowymi. W tej chwili jest tylko jedno domy\u015blne ustawienie. Mo\u017cesz ustawi\u0107 jego tytu\u0142 i natywn\u0105 walut\u0119. To zast\u0119puje poprzednie ustawienia, w kt\u00f3rym mo\u017cna by\u0142o ustawi\u0107 \"domy\u015bln\u0105 walut\u0119\". Jest ona obecnie powi\u0105zana z wybranym ustawieniem finansowym i mo\u017ce by\u0107 zmienione w tej zak\u0142adce.",
|
||||
"administration_currency_form_help": "Wczytywanie strony mo\u017ce zaj\u0105\u0107 du\u017co czasu, je\u015bli zmienisz natywn\u0105 walut\u0119, poniewa\u017c transakcja mo\u017ce wymaga\u0107 przewalutowania na (now\u0105) natywn\u0105 walut\u0119.",
|
||||
"administrations_page_edit_sub_title_js": "Edytuj ustawienia finansowe \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "\u0424\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0435 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u044b",
|
||||
"administrations_index_menu": "\u0424\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0435 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u044b",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III \u0432\u0441\u043a\u043e\u0440\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u043c\u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f\u043c\u0438. \u0421\u0435\u0439\u0447\u0430\u0441 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0434\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u0435\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0432\u0430\u043b\u044e\u0442\u0443. \u042d\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 \"\u0432\u0430\u043b\u044e\u0442\u0443 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\". \u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u044d\u0442\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u0441 \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u043e\u0439 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0435\u0439 \u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u043e\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.",
|
||||
"administration_currency_form_help": "\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u044f\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0432\u0430\u043b\u044e\u0442\u0443, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0430 \u0432 \u043d\u043e\u0432\u0443\u044e \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0432\u0430\u043b\u044e\u0442\u0443.",
|
||||
"administrations_page_edit_sub_title_js": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u0438\u043d\u0430\u043d\u0441\u0430\u043c\u0438 \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Finan\u010dne administracije",
|
||||
"administrations_index_menu": "Finan\u010dne administracije",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III bo kmalu dobil mo\u017enost upravljanja ve\u010d finan\u010dnih administracij. Trenutno imate samo eno. Nastavite lahko naziv te administracije in njeno doma\u010do valuto. To nadome\u0161\u010da prej\u0161njo nastavitev, kjer bi nastavili svojo \"privzeto valuto\". Ta nastavitev je zdaj vezana na finan\u010dno administracijo in se lahko razlikuje glede na administracijo.",
|
||||
"administration_currency_form_help": "\u010ce spremenite doma\u010do valuto, lahko traja dolgo \u010dasa, da se stran nalo\u017ei, ker bo transakcijo morda treba pretvoriti v va\u0161o (novo) doma\u010do valuto.",
|
||||
"administrations_page_edit_sub_title_js": "Uredi finan\u010dno administracijo \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "\u0424\u0456\u043d\u0430\u043d\u0441\u043e\u0432\u0456 \u0430\u0434\u043c\u0456\u043d\u0456\u0441\u0442\u0440\u0430\u0446\u0456\u0457",
|
||||
"administrations_index_menu": "\u0424\u0456\u043d\u0430\u043d\u0441\u043e\u0432\u0456 \u0430\u0434\u043c\u0456\u043d\u0456\u0441\u0442\u0440\u0430\u0446\u0456\u0457",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "Financial administrations",
|
||||
"administrations_index_menu": "Financial administrations",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III will soon get the ability to manage multiple financial administrations. Right now, you only have the one. You can set the title of this administration and its native currency. This replaces the previous setting where you would set your \"default currency\". This setting is now tied to the financial administration and can be different per administration.",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
|
@@ -2,9 +2,10 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "\u8d22\u52a1\u7ba1\u7406",
|
||||
"administrations_index_menu": "\u8d22\u52a1\u7ba1\u7406",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III \u4e0d\u4e45\u5c06\u80fd\u591f\u7ba1\u7406\u591a\u4e2a\u8d22\u52a1\u7ba1\u7406\u3002 \u73b0\u5728\uff0c\u4f60\u53ea\u80fd\u6709\u4e00\u4e2a\u8d22\u52a1\u7ba1\u7406\u3002\u4f60\u53ef\u4ee5\u8bbe\u7f6e\u8fd9\u4e2a\u8d22\u52a1\u7ba1\u7406\u7684\u6807\u9898\u53ca\u5176\u5f53\u5730\u8d27\u5e01\u3002 \u8fd9\u5c06\u53d6\u4ee3\u60a8\u5148\u524d\u8bbe\u7f6e\u7684\u201c\u9ed8\u8ba4\u8d27\u5e01\u201d\u3002 \u8fd9\u79cd\u8bbe\u7f6e\u73b0\u5728\u4e0e\u8d22\u52a1\u7ba1\u7406\u6302\u94a9\uff0c\u6bcf\u4e2a\u7ba1\u7406\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u8bbe\u7f6e\u3002",
|
||||
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
|
||||
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
|
||||
"administration_currency_form_help": "\u5982\u679c\u60a8\u66f4\u6539\u672c\u5730\u8d27\u5e01\uff0c\u9875\u9762\u52a0\u8f7d\u53ef\u80fd\u9700\u8981\u5f88\u957f\u65f6\u95f4\uff0c\u56e0\u4e3a\u4ea4\u6613\u53ef\u80fd\u9700\u8981\u8f6c\u6362\u4e3a\u60a8\u7684(\u65b0)\u672c\u5730\u8d27\u5e01\u3002",
|
||||
"administrations_page_edit_sub_title_js": "\u7f16\u8f91\u8d22\u52a1\u7ba1\u7406{title}",
|
||||
"table": "\u8868\u683c",
|
||||
"welcome_back": "\u4eca\u5929\u7406\u8d22\u4e86\u5417\uff1f",
|
||||
"flash_error": "\u9519\u8bef\uff01",
|
||||
@@ -140,12 +141,12 @@
|
||||
"visit_webhook_url": "\u8bbf\u95ee webhook URL",
|
||||
"reset_webhook_secret": "\u91cd\u7f6e webhook \u5bc6\u94a5",
|
||||
"header_exchange_rates": "\u6c47\u7387",
|
||||
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">the documentation<\/a>.",
|
||||
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
|
||||
"exchange_rates_intro_rates": "Firefly III uses the following exchange rates. The inverse is automatically calculated when it is not provided. If no exchange rate exists for the date of the transaction, Firefly III will go back in time to find one. If none are present, the rate \"1\" will be used.",
|
||||
"exchange_rates_intro": "Frefly III \u652f\u6301\u4e0b\u8f7d\u548c\u4f7f\u7528\u6c47\u7387\u3002\u8bf7\u5728 <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">\u8fd9\u4efd\u6587\u6863<\/a>\u4e2d\u9605\u8bfb\u66f4\u591a\u3002",
|
||||
"exchange_rates_from_to": "\u4ece {from} \u5230 {to} \u7684\u6c47\u7387\uff08\u4ee5\u53ca\u53cd\u5411\uff09",
|
||||
"exchange_rates_intro_rates": "Firefly III \u91c7\u7528\u4ee5\u4e0b\u6c47\u7387\u3002\u5982\u679c\u6ca1\u6709\u63d0\u4f9b\u53cd\u5411\u6c47\u7387\u5219\u81ea\u52a8\u8ba1\u7b97\u3002 \u5982\u679c\u4ea4\u6613\u65e5\u671f\u4e0d\u5b58\u5728\u6c47\u7387\uff0cFifrefly III \u5c06\u5bfb\u627e\u524d\u4e00\u4e2a\u53ef\u7528\u65e5\u671f\u7684\u6c47\u7387\u3002 \u5982\u679c\u6ca1\u6709\uff0c\u5c06\u6309\u6c47\u7387\u4e3a 1 \u8fdb\u884c\u8ba1\u7b97\u3002",
|
||||
"header_exchange_rates_rates": "\u6c47\u7387",
|
||||
"header_exchange_rates_table": "Table with exchange rates",
|
||||
"help_rate_form": "On this day, how many {to} will you get for one {from}?",
|
||||
"header_exchange_rates_table": "\u6c47\u7387\u8868",
|
||||
"help_rate_form": "\u5728\u8fd9\u4e00\u5929\uff0c\u4f60\u80fd\u4ece\u6bcf 1 \u4e2a\u5355\u4f4d\u7684 {from} \u83b7\u5f97\u591a\u5c11 {to}\uff1f",
|
||||
"add_new_rate": "\u6dfb\u52a0\u65b0\u6c47\u7387",
|
||||
"save_new_rate": "\u4fdd\u5b58\u65b0\u6c47\u7387"
|
||||
},
|
||||
@@ -168,7 +169,7 @@
|
||||
"webhook_delivery": "\u53d1\u9001\u683c\u5f0f",
|
||||
"from_currency_to_currency": "{from}→{to}",
|
||||
"to_currency_from_currency": "{to}→{from}",
|
||||
"rate": "\u8bc4\u7ea7"
|
||||
"rate": "\u6c47\u7387"
|
||||
},
|
||||
"list": {
|
||||
"title": "\u6807\u9898",
|
||||
|
@@ -2,6 +2,7 @@
|
||||
"firefly": {
|
||||
"administrations_page_title": "\u591a\u500b\u8ca1\u52d9\u7ba1\u7406",
|
||||
"administrations_index_menu": "\u591a\u500b\u8ca1\u52d9\u7ba1\u7406",
|
||||
"expires_at": "Expires at",
|
||||
"temp_administrations_introduction": "Firefly III \u5373\u5c07\u652f\u63f4\u540c\u6642\u7ba1\u7406\u591a\u500b\u8ca1\u52d9\u7ba1\u7406\u3002\u76ee\u524d\u60a8\u53ea\u6709\u4e00\u500b\u3002\u60a8\u53ef\u5728\u6b64\u8a2d\u5b9a\u5176\u6a19\u984c\u8207\u672c\u5e63\uff0c\u9019\u53d6\u4ee3\u4e86\u5148\u524d\u7684\u300c\u9810\u8a2d\u8ca8\u5e63\u300d\u8a2d\u5b9a\u3002\u6b64\u8a2d\u5b9a\u73fe\u5728\u7d81\u5b9a\u65bc\u8a72\u8ca1\u52d9\u7ba1\u7406\uff0c\u4e26\u53ef\u56e0\u4e0d\u540c\u8ca1\u52d9\u7ba1\u7406\u800c\u7570\u3002",
|
||||
"administration_currency_form_help": "\u5982\u679c\u60a8\u66f4\u6539\u4e86\u672c\u5e63\uff0c\u53ef\u80fd\u9700\u8981\u4e00\u6bb5\u6642\u9593\u624d\u80fd\u8f09\u5165\u9801\u9762\uff0c\u56e0\u70ba\u4ea4\u6613\u53ef\u80fd\u9700\u8981\u8f49\u63db\u70ba\uff08\u65b0\uff09\u672c\u5e63\u3002",
|
||||
"administrations_page_edit_sub_title_js": "\u7de8\u8f2f\u8ca1\u52d9\u7ba1\u7406\u300c{title}\u300d",
|
||||
|
@@ -8,26 +8,22 @@
|
||||
"postinstall": "patch-package --error-on-fail"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^1.8.2",
|
||||
"laravel-vite-plugin": "^1.0.5",
|
||||
"patch-package": "^8.0.0",
|
||||
"sass": "^1.78.0",
|
||||
"axios": "^1",
|
||||
"laravel-vite-plugin": "^1",
|
||||
"patch-package": "^8",
|
||||
"sass": "^1",
|
||||
"vite": "^6",
|
||||
"vite-plugin-manifest-sri": "^0.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ag-grid-community/client-side-row-model": "^32.0.2",
|
||||
"@ag-grid-community/core": "^32.0.2",
|
||||
"@ag-grid-community/infinite-row-model": "^32.0.2",
|
||||
"@ag-grid-community/styles": "^33.0.2",
|
||||
"@fortawesome/fontawesome-free": "^6.4.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"admin-lte": "^4.0.0-alpha3",
|
||||
"admin-lte": "^4.0.0-beta3",
|
||||
"alpinejs": "^3.13.7",
|
||||
"bootstrap": "^5.3.0",
|
||||
"bootstrap5-autocomplete": "^1.1.22",
|
||||
"bootstrap5-tags": "^1.7",
|
||||
"chart.js": "^4.4.0",
|
||||
"bootstrap": "^5",
|
||||
"bootstrap5-autocomplete": "^1",
|
||||
"bootstrap5-tags": "^1",
|
||||
"chart.js": "^4",
|
||||
"chartjs-adapter-date-fns": "^3.0.0",
|
||||
"chartjs-chart-sankey": "^0.14.0",
|
||||
"date-fns": "^4.0.0",
|
||||
|
36
resources/assets/v2/src/api/v1/chart/account/dashboard.js
Normal file
36
resources/assets/v2/src/api/v1/chart/account/dashboard.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* overview.js
|
||||
* Copyright (c) 2022 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/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
import {format} from "date-fns";
|
||||
|
||||
export default class Dashboard {
|
||||
dashboard(start, end) {
|
||||
let startStr = format(start, 'y-MM-dd');
|
||||
let endStr = format(end, 'y-MM-dd');
|
||||
return api.get('/api/v1/chart/account/dashboard', {params: {fix: true, start: startStr, end: endStr}});
|
||||
}
|
||||
|
||||
expense(start, end) {
|
||||
let startStr = format(start, 'y-MM-dd');
|
||||
let endStr = format(end, 'y-MM-dd');
|
||||
return api.get('/api/v1/chart/account/expense-dashboard', {params: {start: startStr, end: endStr}});
|
||||
}
|
||||
}
|
30
resources/assets/v2/src/api/v1/chart/budget/dashboard.js
Normal file
30
resources/assets/v2/src/api/v1/chart/budget/dashboard.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* overview.js
|
||||
* Copyright (c) 2022 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/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
import {format} from "date-fns";
|
||||
|
||||
export default class Dashboard {
|
||||
dashboard(start, end) {
|
||||
let startStr = format(start, 'y-MM-dd');
|
||||
let endStr = format(end, 'y-MM-dd');
|
||||
return api.get('/api/v1/chart/budget/dashboard', {params: {start: startStr, end: endStr}});
|
||||
}
|
||||
}
|
30
resources/assets/v2/src/api/v1/chart/category/dashboard.js
Normal file
30
resources/assets/v2/src/api/v1/chart/category/dashboard.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* overview.js
|
||||
* Copyright (c) 2022 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/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
import {format} from "date-fns";
|
||||
|
||||
export default class Dashboard {
|
||||
dashboard(start, end) {
|
||||
let startStr = format(start, 'y-MM-dd');
|
||||
let endStr = format(end, 'y-MM-dd');
|
||||
return api.get('/api/v1/chart/category/dashboard', {params: {start: startStr, end: endStr}});
|
||||
}
|
||||
}
|
@@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../boot/axios";
|
||||
import {api} from "../../../../boot/axios";
|
||||
import format from "date-fns/format";
|
||||
|
||||
export default class Get {
|
||||
@@ -37,6 +37,18 @@ export default class Get {
|
||||
return api.get('/api/v1/accounts/' + identifier, {params: params});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param identifier
|
||||
* @param params
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
show(identifier, params) {
|
||||
return api.get('/api/v1/accounts/' + identifier, {params: params});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param identifier
|
36
resources/assets/v2/src/api/v1/model/account/put.js
Normal file
36
resources/assets/v2/src/api/v1/model/account/put.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* list.js
|
||||
* Copyright (c) 2022 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/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
import format from "date-fns/format";
|
||||
|
||||
export default class Put {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param identifier
|
||||
* @param params
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
put(identifier, params) {
|
||||
return api.put('/api/v2/accounts/' + identifier, params);
|
||||
}
|
||||
|
||||
}
|
@@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../boot/axios";
|
||||
import {api} from "../../../../boot/axios";
|
||||
|
||||
export default class Post {
|
||||
post(fileName, attachableType, attachableId) {
|
35
resources/assets/v2/src/api/v1/model/budget/get.js
Normal file
35
resources/assets/v2/src/api/v1/model/budget/get.js
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* list.js
|
||||
* Copyright (c) 2022 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/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
import format from "date-fns/format";
|
||||
|
||||
export default class Get {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param params
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
list(params) {
|
||||
return api.get('/api/v2/budgets', {params: params});
|
||||
}
|
||||
|
||||
}
|
35
resources/assets/v2/src/api/v1/model/currency/get.js
Normal file
35
resources/assets/v2/src/api/v1/model/currency/get.js
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* list.js
|
||||
* Copyright (c) 2022 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/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
import format from "date-fns/format";
|
||||
|
||||
export default class Get {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param params
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
list(params) {
|
||||
return api.get('/api/v2/currencies', {params: params});
|
||||
}
|
||||
|
||||
}
|
35
resources/assets/v2/src/api/v1/model/piggy-bank/get.js
Normal file
35
resources/assets/v2/src/api/v1/model/piggy-bank/get.js
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* get.js
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
|
||||
export default class Get {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param params
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
list(params) {
|
||||
return api.get('/api/v1/piggy-banks', {params: params});
|
||||
}
|
||||
|
||||
}
|
42
resources/assets/v2/src/api/v1/model/subscription/get.js
Normal file
42
resources/assets/v2/src/api/v1/model/subscription/get.js
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* get.js
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
|
||||
export default class Get {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param params
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
list(params) {
|
||||
return api.get('/api/v1/subscriptions', {params: params});
|
||||
}
|
||||
|
||||
paid(params) {
|
||||
return api.get('/api/v1/subscriptions/sum/paid', {params: params});
|
||||
}
|
||||
|
||||
unpaid(params) {
|
||||
return api.get('/api/v1/subscriptions/sum/unpaid', {params: params});
|
||||
}
|
||||
}
|
37
resources/assets/v2/src/api/v1/model/transaction/get.js
Normal file
37
resources/assets/v2/src/api/v1/model/transaction/get.js
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* get.js
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
|
||||
export default class Get {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param params
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
list(params) {
|
||||
return api.get('/api/v1/transactions', {params: params});
|
||||
}
|
||||
show(id, params){
|
||||
return api.get('/api/v1/transactions/' + id, {params: params});
|
||||
}
|
||||
}
|
28
resources/assets/v2/src/api/v1/model/transaction/post.js
Normal file
28
resources/assets/v2/src/api/v1/model/transaction/post.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* post.js
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
|
||||
export default class Post {
|
||||
post(submission) {
|
||||
let url = '/api/v1/transactions';
|
||||
return api.post(url, submission);
|
||||
}
|
||||
}
|
28
resources/assets/v2/src/api/v1/model/transaction/put.js
Normal file
28
resources/assets/v2/src/api/v1/model/transaction/put.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* post.js
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
|
||||
export default class Put {
|
||||
put(submission, params) {
|
||||
let url = '/api/v1/transactions/' + parseInt(params.id);
|
||||
return api.put(url, submission);
|
||||
}
|
||||
}
|
45
resources/assets/v2/src/api/v1/model/user-group/get.js
Normal file
45
resources/assets/v2/src/api/v1/model/user-group/get.js
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* list.js
|
||||
* Copyright (c) 2022 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/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
import format from "date-fns/format";
|
||||
|
||||
export default class Get {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param identifier
|
||||
* @param params
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
show(identifier, params) {
|
||||
return api.get('/api/v2/user-groups/' + identifier, {params: params});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param params
|
||||
* @returns {Promise<AxiosResponse<any>>}
|
||||
*/
|
||||
index(params) {
|
||||
return api.get('/api/v2/user-groups', {params: params});
|
||||
}
|
||||
|
||||
}
|
33
resources/assets/v2/src/api/v1/model/user-group/post.js
Normal file
33
resources/assets/v2/src/api/v1/model/user-group/post.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* post.js
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
|
||||
export default class Post {
|
||||
post(submission) {
|
||||
let url = './api/v2/user-groups';
|
||||
return api.post(url, submission);
|
||||
}
|
||||
|
||||
use(groupId) {
|
||||
let url = './api/v2/user-groups/' + groupId + '/use';
|
||||
return api.post(url, {});
|
||||
}
|
||||
}
|
28
resources/assets/v2/src/api/v1/model/user-group/put.js
Normal file
28
resources/assets/v2/src/api/v1/model/user-group/put.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* post.js
|
||||
* Copyright (c) 2023 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {api} from "../../../../boot/axios";
|
||||
|
||||
export default class Put {
|
||||
put(submission, params) {
|
||||
let url = '/api/v2/user-groups/' + parseInt(params.id);
|
||||
return api.put(url, submission);
|
||||
}
|
||||
}
|
@@ -25,7 +25,7 @@ export default class Dashboard {
|
||||
dashboard(start, end) {
|
||||
let startStr = format(start, 'y-MM-dd');
|
||||
let endStr = format(end, 'y-MM-dd');
|
||||
return api.get('/api/v2/chart/account/dashboard', {params: {filter: {start: startStr, end: endStr}}});
|
||||
return api.get('/api/v2/chart/account/dashboard', {params: {start: startStr, end: endStr}});
|
||||
}
|
||||
|
||||
expense(start, end) {
|
||||
|
@@ -24,8 +24,8 @@ import i18next from "i18next";
|
||||
import {format} from "date-fns";
|
||||
import formatMoney from "../../util/format-money.js";
|
||||
|
||||
import Get from "../../api/v2/model/account/get.js";
|
||||
import Put from "../../api/v2/model/account/put.js";
|
||||
import Get from "../../api/v1/model/account/get.js";
|
||||
import Put from "../../api/v1/model/account/put.js";
|
||||
import AccountRenderer from "../../support/renderers/AccountRenderer.js";
|
||||
import {showInternalsButton} from "../../support/page-settings/show-internals-button.js";
|
||||
import {showWizardButton} from "../../support/page-settings/show-wizard-button.js";
|
||||
|
@@ -20,7 +20,7 @@
|
||||
|
||||
import '../../boot/bootstrap.js';
|
||||
import dates from "../shared/dates.js";
|
||||
import Post from "../../api/v2/model/user-group/post.js";
|
||||
import Post from "../../api/v1/model/user-group/post.js";
|
||||
import i18next from "i18next";
|
||||
|
||||
|
||||
|
@@ -20,10 +20,10 @@
|
||||
|
||||
import '../../boot/bootstrap.js';
|
||||
import dates from "../shared/dates.js";
|
||||
import Post from "../../api/v2/model/user-group/post.js";
|
||||
import Post from "../../api/v1/model/user-group/post.js";
|
||||
import i18next from "i18next";
|
||||
import Get from "../../api/v2/model/user-group/get.js";
|
||||
import Put from "../../api/v2/model/user-group/put.js";
|
||||
import Get from "../../api/v1/model/user-group/get.js";
|
||||
import Put from "../../api/v1/model/user-group/put.js";
|
||||
|
||||
|
||||
let administrations = function () {
|
||||
|
@@ -23,11 +23,9 @@ import dates from "../shared/dates.js";
|
||||
import i18next from "i18next";
|
||||
import {format} from "date-fns";
|
||||
|
||||
import '@ag-grid-community/styles/ag-grid.css';
|
||||
import '@ag-grid-community/styles/ag-theme-alpine.css';
|
||||
import '../../css/grid-ff3-theme.css';
|
||||
import Get from "../../api/v2/model/user-group/get.js";
|
||||
import Post from "../../api/v2/model/user-group/post.js";
|
||||
import Get from "../../api/v1/model/user-group/get.js";
|
||||
import Post from "../../api/v1/model/user-group/post.js";
|
||||
|
||||
let index = function () {
|
||||
return {
|
||||
|
@@ -20,9 +20,9 @@
|
||||
|
||||
import {getVariable} from "../../store/get-variable.js";
|
||||
import {setVariable} from "../../store/set-variable.js";
|
||||
import Dashboard from "../../api/v2/chart/account/dashboard.js";
|
||||
import Dashboard from "../../api/v1/chart/account/dashboard.js";
|
||||
import formatMoney from "../../util/format-money.js";
|
||||
import Get from "../../api/v2/model/account/get.js";
|
||||
import Get from "../../api/v1/model/account/get.js";
|
||||
import {Chart} from 'chart.js';
|
||||
import {getDefaultChartSettings} from "../../support/default-chart-settings.js";
|
||||
import {getCacheKey} from "../../support/get-cache-key.js";
|
||||
@@ -39,12 +39,12 @@ export default () => ({
|
||||
loading: false,
|
||||
loadingAccounts: false,
|
||||
accountList: [],
|
||||
autoConversion: false,
|
||||
autoConversionAvailable: false,
|
||||
convertToNative: false,
|
||||
convertToNativeAvailable: false,
|
||||
chartOptions: null,
|
||||
switchAutoConversion() {
|
||||
this.autoConversion = !this.autoConversion;
|
||||
setVariable('autoConversion', this.autoConversion);
|
||||
switchConvertToNative() {
|
||||
this.convertToNative = !this.convertToNative;
|
||||
setVariable('convertToNative', this.convertToNative);
|
||||
},
|
||||
localCacheKey(type) {
|
||||
return 'ds_accounts_' + type;
|
||||
@@ -90,18 +90,18 @@ export default () => ({
|
||||
dataset.label = current.label;
|
||||
|
||||
// use the "native" currency code and use the "native_entries" as array
|
||||
if (this.autoConversion) {
|
||||
currencies.push(current.native_currency_code);
|
||||
dataset.currency_code = current.native_currency_code;
|
||||
collection = Object.values(current.native_entries);
|
||||
yAxis = 'y' + current.native_currency_code;
|
||||
}
|
||||
if (!this.autoConversion) {
|
||||
// if (this.convertToNative) {
|
||||
// currencies.push(current.native_currency_code);
|
||||
// dataset.currency_code = current.native_currency_code;
|
||||
// collection = Object.values(current.native_entries);
|
||||
// yAxis = 'y' + current.native_currency_code;
|
||||
// }
|
||||
// if (!this.convertToNative) {
|
||||
yAxis = 'y' + current.currency_code;
|
||||
dataset.currency_code = current.currency_code;
|
||||
currencies.push(current.currency_code);
|
||||
collection = Object.values(current.entries);
|
||||
}
|
||||
// }
|
||||
dataset.yAxisID = yAxis;
|
||||
dataset.data = collection;
|
||||
|
||||
@@ -217,12 +217,12 @@ export default () => ({
|
||||
for (let iii = 0; iii < current.attributes.transactions.length; iii++) {
|
||||
let currentTransaction = current.attributes.transactions[iii];
|
||||
//console.log(currentTransaction);
|
||||
let nativeAmountRaw = 'withdrawal' === currentTransaction.type ? parseFloat(currentTransaction.native_amount) * -1 : parseFloat(currentTransaction.native_amount);
|
||||
//let nativeAmountRaw = 'withdrawal' === currentTransaction.type ? parseFloat(currentTransaction.native_amount) * -1 : parseFloat(currentTransaction.native_amount);
|
||||
let amountRaw = 'withdrawal' === currentTransaction.type ? parseFloat(currentTransaction.amount) * -1 : parseFloat(currentTransaction.amount);
|
||||
|
||||
// if transfer and source is this account, multiply again
|
||||
if('transfer' === currentTransaction.type && parseInt(currentTransaction.source_id) === accountId) { //
|
||||
nativeAmountRaw = nativeAmountRaw * -1;
|
||||
// nativeAmountRaw = nativeAmountRaw * -1;
|
||||
amountRaw = amountRaw * -1;
|
||||
}
|
||||
|
||||
@@ -232,8 +232,8 @@ export default () => ({
|
||||
type: currentTransaction.type,
|
||||
amount_raw: amountRaw,
|
||||
amount: formatMoney(amountRaw, currentTransaction.currency_code),
|
||||
native_amount_raw: nativeAmountRaw,
|
||||
native_amount: formatMoney(nativeAmountRaw, currentTransaction.native_currency_code),
|
||||
// native_amount_raw: nativeAmountRaw,
|
||||
// native_amount: formatMoney(nativeAmountRaw, currentTransaction.native_currency_code),
|
||||
});
|
||||
}
|
||||
groups.push(group);
|
||||
@@ -244,7 +244,7 @@ export default () => ({
|
||||
order: parent.attributes.order,
|
||||
id: parent.id,
|
||||
balance: parent.attributes.balance,
|
||||
native_balance: parent.attributes.native_balance,
|
||||
//native_balance: parent.attributes.native_balance,
|
||||
groups: groups,
|
||||
});
|
||||
// console.log(parent.attributes);
|
||||
@@ -266,12 +266,12 @@ export default () => ({
|
||||
|
||||
init() {
|
||||
// console.log('accounts init');
|
||||
Promise.all([getVariable('viewRange', '1M'), getVariable('autoConversion', false), getVariable('language', 'en_US'),
|
||||
Promise.all([getVariable('viewRange', '1M'), getVariable('convertToNative', false), getVariable('language', 'en_US'),
|
||||
getConfiguration('cer.enabled', false)
|
||||
]).then((values) => {
|
||||
//console.log('accounts after promises');
|
||||
this.autoConversion = values[1] && values[3];
|
||||
this.autoConversionAvailable = values[3];
|
||||
this.convertToNative = values[1] && values[3];
|
||||
this.convertToNativeAvailable = values[3];
|
||||
afterPromises = true;
|
||||
|
||||
// main dashboard chart:
|
||||
@@ -289,11 +289,11 @@ export default () => ({
|
||||
this.loadChart();
|
||||
this.loadAccounts();
|
||||
});
|
||||
window.store.observe('autoConversion', () => {
|
||||
window.store.observe('convertToNative', () => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
// console.log('accounts observe autoconversion');
|
||||
// console.log('accounts observe convertToNative');
|
||||
this.loadChart();
|
||||
this.loadAccounts();
|
||||
});
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Summary from "../../api/v2/summary/index.js";
|
||||
import Summary from "../../api/v1/summary/index.js";
|
||||
import {format} from "date-fns";
|
||||
import {getVariable} from "../../store/get-variable.js";
|
||||
import formatMoney from "../../util/format-money.js";
|
||||
@@ -31,7 +31,7 @@ export default () => ({
|
||||
billBox: {paid: [], unpaid: []},
|
||||
leftBox: {left: [], perDay: []},
|
||||
netBox: {net: []},
|
||||
autoConversion: false,
|
||||
convertToNative: false,
|
||||
loading: false,
|
||||
boxData: null,
|
||||
boxOptions: null,
|
||||
@@ -42,8 +42,9 @@ export default () => ({
|
||||
const boxesCacheKey = getCacheKey('ds_boxes_data', {start: start, end: end});
|
||||
cleanupCache();
|
||||
|
||||
const cacheValid = window.store.get('cacheValid');
|
||||
//const cacheValid = window.store.get('cacheValid');
|
||||
let cachedData = window.store.get(boxesCacheKey);
|
||||
const cacheValid = false; // force refresh
|
||||
|
||||
if (cacheValid && typeof cachedData !== 'undefined') {
|
||||
this.boxData = cachedData;
|
||||
@@ -75,114 +76,56 @@ export default () => ({
|
||||
continue;
|
||||
}
|
||||
let key = current.key;
|
||||
// native (auto conversion):
|
||||
if (this.autoConversion) {
|
||||
if (key.startsWith('balance-in-native')) {
|
||||
this.balanceBox.amounts.push(formatMoney(current.value, current.currency_code));
|
||||
// prep subtitles (for later)
|
||||
if (!subtitles.hasOwnProperty(current.currency_code)) {
|
||||
subtitles[current.currency_code] = '';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// spent info is used in subtitle:
|
||||
if (key.startsWith('spent-in-native')) {
|
||||
// prep subtitles (for later)
|
||||
if (!subtitles.hasOwnProperty(current.currency_code)) {
|
||||
subtitles[current.currency_code] = '';
|
||||
}
|
||||
// append the amount spent.
|
||||
subtitles[current.currency_code] =
|
||||
subtitles[current.currency_code] +
|
||||
formatMoney(current.value, current.currency_code);
|
||||
continue;
|
||||
}
|
||||
// earned info is used in subtitle:
|
||||
if (key.startsWith('earned-in-native')) {
|
||||
// prep subtitles (for later)
|
||||
if (!subtitles.hasOwnProperty(current.currency_code)) {
|
||||
subtitles[current.currency_code] = '';
|
||||
}
|
||||
// prepend the amount earned.
|
||||
subtitles[current.currency_code] =
|
||||
formatMoney(current.value, current.currency_code) + ' + ' +
|
||||
subtitles[current.currency_code];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key.startsWith('bills-unpaid-in-native')) {
|
||||
this.billBox.unpaid.push(formatMoney(current.value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('bills-paid-in-native')) {
|
||||
this.billBox.paid.push(formatMoney(current.value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('left-to-spend-in-native')) {
|
||||
this.leftBox.left.push(formatMoney(current.value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('left-per-day-to-spend-in-native')) { // per day
|
||||
this.leftBox.perDay.push(formatMoney(current.value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('net-worth-in-native')) {
|
||||
this.netBox.net.push(formatMoney(current.value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
console.log('NOT NATIVE');
|
||||
if (key.startsWith('balance-in-')) {
|
||||
this.balanceBox.amounts.push(formatMoney(current.monetary_value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
// not native
|
||||
if (!this.autoConversion && !key.endsWith('native')) {
|
||||
if (key.startsWith('balance-in-')) {
|
||||
this.balanceBox.amounts.push(formatMoney(current.value, current.currency_code));
|
||||
continue;
|
||||
// spent info is used in subtitle:
|
||||
if (key.startsWith('spent-in-')) {
|
||||
// prep subtitles (for later)
|
||||
if (!subtitles.hasOwnProperty(current.currency_code)) {
|
||||
subtitles[current.currency_code] = '';
|
||||
}
|
||||
// spent info is used in subtitle:
|
||||
if (key.startsWith('spent-in-')) {
|
||||
// prep subtitles (for later)
|
||||
if (!subtitles.hasOwnProperty(current.currency_code)) {
|
||||
subtitles[current.currency_code] = '';
|
||||
}
|
||||
// append the amount spent.
|
||||
subtitles[current.currency_code] =
|
||||
subtitles[current.currency_code] +
|
||||
formatMoney(current.value, current.currency_code);
|
||||
continue;
|
||||
}
|
||||
// earned info is used in subtitle:
|
||||
if (key.startsWith('earned-in-')) {
|
||||
// prep subtitles (for later)
|
||||
if (!subtitles.hasOwnProperty(current.currency_code)) {
|
||||
subtitles[current.currency_code] = '';
|
||||
}
|
||||
// prepend the amount earned.
|
||||
subtitles[current.currency_code] =
|
||||
formatMoney(current.value, current.currency_code) + ' + ' +
|
||||
subtitles[current.currency_code];
|
||||
continue;
|
||||
// append the amount spent.
|
||||
subtitles[current.currency_code] =
|
||||
subtitles[current.currency_code] +
|
||||
formatMoney(current.monetary_value, current.currency_code);
|
||||
continue;
|
||||
}
|
||||
// earned info is used in subtitle:
|
||||
if (key.startsWith('earned-in-')) {
|
||||
// prep subtitles (for later)
|
||||
if (!subtitles.hasOwnProperty(current.currency_code)) {
|
||||
subtitles[current.currency_code] = '';
|
||||
}
|
||||
// prepend the amount earned.
|
||||
subtitles[current.currency_code] =
|
||||
formatMoney(current.monetary_value, current.currency_code) + ' + ' +
|
||||
subtitles[current.currency_code];
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (key.startsWith('bills-unpaid-in-')) {
|
||||
this.billBox.unpaid.push(formatMoney(current.value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('bills-paid-in-')) {
|
||||
this.billBox.paid.push(formatMoney(current.value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('left-to-spend-in-')) {
|
||||
this.leftBox.left.push(formatMoney(current.value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('left-per-day-to-spend-in-')) {
|
||||
this.leftBox.perDay.push(formatMoney(current.value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('net-worth-in-')) {
|
||||
this.netBox.net.push(formatMoney(current.value, current.currency_code));
|
||||
if (key.startsWith('bills-unpaid-in-')) {
|
||||
this.billBox.unpaid.push(formatMoney(current.monetary_value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('bills-paid-in-')) {
|
||||
this.billBox.paid.push(formatMoney(current.monetary_value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('left-to-spend-in-')) {
|
||||
this.leftBox.left.push(formatMoney(current.monetary_value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('left-per-day-to-spend-in-')) {
|
||||
this.leftBox.perDay.push(formatMoney(current.monetary_value, current.currency_code));
|
||||
continue;
|
||||
}
|
||||
if (key.startsWith('net-worth-in-')) {
|
||||
this.netBox.net.push(formatMoney(current.monetary_value, current.currency_code));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,10 +153,10 @@ export default () => ({
|
||||
init() {
|
||||
// console.log('boxes init');
|
||||
// TODO can be replaced by "getVariables"
|
||||
Promise.all([getVariable('viewRange'), getVariable('autoConversion', false)]).then((values) => {
|
||||
Promise.all([getVariable('viewRange'), getVariable('convertToNative', false)]).then((values) => {
|
||||
// console.log('boxes after promises');
|
||||
afterPromises = true;
|
||||
this.autoConversion = values[1];
|
||||
this.convertToNative = values[1];
|
||||
this.loadBoxes();
|
||||
});
|
||||
window.store.observe('end', () => {
|
||||
@@ -224,12 +167,12 @@ export default () => ({
|
||||
this.boxData = null;
|
||||
this.loadBoxes();
|
||||
});
|
||||
window.store.observe('autoConversion', (newValue) => {
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
// console.log('boxes observe autoConversion');
|
||||
this.autoConversion = newValue;
|
||||
// console.log('boxes observe convertToNative');
|
||||
this.convertToNative = newValue;
|
||||
this.loadBoxes();
|
||||
});
|
||||
},
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {getVariable} from "../../store/get-variable.js";
|
||||
import Dashboard from "../../api/v2/chart/budget/dashboard.js";
|
||||
import Dashboard from "../../api/v1/chart/budget/dashboard.js";
|
||||
import {getDefaultChartSettings} from "../../support/default-chart-settings.js";
|
||||
import formatMoney from "../../util/format-money.js";
|
||||
import {Chart} from 'chart.js';
|
||||
@@ -34,7 +34,7 @@ let afterPromises = false;
|
||||
|
||||
export default () => ({
|
||||
loading: false,
|
||||
autoConversion: false,
|
||||
convertToNative: false,
|
||||
loadChart() {
|
||||
if (true === this.loading) {
|
||||
return;
|
||||
@@ -134,7 +134,7 @@ export default () => ({
|
||||
// // convert to EUR yes no?
|
||||
let label = current.label + ' (' + current.currency_code + ')';
|
||||
options.data.labels.push(label);
|
||||
if (this.autoConversion) {
|
||||
if (this.convertToNative) {
|
||||
currencies.push(current.native_currency_code);
|
||||
// series 0: spent
|
||||
options.data.datasets[0].data.push(parseFloat(current.native_entries.spent) * -1);
|
||||
@@ -143,7 +143,7 @@ export default () => ({
|
||||
// series 2: overspent
|
||||
options.data.datasets[2].data.push(parseFloat(current.native_entries.overspent));
|
||||
}
|
||||
if (!this.autoConversion) {
|
||||
if (!this.convertToNative) {
|
||||
currencies.push(current.currency_code);
|
||||
// series 0: spent
|
||||
options.data.datasets[0].data.push(parseFloat(current.entries.spent) * -1);
|
||||
@@ -172,8 +172,8 @@ export default () => ({
|
||||
|
||||
|
||||
init() {
|
||||
Promise.all([getVariable('autoConversion', false)]).then((values) => {
|
||||
this.autoConversion = values[0];
|
||||
Promise.all([getVariable('convertToNative', false)]).then((values) => {
|
||||
this.convertToNative = values[0];
|
||||
afterPromises = true;
|
||||
if (false === this.loading) {
|
||||
this.loadChart();
|
||||
@@ -189,12 +189,12 @@ export default () => ({
|
||||
this.loadChart();
|
||||
}
|
||||
});
|
||||
window.store.observe('autoConversion', (newValue) => {
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
// console.log('boxes observe autoConversion');
|
||||
this.autoConversion = newValue;
|
||||
// console.log('boxes observe convertToNative');
|
||||
this.convertToNative = newValue;
|
||||
if (false === this.loading) {
|
||||
this.loadChart();
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {getVariable} from "../../store/get-variable.js";
|
||||
import Dashboard from "../../api/v2/chart/category/dashboard.js";
|
||||
import Dashboard from "../../api/v1/chart/category/dashboard.js";
|
||||
import {getDefaultChartSettings} from "../../support/default-chart-settings.js";
|
||||
import {Chart} from "chart.js";
|
||||
import formatMoney from "../../util/format-money.js";
|
||||
@@ -32,7 +32,7 @@ let afterPromises = false;
|
||||
|
||||
export default () => ({
|
||||
loading: false,
|
||||
autoConversion: false,
|
||||
convertToNative: false,
|
||||
generateOptions(data) {
|
||||
currencies = [];
|
||||
let options = getDefaultChartSettings('column');
|
||||
@@ -44,7 +44,7 @@ export default () => ({
|
||||
let current = data[i];
|
||||
let code = current.currency_code;
|
||||
// only use native code when doing auto conversion.
|
||||
if (this.autoConversion) {
|
||||
if (this.convertToNative) {
|
||||
code = current.native_currency_code;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ export default () => ({
|
||||
let yAxis = 'y';
|
||||
let current = data[i];
|
||||
let code = current.currency_code;
|
||||
if (this.autoConversion) {
|
||||
if (this.convertToNative) {
|
||||
code = current.native_currency_code;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ export default () => ({
|
||||
// this series' currency matches this column's currency.
|
||||
amount = parseFloat(current.amount);
|
||||
yAxis = 'y' + current.currency_code;
|
||||
if (this.autoConversion) {
|
||||
if (this.convertToNative) {
|
||||
amount = parseFloat(current.native_amount);
|
||||
yAxis = 'y' + current.native_currency_code;
|
||||
}
|
||||
@@ -183,8 +183,8 @@ export default () => ({
|
||||
},
|
||||
init() {
|
||||
// console.log('categories init');
|
||||
Promise.all([getVariable('autoConversion', false),]).then((values) => {
|
||||
this.autoConversion = values[0];
|
||||
Promise.all([getVariable('convertToNative', false),]).then((values) => {
|
||||
this.convertToNative = values[0];
|
||||
afterPromises = true;
|
||||
this.loadChart();
|
||||
});
|
||||
@@ -195,11 +195,11 @@ export default () => ({
|
||||
this.chartData = null;
|
||||
this.loadChart();
|
||||
});
|
||||
window.store.observe('autoConversion', (newValue) => {
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
this.autoConversion = newValue;
|
||||
this.convertToNative = newValue;
|
||||
this.loadChart();
|
||||
});
|
||||
},
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {getVariable} from "../../store/get-variable.js";
|
||||
import Get from "../../api/v2/model/piggy-bank/get.js";
|
||||
import Get from "../../api/v1/model/piggy-bank/get.js";
|
||||
import {getCacheKey} from "../../support/get-cache-key.js";
|
||||
import {format} from "date-fns";
|
||||
import i18next from "i18next";
|
||||
@@ -29,7 +29,7 @@ const PIGGY_CACHE_KEY = 'ds_pg_data';
|
||||
|
||||
export default () => ({
|
||||
loading: false,
|
||||
autoConversion: false,
|
||||
convertToNative: false,
|
||||
sankeyGrouping: 'account',
|
||||
piggies: [],
|
||||
getFreshData() {
|
||||
@@ -96,14 +96,14 @@ export default () => ({
|
||||
id: current.id,
|
||||
name: current.attributes.name,
|
||||
percentage: parseInt(current.attributes.percentage),
|
||||
amount: this.autoConversion ? current.attributes.native_current_amount : current.attributes.current_amount,
|
||||
amount: this.convertToNative ? current.attributes.native_current_amount : current.attributes.current_amount,
|
||||
// left to save
|
||||
left_to_save: this.autoConversion ? current.attributes.native_left_to_save : current.attributes.left_to_save,
|
||||
left_to_save: this.convertToNative ? current.attributes.native_left_to_save : current.attributes.left_to_save,
|
||||
// target amount
|
||||
target_amount: this.autoConversion ? current.attributes.native_target_amount : current.attributes.target_amount,
|
||||
target_amount: this.convertToNative ? current.attributes.native_target_amount : current.attributes.target_amount,
|
||||
// save per month
|
||||
save_per_month: this.autoConversion ? current.attributes.native_save_per_month : current.attributes.save_per_month,
|
||||
currency_code: this.autoConversion ? current.attributes.native_currency_code : current.attributes.currency_code,
|
||||
save_per_month: this.convertToNative ? current.attributes.native_save_per_month : current.attributes.save_per_month,
|
||||
currency_code: this.convertToNative ? current.attributes.native_currency_code : current.attributes.currency_code,
|
||||
|
||||
};
|
||||
dataSet[groupName].piggies.push(piggy);
|
||||
@@ -129,10 +129,10 @@ export default () => ({
|
||||
init() {
|
||||
// console.log('piggies init');
|
||||
apiData = [];
|
||||
Promise.all([getVariable('autoConversion', false)]).then((values) => {
|
||||
Promise.all([getVariable('convertToNative', false)]).then((values) => {
|
||||
|
||||
afterPromises = true;
|
||||
this.autoConversion = values[0];
|
||||
this.convertToNative = values[0];
|
||||
this.loadPiggyBanks();
|
||||
|
||||
});
|
||||
@@ -144,12 +144,12 @@ export default () => ({
|
||||
apiData = [];
|
||||
this.loadPiggyBanks();
|
||||
});
|
||||
window.store.observe('autoConversion', (newValue) => {
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
// console.log('piggies observe autoConversion');
|
||||
this.autoConversion = newValue;
|
||||
// console.log('piggies observe convertToNative');
|
||||
this.convertToNative = newValue;
|
||||
this.loadPiggyBanks();
|
||||
});
|
||||
},
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {getVariable} from "../../store/get-variable.js";
|
||||
import Get from "../../api/v2/model/transaction/get.js";
|
||||
import Get from "../../api/v1/model/transaction/get.js";
|
||||
import {getDefaultChartSettings} from "../../support/default-chart-settings.js";
|
||||
import {Chart} from 'chart.js';
|
||||
import {Flow, SankeyController} from 'chartjs-chart-sankey';
|
||||
@@ -33,7 +33,7 @@ let currencies = [];
|
||||
let afterPromises = false;
|
||||
let chart = null;
|
||||
let transactions = [];
|
||||
let autoConversion = false;
|
||||
let convertToNative = false;
|
||||
let translations = {
|
||||
category: null,
|
||||
unknown_category: null,
|
||||
@@ -83,37 +83,37 @@ function getObjectName(type, name, direction, code) {
|
||||
|
||||
// category 4x
|
||||
if ('category' === type && null !== name && 'in' === direction) {
|
||||
return translations.category + ' "' + name + '" (' + translations.in + (autoConversion ? ', ' + code + ')' : ')');
|
||||
return translations.category + ' "' + name + '" (' + translations.in + (convertToNative ? ', ' + code + ')' : ')');
|
||||
}
|
||||
if ('category' === type && null === name && 'in' === direction) {
|
||||
return translations.unknown_category + ' (' + translations.in + (autoConversion ? ', ' + code + ')' : ')');
|
||||
return translations.unknown_category + ' (' + translations.in + (convertToNative ? ', ' + code + ')' : ')');
|
||||
}
|
||||
if ('category' === type && null !== name && 'out' === direction) {
|
||||
return translations.category + ' "' + name + '" (' + translations.out + (autoConversion ? ', ' + code + ')' : ')');
|
||||
return translations.category + ' "' + name + '" (' + translations.out + (convertToNative ? ', ' + code + ')' : ')');
|
||||
}
|
||||
if ('category' === type && null === name && 'out' === direction) {
|
||||
return translations.unknown_category + ' (' + translations.out + (autoConversion ? ', ' + code + ')' : ')');
|
||||
return translations.unknown_category + ' (' + translations.out + (convertToNative ? ', ' + code + ')' : ')');
|
||||
}
|
||||
// account 4x
|
||||
if ('account' === type && null === name && 'in' === direction) {
|
||||
return translations.unknown_source + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.unknown_source + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
if ('account' === type && null !== name && 'in' === direction) {
|
||||
return translations.revenue_account + '"' + name + '"' + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.revenue_account + '"' + name + '"' + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
if ('account' === type && null === name && 'out' === direction) {
|
||||
return translations.unknown_dest + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.unknown_dest + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
if ('account' === type && null !== name && 'out' === direction) {
|
||||
return translations.expense_account + ' "' + name + '"' + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.expense_account + ' "' + name + '"' + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
|
||||
// budget 2x
|
||||
if ('budget' === type && null !== name) {
|
||||
return translations.budget + ' "' + name + '"' + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.budget + ' "' + name + '"' + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
if ('budget' === type && null === name) {
|
||||
return translations.unknown_budget + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.unknown_budget + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
console.error('Cannot handle: type:"' + type + '", dir: "' + direction + '"');
|
||||
}
|
||||
@@ -121,25 +121,25 @@ function getObjectName(type, name, direction, code) {
|
||||
function getLabelName(type, name, code) {
|
||||
// category
|
||||
if ('category' === type && null !== name) {
|
||||
return translations.category + ' "' + name + '"' + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.category + ' "' + name + '"' + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
if ('category' === type && null === name) {
|
||||
return translations.unknown_category + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.unknown_category + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
// account
|
||||
if ('account' === type && null === name) {
|
||||
return translations.unknown_account + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.unknown_account + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
if ('account' === type && null !== name) {
|
||||
return name + (autoConversion ? ' (' + code + ')' : '');
|
||||
return name + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
|
||||
// budget 2x
|
||||
if ('budget' === type && null !== name) {
|
||||
return translations.budget + ' "' + name + '"' + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.budget + ' "' + name + '"' + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
if ('budget' === type && null === name) {
|
||||
return translations.unknown_budget + (autoConversion ? ' (' + code + ')' : '');
|
||||
return translations.unknown_budget + (convertToNative ? ' (' + code + ')' : '');
|
||||
}
|
||||
console.error('Cannot handle: type:"' + type + '"');
|
||||
}
|
||||
@@ -147,7 +147,7 @@ function getLabelName(type, name, code) {
|
||||
|
||||
export default () => ({
|
||||
loading: false,
|
||||
autoConversion: false,
|
||||
convertToNative: false,
|
||||
generateOptions() {
|
||||
let options = getDefaultChartSettings('sankey');
|
||||
|
||||
@@ -164,8 +164,8 @@ export default () => ({
|
||||
if (group.attributes.transactions.hasOwnProperty(ii)) {
|
||||
// properties of the transaction, used in the generation of the chart:
|
||||
let transaction = group.attributes.transactions[ii];
|
||||
let currencyCode = this.autoConversion ? transaction.native_currency_code : transaction.currency_code;
|
||||
let amount = this.autoConversion ? parseFloat(transaction.native_amount) : parseFloat(transaction.amount);
|
||||
let currencyCode = this.convertToNative ? transaction.native_currency_code : transaction.currency_code;
|
||||
let amount = this.convertToNative ? parseFloat(transaction.native_amount) : parseFloat(transaction.amount);
|
||||
let flowKey;
|
||||
|
||||
/*
|
||||
@@ -194,7 +194,7 @@ export default () => ({
|
||||
if (!amounts.hasOwnProperty(flowKey)) {
|
||||
amounts[flowKey] = {
|
||||
from: category,
|
||||
to: translations.all_money + (this.autoConversion ? ' (' + currencyCode + ')' : ''),
|
||||
to: translations.all_money + (this.convertToNative ? ' (' + currencyCode + ')' : ''),
|
||||
amount: 0
|
||||
};
|
||||
}
|
||||
@@ -214,7 +214,7 @@ export default () => ({
|
||||
|
||||
if (!amounts.hasOwnProperty(flowKey)) {
|
||||
amounts[flowKey] = {
|
||||
from: translations.all_money + (this.autoConversion ? ' (' + currencyCode + ')' : ''),
|
||||
from: translations.all_money + (this.convertToNative ? ' (' + currencyCode + ')' : ''),
|
||||
to: budget,
|
||||
amount: 0
|
||||
};
|
||||
@@ -348,9 +348,9 @@ export default () => ({
|
||||
init() {
|
||||
// console.log('sankey init');
|
||||
transactions = [];
|
||||
Promise.all([getVariable('autoConversion', false)]).then((values) => {
|
||||
this.autoConversion = values[0];
|
||||
autoConversion = values[0];
|
||||
Promise.all([getVariable('convertToNative', false)]).then((values) => {
|
||||
this.convertToNative = values[0];
|
||||
convertToNative = values[0];
|
||||
// some translations:
|
||||
translations.all_money = i18next.t('firefly.all_money');
|
||||
translations.category = i18next.t('firefly.category');
|
||||
@@ -378,12 +378,12 @@ export default () => ({
|
||||
this.transactions = [];
|
||||
this.loadChart();
|
||||
});
|
||||
window.store.observe('autoConversion', (newValue) => {
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
// console.log('sankey observe autoConversion');
|
||||
this.autoConversion = newValue;
|
||||
// console.log('sankey observe convertToNative');
|
||||
this.convertToNative = newValue;
|
||||
this.loadChart();
|
||||
});
|
||||
},
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {getVariable} from "../../store/get-variable.js";
|
||||
import Get from "../../api/v2/model/subscription/get.js";
|
||||
import Get from "../../api/v1/model/subscription/get.js";
|
||||
import {format} from "date-fns";
|
||||
import {getCacheKey} from "../../support/get-cache-key.js";
|
||||
import {Chart} from "chart.js";
|
||||
@@ -66,10 +66,10 @@ function downloadSubscriptions(params) {
|
||||
currency_code: current.attributes.currency_code,
|
||||
|
||||
// native amount
|
||||
native_amount_min: current.attributes.native_amount_min,
|
||||
native_amount_max: current.attributes.native_amount_max,
|
||||
native_amount: (parseFloat(current.attributes.native_amount_max) + parseFloat(current.attributes.native_amount_min)) / 2,
|
||||
native_currency_code: current.attributes.native_currency_code,
|
||||
// native_amount_min: current.attributes.native_amount_min,
|
||||
// native_amount_max: current.attributes.native_amount_max,
|
||||
// native_amount: (parseFloat(current.attributes.native_amount_max) + parseFloat(current.attributes.native_amount_min)) / 2,
|
||||
// native_currency_code: current.attributes.native_currency_code,
|
||||
|
||||
// paid transactions:
|
||||
transactions: [],
|
||||
@@ -79,8 +79,7 @@ function downloadSubscriptions(params) {
|
||||
paid: current.attributes.paid_dates.length > 0,
|
||||
};
|
||||
// set variables
|
||||
bill.expected_amount = params.autoConversion ? formatMoney(bill.native_amount, bill.native_currency_code) :
|
||||
formatMoney(bill.amount, bill.currency_code);
|
||||
bill.expected_amount = formatMoney(bill.amount, bill.currency_code);
|
||||
bill.expected_times = i18next.t('firefly.subscr_expected_x_times', {
|
||||
times: current.attributes.pay_dates.length,
|
||||
amount: bill.expected_amount
|
||||
@@ -92,22 +91,25 @@ function downloadSubscriptions(params) {
|
||||
const currentPayment = current.attributes.paid_dates[iii];
|
||||
let percentage = 100;
|
||||
// math: -100+(paid/expected)*100
|
||||
if (params.autoConversion) {
|
||||
if (params.convertToNative) {
|
||||
percentage = Math.round(-100 + ((parseFloat(currentPayment.native_amount) * -1) / parseFloat(bill.native_amount)) * 100);
|
||||
}
|
||||
if (!params.autoConversion) {
|
||||
if (!params.convertToNative) {
|
||||
percentage = Math.round(-100 + ((parseFloat(currentPayment.amount) * -1) / parseFloat(bill.amount)) * 100);
|
||||
}
|
||||
|
||||
// TODO fix me
|
||||
currentPayment.currency_code = 'EUR';
|
||||
console.log('Currency code: "'+currentPayment+'"');
|
||||
console.log(currentPayment);
|
||||
let currentTransaction = {
|
||||
amount: params.autoConversion ? formatMoney(currentPayment.native_amount, currentPayment.native_currency_code) : formatMoney(currentPayment.amount, currentPayment.currency_code),
|
||||
amount: formatMoney(currentPayment.amount, currentPayment.currency_code),
|
||||
percentage: percentage,
|
||||
date: format(new Date(currentPayment.date), 'PP'),
|
||||
foreign_amount: null,
|
||||
};
|
||||
if (null !== currentPayment.foreign_currency_code) {
|
||||
currentTransaction.foreign_amount = params.autoConversion ? currentPayment.foreign_native_amount : currentPayment.foreign_amount;
|
||||
currentTransaction.foreign_currency_code = params.autoConversion ? currentPayment.native_currency_code : currentPayment.foreign_currency_code;
|
||||
currentTransaction.foreign_amount = currentPayment.foreign_amount;
|
||||
currentTransaction.foreign_currency_code = currentPayment.foreign_currency_code;
|
||||
}
|
||||
|
||||
bill.transactions.push(currentTransaction);
|
||||
@@ -119,7 +121,7 @@ function downloadSubscriptions(params) {
|
||||
// bill is unpaid, count the "pay_dates" and multiply with the "amount".
|
||||
// since bill is unpaid, this can only be in currency amount and native currency amount.
|
||||
const totalAmount = current.attributes.pay_dates.length * bill.amount;
|
||||
const totalNativeAmount = current.attributes.pay_dates.length * bill.native_amount;
|
||||
// const totalNativeAmount = current.attributes.pay_dates.length * bill.native_amount;
|
||||
// for bill's currency
|
||||
if (!subscriptionData[objectGroupId].payment_info.hasOwnProperty(bill.currency_code)) {
|
||||
subscriptionData[objectGroupId].payment_info[bill.currency_code] = {
|
||||
@@ -128,11 +130,11 @@ function downloadSubscriptions(params) {
|
||||
unpaid: 0,
|
||||
native_currency_code: bill.native_currency_code,
|
||||
native_paid: 0,
|
||||
native_unpaid: 0,
|
||||
//native_unpaid: 0,
|
||||
};
|
||||
}
|
||||
subscriptionData[objectGroupId].payment_info[bill.currency_code].unpaid += totalAmount;
|
||||
subscriptionData[objectGroupId].payment_info[bill.currency_code].native_unpaid += totalNativeAmount;
|
||||
//subscriptionData[objectGroupId].payment_info[bill.currency_code].native_unpaid += totalNativeAmount;
|
||||
}
|
||||
|
||||
if (current.attributes.paid_dates.length > 0) {
|
||||
@@ -149,15 +151,15 @@ function downloadSubscriptions(params) {
|
||||
currency_code: bill.currency_code,
|
||||
paid: 0,
|
||||
unpaid: 0,
|
||||
native_currency_code: bill.native_currency_code,
|
||||
native_paid: 0,
|
||||
native_unpaid: 0,
|
||||
// native_currency_code: bill.native_currency_code,
|
||||
// native_paid: 0,
|
||||
//native_unpaid: 0,
|
||||
};
|
||||
}
|
||||
const amount = parseFloat(currentJournal.amount) * -1;
|
||||
const nativeAmount = parseFloat(currentJournal.native_amount) * -1;
|
||||
// const nativeAmount = parseFloat(currentJournal.native_amount) * -1;
|
||||
subscriptionData[objectGroupId].payment_info[currentJournal.currency_code].paid += amount;
|
||||
subscriptionData[objectGroupId].payment_info[currentJournal.currency_code].native_paid += nativeAmount;
|
||||
// subscriptionData[objectGroupId].payment_info[currentJournal.currency_code].native_paid += nativeAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,7 +180,7 @@ function downloadSubscriptions(params) {
|
||||
|
||||
export default () => ({
|
||||
loading: false,
|
||||
autoConversion: false,
|
||||
convertToNative: false,
|
||||
subscriptions: [],
|
||||
startSubscriptions() {
|
||||
this.loading = true;
|
||||
@@ -198,7 +200,7 @@ export default () => ({
|
||||
let params = {
|
||||
start: format(start, 'y-MM-dd'),
|
||||
end: format(end, 'y-MM-dd'),
|
||||
autoConversion: this.autoConversion,
|
||||
// convertToNative: this.convertToNative,
|
||||
page: 1
|
||||
};
|
||||
downloadSubscriptions(params).then(() => {
|
||||
@@ -226,9 +228,9 @@ export default () => ({
|
||||
drawPieChart(groupId, groupTitle, data) {
|
||||
let id = '#pie_' + groupId + '_' + data.currency_code;
|
||||
//console.log(data);
|
||||
const unpaidAmount = this.autoConversion ? data.native_unpaid : data.unpaid;
|
||||
const paidAmount = this.autoConversion ? data.native_paid : data.paid;
|
||||
const currencyCode = this.autoConversion ? data.native_currency_code : data.currency_code;
|
||||
const unpaidAmount = data.unpaid;
|
||||
const paidAmount = data.paid;
|
||||
const currencyCode = data.currency_code;
|
||||
const chartData = {
|
||||
labels: [
|
||||
i18next.t('firefly.paid'),
|
||||
@@ -267,8 +269,8 @@ export default () => ({
|
||||
},
|
||||
|
||||
init() {
|
||||
Promise.all([getVariable('autoConversion', false)]).then((values) => {
|
||||
this.autoConversion = values[0];
|
||||
Promise.all([getVariable('convertToNative', false)]).then((values) => {
|
||||
this.convertToNative = values[0];
|
||||
afterPromises = true;
|
||||
|
||||
if (false === this.loading) {
|
||||
@@ -285,11 +287,11 @@ export default () => ({
|
||||
this.startSubscriptions();
|
||||
}
|
||||
});
|
||||
window.store.observe('autoConversion', (newValue) => {
|
||||
window.store.observe('convertToNative', (newValue) => {
|
||||
if (!afterPromises) {
|
||||
return;
|
||||
}
|
||||
this.autoConversion = newValue;
|
||||
this.convertToNative = newValue;
|
||||
if (false === this.loading) {
|
||||
this.startSubscriptions();
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ import dates from '../../pages/shared/dates.js';
|
||||
import {createEmptySplit, defaultErrorSet} from "./shared/create-empty-split.js";
|
||||
import {parseFromEntries} from "./shared/parse-from-entries.js";
|
||||
import formatMoney from "../../util/format-money.js";
|
||||
import Post from "../../api/v2/model/transaction/post.js";
|
||||
import Post from "../../api/v1/model/transaction/post.js";
|
||||
import {loadCurrencies} from "./shared/load-currencies.js";
|
||||
import {loadBudgets} from "./shared/load-budgets.js";
|
||||
import {loadPiggyBanks} from "./shared/load-piggy-banks.js";
|
||||
|
@@ -21,7 +21,7 @@
|
||||
import '../../boot/bootstrap.js';
|
||||
import dates from '../../pages/shared/dates.js';
|
||||
import formatMoney from "../../util/format-money.js";
|
||||
import Get from "../../api/v2/model/transaction/get.js";
|
||||
import Get from "../../api/v1/model/transaction/get.js";
|
||||
import {parseDownloadedSplits} from "./shared/parse-downloaded-splits.js";
|
||||
import {addAutocomplete, getUrls} from "./shared/add-autocomplete.js";
|
||||
import {
|
||||
@@ -40,7 +40,7 @@ import Tags from "bootstrap5-tags";
|
||||
import i18next from "i18next";
|
||||
import {defaultErrorSet} from "./shared/create-empty-split.js";
|
||||
import {parseFromEntries} from "./shared/parse-from-entries.js";
|
||||
import Put from "../../api/v2/model/transaction/put.js";
|
||||
import Put from "../../api/v1/model/transaction/put.js";
|
||||
import {processAttachments} from "./shared/process-attachments.js";
|
||||
import {spliceErrorsIntoTransactions} from "./shared/splice-errors-into-transactions.js";
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user