mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-18 18:40:12 +00:00
Compare commits
54 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
0a6b34b4f2 | ||
|
1e06b4dd0b | ||
|
5701f95e0b | ||
|
60d3572d37 | ||
|
ffa6e6a571 | ||
|
d6453cd735 | ||
|
fd79f9df44 | ||
|
4587340293 | ||
|
90bfdc7573 | ||
|
eca12f661f | ||
|
f85878b843 | ||
|
6499b5eaab | ||
|
7e4fece63d | ||
|
512eddf8be | ||
|
f0fa93a811 | ||
|
3c8de21709 | ||
|
81173e8340 | ||
|
35a8fa5f02 | ||
|
443036936d | ||
|
ac88007593 | ||
|
2297589dca | ||
|
6ada5fa560 | ||
|
8f6eefb5e7 | ||
|
b36a50381b | ||
|
51f84b3060 | ||
|
72132a19b0 | ||
|
065d165211 | ||
|
cabedf39b2 | ||
|
5d3806fcd4 | ||
|
01695b3342 | ||
|
71fb5fe077 | ||
|
3bec106840 | ||
|
fb01c36be1 | ||
|
26d851e69e | ||
|
28c18c046b | ||
|
318cef7e3b | ||
|
e8dc8f25be | ||
|
10ccc30240 | ||
|
5adc877d5e | ||
|
30923afb2b | ||
|
4eb6813b43 | ||
|
7521a31619 | ||
|
fc05beb452 | ||
|
1103428a83 | ||
|
d06d521bf0 | ||
|
8f64f1c0eb | ||
|
d11c232171 | ||
|
93c73248de | ||
|
5bed081ab9 | ||
|
c5188c503e | ||
|
98ffcac7b6 | ||
|
df1e81d611 | ||
|
9711170b08 | ||
|
e43264bdce |
8
.github/label-actions.yml
vendored
8
.github/label-actions.yml
vendored
@@ -9,9 +9,9 @@ fixed:
|
|||||||
|
|
||||||
This is an automatic reply. `Share and enjoy`
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
This issue has been marked as fixed. The bug, feature or enhancement will become a part of Firefly III or the data importer in due course. Thanks for reporting!
|
This issue has been marked as fixed. Thanks for reporting! A new version will be released in due time. Unfortunately, [I cannot give an estimate](https://docs.firefly-iii.org/references/faq/firefly-iii/general/#when-will-you-release-version-the-next-version), but [the roadmap](https://roadmap.firefly-iii.org/) is available for your reading pleasure.
|
||||||
|
|
||||||
A new version will be released in due time. Unfortunately, [I cannot give an estimate](https://docs.firefly-iii.org/references/faq/firefly-iii/general/#when-will-you-release-version-the-next-version), but [the roadmap](https://roadmap.firefly-iii.org/) is available for your reading pleasure.
|
There is no need to close the issue. It will be closed automatically.
|
||||||
|
|
||||||
Thank you for your contributions.
|
Thank you for your contributions.
|
||||||
feature:
|
feature:
|
||||||
@@ -23,7 +23,7 @@ feature:
|
|||||||
|
|
||||||
This is an automatic reply. `Share and enjoy`
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
This issue has been marked as a feature request. The requested (new) feature will become a part of Firefly III or the data importer in due course.
|
This issue has been marked as a feature request.
|
||||||
|
|
||||||
If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ enhancement:
|
|||||||
|
|
||||||
This is an automatic reply. `Share and enjoy`
|
This is an automatic reply. `Share and enjoy`
|
||||||
|
|
||||||
This issue has been marked as an enhancement. The requested enhancement to an existing feature will become a part of Firefly III or the data importer in due course.
|
This issue has been marked as an enhancement.
|
||||||
|
|
||||||
If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
|
||||||
|
|
||||||
|
2
.github/workflows/closed-issues.yml
vendored
2
.github/workflows/closed-issues.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
|||||||
command_and_close:
|
command_and_close:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: aws-actions/closed-issue-message@v1
|
- uses: aws-actions/closed-issue-message@v2
|
||||||
with:
|
with:
|
||||||
message: |
|
message: |
|
||||||
Hi there! This is an automatic reply. `Share and enjoy`
|
Hi there! This is an automatic reply. `Share and enjoy`
|
||||||
|
@@ -3,6 +3,9 @@
|
|||||||
Over time, many people have contributed to Firefly III. Their efforts are not always visible, but always remembered and appreciated.
|
Over time, many people have contributed to Firefly III. Their efforts are not always visible, but always remembered and appreciated.
|
||||||
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
|
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
|
||||||
|
- SoftBrix
|
||||||
|
|
||||||
## 2024
|
## 2024
|
||||||
- Sobuno
|
- Sobuno
|
||||||
- TasneemTantawy
|
- TasneemTantawy
|
||||||
|
@@ -83,6 +83,9 @@ class AccountController extends Controller
|
|||||||
$return = [];
|
$return = [];
|
||||||
$result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
|
$result = $this->repository->searchAccount((string) $query, $types, $this->parameters->get('limit'));
|
||||||
|
|
||||||
|
// set date to end-of-day for account balance.
|
||||||
|
$date->endOfDay();
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($result as $account) {
|
foreach ($result as $account) {
|
||||||
$nameWithBalance = $account->name;
|
$nameWithBalance = $account->name;
|
||||||
|
@@ -32,6 +32,7 @@ use FireflyIII\Exceptions\FireflyException;
|
|||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Preference;
|
use FireflyIII\Models\Preference;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Api\ApiSupport;
|
use FireflyIII\Support\Http\Api\ApiSupport;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
@@ -80,6 +81,10 @@ class AccountController extends Controller
|
|||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = $dates['end'];
|
$end = $dates['end'];
|
||||||
|
|
||||||
|
// set dates to end of day + start of day:
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
// user's preferences
|
// user's preferences
|
||||||
$defaultSet = $this->repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
|
$defaultSet = $this->repository->getAccountsByType([AccountTypeEnum::ASSET->value])->pluck('id')->toArray();
|
||||||
|
|
||||||
@@ -113,7 +118,7 @@ class AccountController extends Controller
|
|||||||
];
|
];
|
||||||
// TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
|
// TODO this code is also present in the V2 chart account controller so this method is due to be deprecated.
|
||||||
$currentStart = clone $start;
|
$currentStart = clone $start;
|
||||||
$range = app('steam')->finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative);
|
$range = Steam::finalAccountBalanceInRange($account, $start, clone $end, $this->convertToNative);
|
||||||
$previous = array_values($range)[0][$field];
|
$previous = array_values($range)[0][$field];
|
||||||
while ($currentStart <= $end) {
|
while ($currentStart <= $end) {
|
||||||
$format = $currentStart->format('Y-m-d');
|
$format = $currentStart->format('Y-m-d');
|
||||||
|
@@ -57,11 +57,11 @@ class IndexController extends Controller
|
|||||||
|
|
||||||
public function index(): JsonResponse
|
public function index(): JsonResponse
|
||||||
{
|
{
|
||||||
$piggies = $this->repository->getAll();
|
$entries = $this->repository->getAll();
|
||||||
$pageSize = $this->parameters->get('limit');
|
$pageSize = $this->parameters->get('limit');
|
||||||
$count = $piggies->count();
|
$count = $entries->count();
|
||||||
$piggies = $piggies->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
$entries = $entries->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
|
||||||
$paginator = new LengthAwarePaginator($piggies, $count, $pageSize, $this->parameters->get('page'));
|
$paginator = new LengthAwarePaginator($entries, $count, $pageSize, $this->parameters->get('page'));
|
||||||
$transformer = new ExchangeRateTransformer();
|
$transformer = new ExchangeRateTransformer();
|
||||||
$transformer->setParameters($this->parameters); // give params to transformer
|
$transformer->setParameters($this->parameters); // give params to transformer
|
||||||
|
|
||||||
|
@@ -31,6 +31,7 @@ use FireflyIII\Models\Account;
|
|||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Chart\ChartData;
|
use FireflyIII\Support\Chart\ChartData;
|
||||||
|
use FireflyIII\Support\Facades\Steam;
|
||||||
use FireflyIII\Support\Http\Api\CleansChartData;
|
use FireflyIII\Support\Http\Api\CleansChartData;
|
||||||
use FireflyIII\Support\Http\Api\CollectsAccountsFromFilter;
|
use FireflyIII\Support\Http\Api\CollectsAccountsFromFilter;
|
||||||
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
|
||||||
@@ -118,7 +119,7 @@ class AccountController extends Controller
|
|||||||
'native_entries' => [],
|
'native_entries' => [],
|
||||||
];
|
];
|
||||||
$currentStart = clone $params['start'];
|
$currentStart = clone $params['start'];
|
||||||
$range = app('steam')->finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
|
$range = Steam::finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $this->convertToNative);
|
||||||
|
|
||||||
$previous = array_values($range)[0]['balance'];
|
$previous = array_values($range)[0]['balance'];
|
||||||
$previousNative = array_values($range)[0]['native_balance'];
|
$previousNative = array_values($range)[0]['native_balance'];
|
||||||
|
@@ -54,6 +54,9 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
|||||||
$dayBefore = clone $this->start;
|
$dayBefore = clone $this->start;
|
||||||
$dayBefore->subDay();
|
$dayBefore->subDay();
|
||||||
|
|
||||||
|
// move to end of day
|
||||||
|
$dayBefore->endOfDay();
|
||||||
|
|
||||||
/** @var Account $account */
|
/** @var Account $account */
|
||||||
foreach ($this->accounts as $account) {
|
foreach ($this->accounts as $account) {
|
||||||
// balance the day before:
|
// balance the day before:
|
||||||
|
@@ -26,6 +26,7 @@ namespace FireflyIII\Handlers\Observer;
|
|||||||
|
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
|
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||||
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
@@ -52,6 +53,7 @@ class AccountObserver
|
|||||||
$currency = $repository->getAccountCurrency($account);
|
$currency = $repository->getAccountCurrency($account);
|
||||||
if (null !== $currency && $currency->id !== $userCurrency->id && '' !== (string) $account->virtual_balance && 0 !== bccomp($account->virtual_balance, '0')) {
|
if (null !== $currency && $currency->id !== $userCurrency->id && '' !== (string) $account->virtual_balance && 0 !== bccomp($account->virtual_balance, '0')) {
|
||||||
$converter = new ExchangeRateConverter();
|
$converter = new ExchangeRateConverter();
|
||||||
|
$converter->setUserGroup($account->user->userGroup);
|
||||||
$converter->setIgnoreSettings(true);
|
$converter->setIgnoreSettings(true);
|
||||||
$account->native_virtual_balance = $converter->convert($currency, $userCurrency, today(), $account->virtual_balance);
|
$account->native_virtual_balance = $converter->convert($currency, $userCurrency, today(), $account->virtual_balance);
|
||||||
|
|
||||||
@@ -72,12 +74,15 @@ class AccountObserver
|
|||||||
// app('log')->debug('Observe "deleting" of an account.');
|
// app('log')->debug('Observe "deleting" of an account.');
|
||||||
$account->accountMeta()->delete();
|
$account->accountMeta()->delete();
|
||||||
|
|
||||||
|
$repository = app(AttachmentRepositoryInterface::class);
|
||||||
|
$repository->setUser($account->user);
|
||||||
|
|
||||||
/** @var PiggyBank $piggy */
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($account->piggyBanks()->get() as $piggy) {
|
foreach ($account->piggyBanks()->get() as $piggy) {
|
||||||
$piggy->accounts()->detach($account);
|
$piggy->accounts()->detach($account);
|
||||||
}
|
}
|
||||||
foreach ($account->attachments()->get() as $attachment) {
|
foreach ($account->attachments()->get() as $attachment) {
|
||||||
$attachment->delete();
|
$repository->destroy($attachment);
|
||||||
}
|
}
|
||||||
foreach ($account->transactions()->get() as $transaction) {
|
foreach ($account->transactions()->get() as $transaction) {
|
||||||
$transaction->delete();
|
$transaction->delete();
|
||||||
|
@@ -52,6 +52,7 @@ class AutoBudgetObserver
|
|||||||
$autoBudget->native_amount = null;
|
$autoBudget->native_amount = null;
|
||||||
if ($autoBudget->transactionCurrency->id !== $userCurrency->id) {
|
if ($autoBudget->transactionCurrency->id !== $userCurrency->id) {
|
||||||
$converter = new ExchangeRateConverter();
|
$converter = new ExchangeRateConverter();
|
||||||
|
$converter->setUserGroup($autoBudget->budget->user->userGroup);
|
||||||
$converter->setIgnoreSettings(true);
|
$converter->setIgnoreSettings(true);
|
||||||
$autoBudget->native_amount = $converter->convert($autoBudget->transactionCurrency, $userCurrency, today(), $autoBudget->amount);
|
$autoBudget->native_amount = $converter->convert($autoBudget->transactionCurrency, $userCurrency, today(), $autoBudget->amount);
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Handlers\Observer;
|
namespace FireflyIII\Handlers\Observer;
|
||||||
|
|
||||||
use FireflyIII\Models\Bill;
|
use FireflyIII\Models\Bill;
|
||||||
|
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
@@ -41,9 +42,12 @@ class BillObserver
|
|||||||
|
|
||||||
public function deleting(Bill $bill): void
|
public function deleting(Bill $bill): void
|
||||||
{
|
{
|
||||||
|
$repository = app(AttachmentRepositoryInterface::class);
|
||||||
|
$repository->setUser($bill->user);
|
||||||
|
|
||||||
// app('log')->debug('Observe "deleting" of a bill.');
|
// app('log')->debug('Observe "deleting" of a bill.');
|
||||||
foreach ($bill->attachments()->get() as $attachment) {
|
foreach ($bill->attachments()->get() as $attachment) {
|
||||||
$attachment->delete();
|
$repository->destroy($attachment);
|
||||||
}
|
}
|
||||||
$bill->notes()->delete();
|
$bill->notes()->delete();
|
||||||
}
|
}
|
||||||
@@ -64,6 +68,7 @@ class BillObserver
|
|||||||
$bill->native_amount_max = null;
|
$bill->native_amount_max = null;
|
||||||
if ($bill->transactionCurrency->id !== $userCurrency->id) {
|
if ($bill->transactionCurrency->id !== $userCurrency->id) {
|
||||||
$converter = new ExchangeRateConverter();
|
$converter = new ExchangeRateConverter();
|
||||||
|
$converter->setUserGroup($bill->user->userGroup);
|
||||||
$converter->setIgnoreSettings(true);
|
$converter->setIgnoreSettings(true);
|
||||||
$bill->native_amount_min = $converter->convert($bill->transactionCurrency, $userCurrency, today(), $bill->amount_min);
|
$bill->native_amount_min = $converter->convert($bill->transactionCurrency, $userCurrency, today(), $bill->amount_min);
|
||||||
$bill->native_amount_max = $converter->convert($bill->transactionCurrency, $userCurrency, today(), $bill->amount_max);
|
$bill->native_amount_max = $converter->convert($bill->transactionCurrency, $userCurrency, today(), $bill->amount_max);
|
||||||
|
@@ -54,6 +54,7 @@ class BudgetLimitObserver
|
|||||||
$budgetLimit->native_amount = null;
|
$budgetLimit->native_amount = null;
|
||||||
if ($budgetLimit->transactionCurrency->id !== $userCurrency->id) {
|
if ($budgetLimit->transactionCurrency->id !== $userCurrency->id) {
|
||||||
$converter = new ExchangeRateConverter();
|
$converter = new ExchangeRateConverter();
|
||||||
|
$converter->setUserGroup($budgetLimit->budget->user->userGroup);
|
||||||
$converter->setIgnoreSettings(true);
|
$converter->setIgnoreSettings(true);
|
||||||
$budgetLimit->native_amount = $converter->convert($budgetLimit->transactionCurrency, $userCurrency, today(), $budgetLimit->amount);
|
$budgetLimit->native_amount = $converter->convert($budgetLimit->transactionCurrency, $userCurrency, today(), $budgetLimit->amount);
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@ namespace FireflyIII\Handlers\Observer;
|
|||||||
|
|
||||||
use FireflyIII\Models\Budget;
|
use FireflyIII\Models\Budget;
|
||||||
use FireflyIII\Models\BudgetLimit;
|
use FireflyIII\Models\BudgetLimit;
|
||||||
|
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BudgetObserver
|
* Class BudgetObserver
|
||||||
@@ -34,8 +35,12 @@ class BudgetObserver
|
|||||||
public function deleting(Budget $budget): void
|
public function deleting(Budget $budget): void
|
||||||
{
|
{
|
||||||
app('log')->debug('Observe "deleting" of a budget.');
|
app('log')->debug('Observe "deleting" of a budget.');
|
||||||
|
|
||||||
|
$repository = app(AttachmentRepositoryInterface::class);
|
||||||
|
$repository->setUser($budget->user);
|
||||||
|
|
||||||
foreach ($budget->attachments()->get() as $attachment) {
|
foreach ($budget->attachments()->get() as $attachment) {
|
||||||
$attachment->delete();
|
$repository->destroy($attachment);
|
||||||
}
|
}
|
||||||
$budgetLimits = $budget->budgetlimits()->get();
|
$budgetLimits = $budget->budgetlimits()->get();
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Handlers\Observer;
|
namespace FireflyIII\Handlers\Observer;
|
||||||
|
|
||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
|
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CategoryObserver
|
* Class CategoryObserver
|
||||||
@@ -33,8 +34,12 @@ class CategoryObserver
|
|||||||
public function deleting(Category $category): void
|
public function deleting(Category $category): void
|
||||||
{
|
{
|
||||||
app('log')->debug('Observe "deleting" of a category.');
|
app('log')->debug('Observe "deleting" of a category.');
|
||||||
|
|
||||||
|
$repository = app(AttachmentRepositoryInterface::class);
|
||||||
|
$repository->setUser($category->user);
|
||||||
|
|
||||||
foreach ($category->attachments()->get() as $attachment) {
|
foreach ($category->attachments()->get() as $attachment) {
|
||||||
$attachment->delete();
|
$repository->destroy($attachment);
|
||||||
}
|
}
|
||||||
$category->notes()->delete();
|
$category->notes()->delete();
|
||||||
}
|
}
|
||||||
|
@@ -52,6 +52,7 @@ class PiggyBankEventObserver
|
|||||||
$event->native_amount = null;
|
$event->native_amount = null;
|
||||||
if ($event->piggyBank->transactionCurrency->id !== $userCurrency->id) {
|
if ($event->piggyBank->transactionCurrency->id !== $userCurrency->id) {
|
||||||
$converter = new ExchangeRateConverter();
|
$converter = new ExchangeRateConverter();
|
||||||
|
$converter->setUserGroup($event->piggyBank->accounts()->first()->user->userGroup);
|
||||||
$converter->setIgnoreSettings(true);
|
$converter->setIgnoreSettings(true);
|
||||||
$event->native_amount = $converter->convert($event->piggyBank->transactionCurrency, $userCurrency, today(), $event->amount);
|
$event->native_amount = $converter->convert($event->piggyBank->transactionCurrency, $userCurrency, today(), $event->amount);
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Handlers\Observer;
|
namespace FireflyIII\Handlers\Observer;
|
||||||
|
|
||||||
use FireflyIII\Models\PiggyBank;
|
use FireflyIII\Models\PiggyBank;
|
||||||
|
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
@@ -46,8 +47,11 @@ class PiggyBankObserver
|
|||||||
{
|
{
|
||||||
app('log')->debug('Observe "deleting" of a piggy bank.');
|
app('log')->debug('Observe "deleting" of a piggy bank.');
|
||||||
|
|
||||||
|
$repository = app(AttachmentRepositoryInterface::class);
|
||||||
|
$repository->setUser($piggyBank->accounts()->first()->user);
|
||||||
|
|
||||||
foreach ($piggyBank->attachments()->get() as $attachment) {
|
foreach ($piggyBank->attachments()->get() as $attachment) {
|
||||||
$attachment->delete();
|
$repository->destroy($attachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
$piggyBank->piggyBankEvents()->delete();
|
$piggyBank->piggyBankEvents()->delete();
|
||||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Handlers\Observer;
|
namespace FireflyIII\Handlers\Observer;
|
||||||
|
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
|
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class RecurrenceObserver
|
* Class RecurrenceObserver
|
||||||
@@ -33,8 +34,12 @@ class RecurrenceObserver
|
|||||||
public function deleting(Recurrence $recurrence): void
|
public function deleting(Recurrence $recurrence): void
|
||||||
{
|
{
|
||||||
app('log')->debug('Observe "deleting" of a recurrence.');
|
app('log')->debug('Observe "deleting" of a recurrence.');
|
||||||
|
|
||||||
|
$repository = app(AttachmentRepositoryInterface::class);
|
||||||
|
$repository->setUser($recurrence->user);
|
||||||
|
|
||||||
foreach ($recurrence->attachments()->get() as $attachment) {
|
foreach ($recurrence->attachments()->get() as $attachment) {
|
||||||
$attachment->delete();
|
$repository->destroy($attachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
$recurrence->recurrenceRepetitions()->delete();
|
$recurrence->recurrenceRepetitions()->delete();
|
||||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Handlers\Observer;
|
namespace FireflyIII\Handlers\Observer;
|
||||||
|
|
||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
|
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TagObserver
|
* Class TagObserver
|
||||||
@@ -34,8 +35,11 @@ class TagObserver
|
|||||||
{
|
{
|
||||||
app('log')->debug('Observe "deleting" of a tag.');
|
app('log')->debug('Observe "deleting" of a tag.');
|
||||||
|
|
||||||
|
$repository = app(AttachmentRepositoryInterface::class);
|
||||||
|
$repository->setUser($tag->user);
|
||||||
|
|
||||||
foreach ($tag->attachments()->get() as $attachment) {
|
foreach ($tag->attachments()->get() as $attachment) {
|
||||||
$attachment->delete();
|
$repository->destroy($attachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag->locations()->delete();
|
$tag->locations()->delete();
|
||||||
|
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Handlers\Observer;
|
namespace FireflyIII\Handlers\Observer;
|
||||||
|
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
|
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class TransactionJournalObserver
|
* Class TransactionJournalObserver
|
||||||
@@ -34,6 +35,10 @@ class TransactionJournalObserver
|
|||||||
{
|
{
|
||||||
app('log')->debug('Observe "deleting" of a transaction journal.');
|
app('log')->debug('Observe "deleting" of a transaction journal.');
|
||||||
|
|
||||||
|
$repository = app(AttachmentRepositoryInterface::class);
|
||||||
|
$repository->setUser($transactionJournal->user);
|
||||||
|
|
||||||
|
|
||||||
// to make sure the listener doesn't get back to use and loop
|
// to make sure the listener doesn't get back to use and loop
|
||||||
TransactionJournal::withoutEvents(static function () use ($transactionJournal): void {
|
TransactionJournal::withoutEvents(static function () use ($transactionJournal): void {
|
||||||
foreach ($transactionJournal->transactions()->get() as $transaction) {
|
foreach ($transactionJournal->transactions()->get() as $transaction) {
|
||||||
@@ -41,7 +46,7 @@ class TransactionJournalObserver
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
foreach ($transactionJournal->attachments()->get() as $attachment) {
|
foreach ($transactionJournal->attachments()->get() as $attachment) {
|
||||||
$attachment->delete();
|
$repository->destroy($attachment);
|
||||||
}
|
}
|
||||||
$transactionJournal->locations()->delete();
|
$transactionJournal->locations()->delete();
|
||||||
$transactionJournal->sourceJournalLinks()->delete();
|
$transactionJournal->sourceJournalLinks()->delete();
|
||||||
|
@@ -100,7 +100,7 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
'category_id',
|
'category_id',
|
||||||
'budget_id',
|
'budget_id',
|
||||||
];
|
];
|
||||||
$this->stringFields = ['amount', 'foreign_amount'];
|
$this->stringFields = ['amount', 'foreign_amount', 'native_amount', 'native_foreign_amount'];
|
||||||
$this->total = 0;
|
$this->total = 0;
|
||||||
$this->fields = [
|
$this->fields = [
|
||||||
// group
|
// group
|
||||||
@@ -714,6 +714,9 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
if (null === $transaction['amount']) {
|
if (null === $transaction['amount']) {
|
||||||
throw new FireflyException(sprintf('Amount is NULL for a transaction in group #%d, please investigate.', $groudId));
|
throw new FireflyException(sprintf('Amount is NULL for a transaction in group #%d, please investigate.', $groudId));
|
||||||
}
|
}
|
||||||
|
$nativeAmount = (string) ('' === $transaction['native_amount'] ? '0' : $transaction['native_amount']);
|
||||||
|
$nativeForeignAmount = (string) ('' === $transaction['native_foreign_amount'] ? '0' : $transaction['native_foreign_amount']);
|
||||||
|
$foreignAmount = (string) ('' === $transaction['foreign_amount'] ? '0' : $transaction['foreign_amount']);
|
||||||
|
|
||||||
// set default:
|
// set default:
|
||||||
if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) {
|
if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) {
|
||||||
@@ -724,9 +727,8 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
$groups[$groudId]['sums'][$currencyId]['amount'] = '0';
|
$groups[$groudId]['sums'][$currencyId]['amount'] = '0';
|
||||||
$groups[$groudId]['sums'][$currencyId]['native_amount'] = '0';
|
$groups[$groudId]['sums'][$currencyId]['native_amount'] = '0';
|
||||||
}
|
}
|
||||||
$transaction['native_amount'] = null === $transaction['native_amount'] ? '0' : $transaction['native_amount'];
|
|
||||||
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['amount']);
|
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['amount']);
|
||||||
$groups[$groudId]['sums'][$currencyId]['native_amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['native_amount'], $transaction['native_amount']);
|
$groups[$groudId]['sums'][$currencyId]['native_amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['native_amount'], $nativeAmount);
|
||||||
|
|
||||||
if (null !== $transaction['foreign_amount'] && null !== $transaction['foreign_currency_id']) {
|
if (null !== $transaction['foreign_amount'] && null !== $transaction['foreign_currency_id']) {
|
||||||
$currencyId = (int) $transaction['foreign_currency_id'];
|
$currencyId = (int) $transaction['foreign_currency_id'];
|
||||||
@@ -738,11 +740,10 @@ class GroupCollector implements GroupCollectorInterface
|
|||||||
$groups[$groudId]['sums'][$currencyId]['currency_symbol'] = $transaction['foreign_currency_symbol'];
|
$groups[$groudId]['sums'][$currencyId]['currency_symbol'] = $transaction['foreign_currency_symbol'];
|
||||||
$groups[$groudId]['sums'][$currencyId]['currency_decimal_places'] = $transaction['foreign_currency_decimal_places'];
|
$groups[$groudId]['sums'][$currencyId]['currency_decimal_places'] = $transaction['foreign_currency_decimal_places'];
|
||||||
$groups[$groudId]['sums'][$currencyId]['amount'] = '0';
|
$groups[$groudId]['sums'][$currencyId]['amount'] = '0';
|
||||||
$groups[$groudId]['sums'][$currencyId]['save_amount'] = '0';
|
$groups[$groudId]['sums'][$currencyId]['native_amount'] = '0';
|
||||||
}
|
}
|
||||||
$transaction['native_foreign_amount'] = null === $transaction['native_foreign_amount'] ? '0' : $transaction['native_foreign_amount'];
|
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $foreignAmount);
|
||||||
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['foreign_amount']);
|
$groups[$groudId]['sums'][$currencyId]['native_amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $nativeForeignAmount);
|
||||||
$groups[$groudId]['sums'][$currencyId]['native_amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['native_foreign_amount']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -108,11 +108,14 @@ class ReconcileController extends Controller
|
|||||||
if ($end->lt($start)) {
|
if ($end->lt($start)) {
|
||||||
[$start, $end] = [$end, $start];
|
[$start, $end] = [$end, $start];
|
||||||
}
|
}
|
||||||
|
// move dates to end of day and start of day:
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
$startDate = clone $start;
|
$startDate = clone $start;
|
||||||
$startDate->subDay();
|
$startDate->subDay()->endOfDay();
|
||||||
$startBalance = Steam::finalAccountBalance($account, $startDate)['balance'];
|
$startBalance = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places);
|
||||||
$endBalance = Steam::finalAccountBalance($account, $end)['balance'];
|
$endBalance = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places);
|
||||||
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
|
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
|
||||||
$subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]);
|
$subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]);
|
||||||
|
|
||||||
|
@@ -93,6 +93,11 @@ class ShowController extends Controller
|
|||||||
if ($end->lt($start)) {
|
if ($end->lt($start)) {
|
||||||
[$start, $end] = [$end, $start];
|
[$start, $end] = [$end, $start];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure dates are end of day and start of day:
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
$location = $this->repository->getLocation($account);
|
$location = $this->repository->getLocation($account);
|
||||||
$attachments = $this->repository->getAttachments($account);
|
$attachments = $this->repository->getAttachments($account);
|
||||||
$today = today(config('app.timezone'));
|
$today = today(config('app.timezone'));
|
||||||
@@ -181,6 +186,8 @@ class ShowController extends Controller
|
|||||||
$subTitle = (string) trans('firefly.all_journals_for_account', ['name' => $account->name]);
|
$subTitle = (string) trans('firefly.all_journals_for_account', ['name' => $account->name]);
|
||||||
$periods = new Collection();
|
$periods = new Collection();
|
||||||
|
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setAccounts(new Collection([$account]))->setLimit($pageSize)->setPage($page)->withAccountInformation()->withCategoryInformation();
|
$collector->setAccounts(new Collection([$account]))->setLimit($pageSize)->setPage($page)->withAccountInformation()->withCategoryInformation();
|
||||||
|
@@ -109,8 +109,8 @@ class AccountController extends Controller
|
|||||||
$accountNames = $this->extractNames($accounts);
|
$accountNames = $this->extractNames($accounts);
|
||||||
|
|
||||||
// grab all balances
|
// grab all balances
|
||||||
$startBalances = app('steam')->finalAccountsBalance($accounts, $start);
|
$startBalances = Steam::finalAccountsBalance($accounts, $start);
|
||||||
$endBalances = app('steam')->finalAccountsBalance($accounts, $end);
|
$endBalances = Steam::finalAccountsBalance($accounts, $end);
|
||||||
|
|
||||||
// loop the accounts, then check for balance and currency info.
|
// loop the accounts, then check for balance and currency info.
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
@@ -416,7 +416,9 @@ class AccountController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function period(Account $account, Carbon $start, Carbon $end): JsonResponse
|
public function period(Account $account, Carbon $start, Carbon $end): JsonResponse
|
||||||
{
|
{
|
||||||
Log::debug(sprintf('Now in period("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d')));
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
Log::debug(sprintf('Now in period("%s", "%s")', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
|
||||||
$chartData = [];
|
$chartData = [];
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty('chart.account.period');
|
$cache->addProperty('chart.account.period');
|
||||||
@@ -431,7 +433,7 @@ class AccountController extends Controller
|
|||||||
// collect and filter balances for the entire period.
|
// collect and filter balances for the entire period.
|
||||||
$step = $this->calculateStep($start, $end);
|
$step = $this->calculateStep($start, $end);
|
||||||
Log::debug(sprintf('Step is %s', $step));
|
Log::debug(sprintf('Step is %s', $step));
|
||||||
$locale = app('steam')->getLocale();
|
$locale = Steam::getLocale();
|
||||||
$return = [];
|
$return = [];
|
||||||
|
|
||||||
// fix for issue https://github.com/firefly-iii/firefly-iii/issues/8041
|
// fix for issue https://github.com/firefly-iii/firefly-iii/issues/8041
|
||||||
@@ -442,11 +444,8 @@ class AccountController extends Controller
|
|||||||
$format = (string) trans('config.month_and_day_js', [], $locale);
|
$format = (string) trans('config.month_and_day_js', [], $locale);
|
||||||
$accountCurrency = $this->accountRepository->getAccountCurrency($account);
|
$accountCurrency = $this->accountRepository->getAccountCurrency($account);
|
||||||
|
|
||||||
Log::debug('One');
|
|
||||||
$range = Steam::finalAccountBalanceInRange($account, $start, $end, $this->convertToNative);
|
$range = Steam::finalAccountBalanceInRange($account, $start, $end, $this->convertToNative);
|
||||||
Log::debug('Two');
|
|
||||||
$range = Steam::filterAccountBalances($range, $account, $this->convertToNative, $accountCurrency);
|
$range = Steam::filterAccountBalances($range, $account, $this->convertToNative, $accountCurrency);
|
||||||
Log::debug('Three');
|
|
||||||
|
|
||||||
// temp, get end balance.
|
// temp, get end balance.
|
||||||
Log::debug('temp get end balance');
|
Log::debug('temp get end balance');
|
||||||
@@ -462,25 +461,32 @@ class AccountController extends Controller
|
|||||||
Log::debug('Balances exist at:');
|
Log::debug('Balances exist at:');
|
||||||
foreach ($range as $key => $value) {
|
foreach ($range as $key => $value) {
|
||||||
$newRange[] = ['date' => $key, 'info' => $value];
|
$newRange[] = ['date' => $key, 'info' => $value];
|
||||||
Log::debug(sprintf(' - %s', $key));
|
Log::debug(sprintf('%d - %s (%s)', count($newRange) - 1, $key, json_encode($value)));
|
||||||
}
|
}
|
||||||
$carbon = Carbon::createFromFormat('Y-m-d', $newRange[0]['date']);
|
$carbon = Carbon::createFromFormat('Y-m-d', $newRange[0]['date'])->endOfDay();
|
||||||
|
Log::debug(sprintf('Start of loop, $carbon is %s', $carbon->format('Y-m-d H:i:s')));
|
||||||
while ($end->gte($current)) {
|
while ($end->gte($current)) {
|
||||||
$momentBalance = $previous;
|
$momentBalance = $previous;
|
||||||
$theDate = $current->format('Y-m-d');
|
// $theDate = $current->format('Y-m-d');
|
||||||
while ($carbon->lte($current) && array_key_exists($expectedIndex, $newRange)) {
|
Log::debug(sprintf('Now at %s, with momentBalance %s', $current->format('Y-m-d H:i:s'), json_encode($momentBalance)));
|
||||||
$momentBalance = $newRange[$expectedIndex]['info'];
|
|
||||||
Log::debug(sprintf('Expected index is %d!, date is %s, current is %s', $expectedIndex, $carbon->format('Y-m-d'), $current->format('Y-m-d')));
|
|
||||||
$carbon = Carbon::createFromFormat('Y-m-d', $newRange[$expectedIndex]['date']);
|
|
||||||
++$expectedIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// loop over the array with balances, find one that is earlier or on the same day.
|
||||||
|
while ($carbon->lte($current) && array_key_exists($expectedIndex, $newRange)) {
|
||||||
|
Log::debug(sprintf('[a] Expected index is %d, $carbon is %s, current is %s', $expectedIndex, $carbon->format('Y-m-d H:i:s'), $current->format('Y-m-d H:i:s')));
|
||||||
|
|
||||||
|
// grab the balance from that particular $expectedIndex
|
||||||
|
$momentBalance = $newRange[$expectedIndex]['info'];
|
||||||
|
++$expectedIndex;
|
||||||
|
|
||||||
|
// make new carbon based on the next found date. this should stop the loop.
|
||||||
|
if (array_key_exists($expectedIndex, $newRange)) {
|
||||||
|
$carbon = Carbon::createFromFormat('Y-m-d', $newRange[$expectedIndex]['date'])->endOfDay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log::debug(sprintf('momentBalance is now %s', json_encode($momentBalance)));
|
||||||
$return = $this->updateChartKeys($return, $momentBalance);
|
$return = $this->updateChartKeys($return, $momentBalance);
|
||||||
$previous = $momentBalance;
|
$previous = $momentBalance;
|
||||||
|
|
||||||
Log::debug(sprintf('Now at %s', $theDate), $momentBalance);
|
|
||||||
|
|
||||||
|
|
||||||
// process each balance thing.
|
// process each balance thing.
|
||||||
foreach ($momentBalance as $key => $amount) {
|
foreach ($momentBalance as $key => $amount) {
|
||||||
$label = $current->isoFormat($format);
|
$label = $current->isoFormat($format);
|
||||||
@@ -489,8 +495,6 @@ class AccountController extends Controller
|
|||||||
$current = app('navigation')->addPeriod($current, $step, 0);
|
$current = app('navigation')->addPeriod($current, $step, 0);
|
||||||
// here too, to fix #8041, the data is corrected to the end of the period.
|
// here too, to fix #8041, the data is corrected to the end of the period.
|
||||||
$current = app('navigation')->endOfX($current, $step, null);
|
$current = app('navigation')->endOfX($current, $step, null);
|
||||||
Log::debug(sprintf('Next moment is %s', $current->format('Y-m-d')));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Log::debug('End of chart loop.');
|
Log::debug('End of chart loop.');
|
||||||
// second loop (yes) to create nice array with info! Yay!
|
// second loop (yes) to create nice array with info! Yay!
|
||||||
@@ -567,8 +571,8 @@ class AccountController extends Controller
|
|||||||
$accountNames = $this->extractNames($accounts);
|
$accountNames = $this->extractNames($accounts);
|
||||||
|
|
||||||
// grab all balances
|
// grab all balances
|
||||||
$startBalances = app('steam')->finalAccountsBalance($accounts, $start);
|
$startBalances = Steam::finalAccountsBalance($accounts, $start);
|
||||||
$endBalances = app('steam')->finalAccountsBalance($accounts, $end);
|
$endBalances = Steam::finalAccountsBalance($accounts, $end);
|
||||||
|
|
||||||
|
|
||||||
// loop the accounts, then check for balance and currency info.
|
// loop the accounts, then check for balance and currency info.
|
||||||
|
@@ -189,13 +189,14 @@ class ReconcileController extends Controller
|
|||||||
if ($end->lt($start)) {
|
if ($end->lt($start)) {
|
||||||
[$end, $start] = [$start, $end];
|
[$end, $start] = [$start, $end];
|
||||||
}
|
}
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
$startDate = clone $start;
|
$startDate = clone $start;
|
||||||
$startDate->subDay();
|
$startDate->subDay();
|
||||||
$end->endOfDay();
|
|
||||||
|
|
||||||
$currency = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency;
|
$currency = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency;
|
||||||
$startBalance = Steam::finalAccountBalance($account, $startDate)['balance'];
|
$startBalance = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places);
|
||||||
$endBalance = Steam::finalAccountBalance($account, $end)['balance'];
|
$endBalance = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places);
|
||||||
|
|
||||||
// get the transactions
|
// get the transactions
|
||||||
$selectionStart = clone $start;
|
$selectionStart = clone $start;
|
||||||
|
@@ -83,6 +83,8 @@ class ReportController extends Controller
|
|||||||
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
|
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
|
||||||
}
|
}
|
||||||
$this->repository->cleanupBudgets();
|
$this->repository->cleanupBudgets();
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
app('view')->share(
|
app('view')->share(
|
||||||
'subTitle',
|
'subTitle',
|
||||||
@@ -114,6 +116,8 @@ class ReportController extends Controller
|
|||||||
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
|
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
|
||||||
}
|
}
|
||||||
$this->repository->cleanupBudgets();
|
$this->repository->cleanupBudgets();
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
app('view')->share(
|
app('view')->share(
|
||||||
'subTitle',
|
'subTitle',
|
||||||
@@ -146,6 +150,8 @@ class ReportController extends Controller
|
|||||||
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
|
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
|
||||||
}
|
}
|
||||||
$this->repository->cleanupBudgets();
|
$this->repository->cleanupBudgets();
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
app('view')->share(
|
app('view')->share(
|
||||||
'subTitle',
|
'subTitle',
|
||||||
@@ -179,6 +185,8 @@ class ReportController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->repository->cleanupBudgets();
|
$this->repository->cleanupBudgets();
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
app('view')->share(
|
app('view')->share(
|
||||||
'subTitle',
|
'subTitle',
|
||||||
@@ -211,6 +219,8 @@ class ReportController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->repository->cleanupBudgets();
|
$this->repository->cleanupBudgets();
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
app('view')->share(
|
app('view')->share(
|
||||||
'subTitle',
|
'subTitle',
|
||||||
@@ -367,6 +377,8 @@ class ReportController extends Controller
|
|||||||
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
|
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
|
||||||
}
|
}
|
||||||
$this->repository->cleanupBudgets();
|
$this->repository->cleanupBudgets();
|
||||||
|
$start->startOfDay();
|
||||||
|
$end->endOfDay();
|
||||||
|
|
||||||
app('view')->share(
|
app('view')->share(
|
||||||
'subTitle',
|
'subTitle',
|
||||||
|
@@ -57,7 +57,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getCompleteSet(): Collection
|
public function getCompleteSet(): Collection
|
||||||
{
|
{
|
||||||
return TransactionCurrency::orderBy('code', 'ASC')->get();
|
return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -108,6 +108,6 @@ class ExchangeRateRepository implements ExchangeRateRepositoryInterface
|
|||||||
#[\Override]
|
#[\Override]
|
||||||
public function getAll(): Collection
|
public function getAll(): Collection
|
||||||
{
|
{
|
||||||
return $this->userGroup->currencyExchangeRates()->get();
|
return $this->userGroup->currencyExchangeRates()->orderBy('date', 'ASC')->get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,10 +28,11 @@ use FireflyIII\Exceptions\FireflyException;
|
|||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
|
use FireflyIII\Support\Facades\Amount;
|
||||||
|
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use FireflyIII\Support\Facades\Amount;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Steam.
|
* Class Steam.
|
||||||
@@ -75,98 +76,79 @@ class Steam
|
|||||||
$balances = [];
|
$balances = [];
|
||||||
$formatted = $start->format('Y-m-d');
|
$formatted = $start->format('Y-m-d');
|
||||||
$startBalance = $this->finalAccountBalance($account, $start);
|
$startBalance = $this->finalAccountBalance($account, $start);
|
||||||
$defaultCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup);
|
$nativeCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup);
|
||||||
$accountCurrency = $this->getAccountCurrency($account);
|
$accountCurrency = $this->getAccountCurrency($account);
|
||||||
$hasCurrency = null !== $accountCurrency;
|
$hasCurrency = null !== $accountCurrency;
|
||||||
$currency = $accountCurrency ?? $defaultCurrency;
|
$currency = $accountCurrency ?? $nativeCurrency;
|
||||||
Log::debug(sprintf('Currency is %s', $currency->code));
|
Log::debug(sprintf('Currency is %s', $currency->code));
|
||||||
|
|
||||||
|
// set start balances:
|
||||||
|
$startBalance[$currency->code] ??= '0';
|
||||||
|
if ($hasCurrency) {
|
||||||
|
$startBalance[$accountCurrency->code] ??= '0';
|
||||||
|
}
|
||||||
if (!$hasCurrency) {
|
if (!$hasCurrency) {
|
||||||
Log::debug(sprintf('Also set start balance in %s', $defaultCurrency->code));
|
Log::debug(sprintf('Also set start balance in %s', $nativeCurrency->code));
|
||||||
$startBalance[$defaultCurrency->code] ??= '0';
|
$startBalance[$nativeCurrency->code] ??= '0';
|
||||||
}
|
}
|
||||||
$currencies = [
|
$currencies = [
|
||||||
$currency->id => $currency,
|
$currency->id => $currency,
|
||||||
$defaultCurrency->id => $defaultCurrency,
|
$nativeCurrency->id => $nativeCurrency,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
$startBalance[$currency->code] ??= '0';
|
|
||||||
$balances[$formatted] = $startBalance;
|
$balances[$formatted] = $startBalance;
|
||||||
Log::debug('Final start balance: ', $startBalance);
|
Log::debug('Final start balance: ', $startBalance);
|
||||||
|
|
||||||
|
// sums up the balance changes per day.
|
||||||
// sums up the balance changes per day, for foreign, native and normal amounts.
|
|
||||||
$set = $account->transactions()
|
$set = $account->transactions()
|
||||||
->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s'))
|
->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s'))
|
||||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s'))
|
->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s'))
|
||||||
->groupBy('transaction_journals.date')
|
->groupBy('transaction_journals.date')
|
||||||
->groupBy('transactions.transaction_currency_id')
|
->groupBy('transactions.transaction_currency_id')
|
||||||
->groupBy('transactions.foreign_currency_id')
|
|
||||||
->orderBy('transaction_journals.date', 'ASC')
|
->orderBy('transaction_journals.date', 'ASC')
|
||||||
->whereNull('transaction_journals.deleted_at')
|
->whereNull('transaction_journals.deleted_at')
|
||||||
->get(
|
->get(
|
||||||
[ // @phpstan-ignore-line
|
[ // @phpstan-ignore-line
|
||||||
'transaction_journals.date',
|
'transaction_journals.date',
|
||||||
'transactions.transaction_currency_id',
|
'transactions.transaction_currency_id',
|
||||||
DB::raw('SUM(transactions.amount) AS modified'),
|
DB::raw('SUM(transactions.amount) AS sum_of_day'),
|
||||||
'transactions.foreign_currency_id',
|
|
||||||
DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'),
|
|
||||||
DB::raw('SUM(transactions.native_amount) AS modified_native'),
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
$currentBalance = $startBalance;
|
$currentBalance = $startBalance;
|
||||||
|
$converter = new ExchangeRateConverter();
|
||||||
|
|
||||||
|
|
||||||
/** @var Transaction $entry */
|
/** @var Transaction $entry */
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
// normal, native and foreign amount
|
// get date object
|
||||||
$carbon = new Carbon($entry->date, $entry->date_tz);
|
$carbon = new Carbon($entry->date, $entry->date_tz);
|
||||||
$modified = (string) (null === $entry->modified ? '0' : $entry->modified);
|
// make sure sum is a string:
|
||||||
$foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign);
|
$sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day);
|
||||||
$nativeModified = (string) (null === $entry->modified_native ? '0' : $entry->modified_native);
|
|
||||||
|
|
||||||
// find currency of this entry.
|
// find currency of this entry, does not have to exist.
|
||||||
$currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id);
|
$currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id);
|
||||||
|
|
||||||
|
// make sure this $entry has its own $entryCurrency
|
||||||
/** @var TransactionCurrency $entryCurrency */
|
/** @var TransactionCurrency $entryCurrency */
|
||||||
$entryCurrency = $currencies[$entry->transaction_currency_id];
|
$entryCurrency = $currencies[$entry->transaction_currency_id];
|
||||||
|
|
||||||
Log::debug(sprintf('Processing transaction(s) on date %s', $carbon->format('Y-m-d H:i:s')));
|
Log::debug(sprintf('Processing transaction(s) on date %s', $carbon->format('Y-m-d H:i:s')));
|
||||||
|
$currentBalance[$entryCurrency->code] ??= '0';
|
||||||
|
$currentBalance[$entryCurrency->code] = bcadd($sumOfDay, $currentBalance[$entryCurrency->code]);
|
||||||
|
|
||||||
// if convert to native, if NOT convert to native.
|
// if not convert to native, add the amount to "balance", do nothing else.
|
||||||
if ($convertToNative) {
|
|
||||||
Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $this->bcround($modified, 2), $this->bcround($foreignModified, 2), $this->bcround($nativeModified, 2)));
|
|
||||||
// if the currency is the default currency add to native balance + currency balance
|
|
||||||
if ($entry->transaction_currency_id === $defaultCurrency->id) {
|
|
||||||
Log::debug('Add amount to native.');
|
|
||||||
$currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $modified);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add to native balance.
|
|
||||||
if ($entry->foreign_currency_id !== $defaultCurrency->id) {
|
|
||||||
// this check is not necessary, because if the foreign currency is the same as the default currency, the native amount is zero.
|
|
||||||
// so adding this would mean nothing.
|
|
||||||
$currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeModified);
|
|
||||||
}
|
|
||||||
if ($entry->foreign_currency_id === $defaultCurrency->id) {
|
|
||||||
$currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $foreignModified);
|
|
||||||
}
|
|
||||||
// add to balance if is the same.
|
|
||||||
if ($entry->transaction_currency_id === $accountCurrency?->id) {
|
|
||||||
$currentBalance['balance'] = bcadd($currentBalance['balance'], $modified);
|
|
||||||
}
|
|
||||||
// add currency balance
|
|
||||||
$currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified);
|
|
||||||
}
|
|
||||||
if (!$convertToNative) {
|
if (!$convertToNative) {
|
||||||
Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $modified, $foreignModified, $nativeModified));
|
$currentBalance['balance'] = bcadd($currentBalance['balance'], $sumOfDay);
|
||||||
// add to balance, as expected.
|
|
||||||
$currentBalance['balance'] = bcadd($currentBalance['balance'] ?? '0', $modified);
|
|
||||||
// add to GBP, as expected.
|
|
||||||
$currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified);
|
|
||||||
}
|
}
|
||||||
|
// if convert to native add the converted amount to "native_balance".
|
||||||
|
if ($convertToNative) {
|
||||||
|
$nativeSumOfDay = $converter->convert($entryCurrency, $nativeCurrency, $carbon, $sumOfDay);
|
||||||
|
$currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeSumOfDay);
|
||||||
|
}
|
||||||
|
// add final $currentBalance array to the big one.
|
||||||
$balances[$carbon->format('Y-m-d')] = $currentBalance;
|
$balances[$carbon->format('Y-m-d')] = $currentBalance;
|
||||||
Log::debug('Updated entry', $currentBalance);
|
Log::debug('Updated entry', $currentBalance);
|
||||||
}
|
}
|
||||||
@@ -275,24 +257,14 @@ class Steam
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the balance of an account at exact moment given. Array with at least one value.
|
* Returns the balance of an account at exact moment given. Array with at least one value.
|
||||||
|
* Always returns:
|
||||||
|
* "balance": balance in the account's currency OR user's native currency if the account has no currency
|
||||||
|
* "EUR": balance in EUR (or whatever currencies the account has balance in)
|
||||||
*
|
*
|
||||||
* "balance" the balance in whatever currency the account has, so the sum of all transaction that happen to have
|
* If the user has $convertToNative:
|
||||||
* THAT currency.
|
* "balance": balance in the account's currency OR user's native currency if the account has no currency
|
||||||
* "native_balance" the balance according to the "native_amount" + "native_foreign_amount" fields.
|
* --> "native_balance": balance in the user's native balance, with all amounts converted to native.
|
||||||
* "ABC" the balance in this particular currency code (may repeat for each found currency).
|
* "EUR": balance in EUR (or whatever currencies the account has balance in)
|
||||||
*
|
|
||||||
* Het maakt niet uit of de native currency wel of niet gelijk is aan de account currency.
|
|
||||||
* Optelsom zou hetzelfde moeten zijn. Als het EUR is en de rekening ook is native_amount 0.
|
|
||||||
* Zo niet is amount 0 en native_amount het bedrag.
|
|
||||||
*
|
|
||||||
* Eerst een som van alle transacties in de native currency. Alle EUR bij elkaar opgeteld.
|
|
||||||
* Om te weten wat er nog meer op de rekening gebeurt, pak alles waar currency niet EUR is, en de foreign ook niet,
|
|
||||||
* en tel native_amount erbij op.
|
|
||||||
* Daarna pak je alle transacties waar currency niet EUR is, en de foreign wel, en tel foreign_amount erbij op.
|
|
||||||
*
|
|
||||||
* Wil je niks weten van native currencies, pak je:
|
|
||||||
*
|
|
||||||
* Eerst een som van alle transacties gegroepeerd op currency. Einde.
|
|
||||||
*/
|
*/
|
||||||
public function finalAccountBalance(Account $account, Carbon $date): array
|
public function finalAccountBalance(Account $account, Carbon $date): array
|
||||||
{
|
{
|
||||||
@@ -310,48 +282,11 @@ class Steam
|
|||||||
$accountCurrency = $this->getAccountCurrency($account);
|
$accountCurrency = $this->getAccountCurrency($account);
|
||||||
$hasCurrency = null !== $accountCurrency;
|
$hasCurrency = null !== $accountCurrency;
|
||||||
$currency = $hasCurrency ? $accountCurrency : $native;
|
$currency = $hasCurrency ? $accountCurrency : $native;
|
||||||
$return = [];
|
$return = [
|
||||||
|
'native_balance' => '0',
|
||||||
// first, the "balance", as described earlier.
|
'balance' => '0', // this key is overwritten right away, but I must remember it is always created.
|
||||||
if ($convertToNative) {
|
];
|
||||||
// normal balance
|
// balance(s) in all currencies.
|
||||||
$return['balance'] = (string) $account->transactions()
|
|
||||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
|
||||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
|
|
||||||
->where('transactions.transaction_currency_id', $native->id)
|
|
||||||
->sum('transactions.amount')
|
|
||||||
;
|
|
||||||
// plus virtual balance, if the account has a virtual_balance in the native currency
|
|
||||||
if ($native->id === $accountCurrency?->id) {
|
|
||||||
$return['balance'] = bcadd('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance, $return['balance']);
|
|
||||||
}
|
|
||||||
// Log::debug(sprintf('balance is (%s only) %s (with virtual balance)', $native->code, $this->bcround($return['balance'], 2)));
|
|
||||||
|
|
||||||
// native balance
|
|
||||||
$return['native_balance'] = (string) $account->transactions()
|
|
||||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
|
||||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
|
|
||||||
->whereNot('transactions.transaction_currency_id', $native->id)
|
|
||||||
->sum('transactions.native_amount')
|
|
||||||
;
|
|
||||||
// plus native virtual balance.
|
|
||||||
$return['native_balance'] = bcadd('' === (string) $account->native_virtual_balance ? '0' : $account->native_virtual_balance, $return['native_balance']);
|
|
||||||
// Log::debug(sprintf('native_balance is (all transactions to %s) %s (with virtual balance)', $native->code, $this->bcround($return['native_balance'])));
|
|
||||||
|
|
||||||
// plus foreign transactions in THIS currency.
|
|
||||||
$sum = (string) $account->transactions()
|
|
||||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
|
||||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
|
|
||||||
->whereNot('transactions.transaction_currency_id', $native->id)
|
|
||||||
->where('transactions.foreign_currency_id', $native->id)
|
|
||||||
->sum('transactions.foreign_amount')
|
|
||||||
;
|
|
||||||
$return['native_balance'] = bcadd($return['native_balance'], $sum);
|
|
||||||
|
|
||||||
// Log::debug(sprintf('Foreign amount transactions add (%s only) %s, total native_balance is now %s', $native->code, $this->bcround($sum), $this->bcround($return['native_balance'])));
|
|
||||||
}
|
|
||||||
|
|
||||||
// balance(s) in other (all) currencies.
|
|
||||||
$array = $account->transactions()
|
$array = $account->transactions()
|
||||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||||
->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id')
|
->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id')
|
||||||
@@ -360,31 +295,38 @@ class Steam
|
|||||||
;
|
;
|
||||||
$others = $this->groupAndSumTransactions($array, 'code', 'amount');
|
$others = $this->groupAndSumTransactions($array, 'code', 'amount');
|
||||||
// Log::debug('All balances are (joined)', $others);
|
// Log::debug('All balances are (joined)', $others);
|
||||||
// if the account has no own currency preference, drop balance in favor of native balance
|
// if there is no request to convert, take this as "balance" and "native_balance".
|
||||||
if ($hasCurrency && !$convertToNative) {
|
|
||||||
$return['balance'] = $others[$currency->code] ?? '0';
|
$return['balance'] = $others[$currency->code] ?? '0';
|
||||||
$return['native_balance'] = $others[$currency->code] ?? '0';
|
if (!$convertToNative) {
|
||||||
// Log::debug(sprintf('Set balance + native_balance to %s', $return['balance']));
|
unset($return['native_balance']);
|
||||||
|
// Log::debug(sprintf('Set balance to %s, unset native_balance', $return['balance']));
|
||||||
|
}
|
||||||
|
// if there is a request to convert, convert to "native_balance" and use "balance" for whichever amount is in the native currency.
|
||||||
|
if ($convertToNative) {
|
||||||
|
$return['native_balance'] = $this->convertAllBalances($others, $native, $date); // todo sum all and convert.
|
||||||
|
// Log::debug(sprintf('Set native_balance to %s', $return['native_balance']));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the currency is the same as the native currency, set the native_balance to the balance for consistency.
|
// either way, the balance is always combined with the virtual balance:
|
||||||
// if($currency->id === $native->id) {
|
$virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance);
|
||||||
// $return['native_balance'] = $return['balance'];
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (!$hasCurrency && array_key_exists('balance', $return)) {
|
if ($convertToNative) {
|
||||||
// Log::debug('Account has no currency preference, dropping balance in favor of native balance.');
|
// the native balance is combined with a converted virtual_balance:
|
||||||
$sum = bcadd($return['balance'], $return['native_balance']);
|
$converter = new ExchangeRateConverter();
|
||||||
// Log::debug(sprintf('%s + %s = %s', $return['balance'], $return['native_balance'], $sum));
|
$nativeVirtualBalance = $converter->convert($currency, $native, $date, $virtualBalance);
|
||||||
$return['native_balance'] = $sum;
|
$return['native_balance'] = bcadd($nativeVirtualBalance, $return['native_balance']);
|
||||||
unset($return['balance']);
|
// Log::debug(sprintf('Native virtual balance makes the native total %s', $return['native_balance']));
|
||||||
|
}
|
||||||
|
if (!$convertToNative) {
|
||||||
|
// if not, also increase the balance + native balance for consistency.
|
||||||
|
$return['balance'] = bcadd($return['balance'], $virtualBalance);
|
||||||
|
// Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['balance']));
|
||||||
}
|
}
|
||||||
$final = array_merge($return, $others);
|
$final = array_merge($return, $others);
|
||||||
// Log::debug('Return is', $final);
|
Log::debug('Final balance is', $final);
|
||||||
$cache->store($final);
|
$cache->store($final);
|
||||||
|
|
||||||
return array_merge($return, $others);
|
return $final;
|
||||||
// Log::debug('Return is', $final);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function filterAccountBalances(array $total, Account $account, bool $convertToNative, ?TransactionCurrency $currency = null): array
|
public function filterAccountBalances(array $total, Account $account, bool $convertToNative, ?TransactionCurrency $currency = null): array
|
||||||
@@ -410,17 +352,18 @@ class Steam
|
|||||||
$defaultCurrency = app('amount')->getNativeCurrency();
|
$defaultCurrency = app('amount')->getNativeCurrency();
|
||||||
if ($convertToNative) {
|
if ($convertToNative) {
|
||||||
if ($defaultCurrency->id === $currency?->id) {
|
if ($defaultCurrency->id === $currency?->id) {
|
||||||
Log::debug(sprintf('Unset "native_balance" and "%s" for account #%d', $defaultCurrency->code, $account->id));
|
Log::debug(sprintf('Unset "native_balance" and [%s] for account #%d', $defaultCurrency->code, $account->id));
|
||||||
unset($set['native_balance'], $set[$defaultCurrency->code]);
|
unset($set['native_balance'], $set[$defaultCurrency->code]);
|
||||||
}
|
}
|
||||||
|
// todo rethink this logic.
|
||||||
if (null !== $currency && $defaultCurrency->id !== $currency->id) {
|
if (null !== $currency && $defaultCurrency->id !== $currency->id) {
|
||||||
Log::debug(sprintf('Unset balance for account #%d', $account->id));
|
Log::debug(sprintf('Unset balance for account #%d', $account->id));
|
||||||
unset($set['balance']);
|
unset($set['balance']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $currency) {
|
if (null === $currency) {
|
||||||
Log::debug(sprintf('TEMP DO NOT Drop defaultCurrency balance for account #%d', $account->id));
|
Log::debug(sprintf('Unset balance for account #%d', $account->id));
|
||||||
// unset($set[$this->defaultCurrency->code]);
|
unset($set['balance']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,16 +371,15 @@ class Steam
|
|||||||
if (null === $currency) {
|
if (null === $currency) {
|
||||||
Log::debug(sprintf('Unset native_balance and make defaultCurrency balance the balance for account #%d', $account->id));
|
Log::debug(sprintf('Unset native_balance and make defaultCurrency balance the balance for account #%d', $account->id));
|
||||||
$set['balance'] = $set[$defaultCurrency->code] ?? '0';
|
$set['balance'] = $set[$defaultCurrency->code] ?? '0';
|
||||||
unset($set['native_balance'], $set[$defaultCurrency->code]);
|
unset($set[$defaultCurrency->code]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $currency) {
|
if (null !== $currency) {
|
||||||
Log::debug(sprintf('Unset native_balance + defaultCurrency + currencyCode balance for account #%d', $account->id));
|
Log::debug(sprintf('Unset [%s] + [%s] balance for account #%d', $defaultCurrency->code, $currency->code, $account->id));
|
||||||
unset($set['native_balance'], $set[$defaultCurrency->code], $set[$currency->code]);
|
unset($set[$defaultCurrency->code], $set[$currency->code]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// put specific value first in array.
|
// put specific value first in array.
|
||||||
if (array_key_exists('native_balance', $set)) {
|
if (array_key_exists('native_balance', $set)) {
|
||||||
$set = ['native_balance' => $set['native_balance']] + $set;
|
$set = ['native_balance' => $set['native_balance']] + $set;
|
||||||
@@ -687,4 +629,21 @@ class Steam
|
|||||||
|
|
||||||
return $amount;
|
return $amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function convertAllBalances(array $others, TransactionCurrency $native, Carbon $date): string
|
||||||
|
{
|
||||||
|
$total = '0';
|
||||||
|
$converter = new ExchangeRateConverter();
|
||||||
|
foreach ($others as $key => $amount) {
|
||||||
|
$currency = TransactionCurrency::where('code', $key)->first();
|
||||||
|
if (null === $currency) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$current = $converter->convert($currency, $native, $date, $amount);
|
||||||
|
Log::debug(sprintf('Convert %s %s to %s %s', $currency->code, $amount, $native->code, $current));
|
||||||
|
$total = bcadd($current, $total);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $total;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -132,7 +132,7 @@ class PiggyBankTransformer extends AbstractTransformer
|
|||||||
$return = [];
|
$return = [];
|
||||||
foreach ($piggyBank->accounts()->get() as $account) {
|
foreach ($piggyBank->accounts()->get() as $account) {
|
||||||
$return[] = [
|
$return[] = [
|
||||||
'id' => $account->id,
|
'id' => (string) $account->id,
|
||||||
'name' => $account->name,
|
'name' => $account->name,
|
||||||
'current_amount' => (string) $account->pivot->current_amount,
|
'current_amount' => (string) $account->pivot->current_amount,
|
||||||
'native_current_amount' => (string) $account->pivot->native_current_amount,
|
'native_current_amount' => (string) $account->pivot->native_current_amount,
|
||||||
|
38
changelog.md
38
changelog.md
@@ -3,6 +3,44 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
## 6.2.3 - 2025-02-05
|
||||||
|
|
||||||
|
> ⚠️ _Most pressing issues are fixed. Please open [an issue here](https://github.com/firefly-iii/firefly-iii/issues/new?template=bug.yml) if you run into problems._
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- [Issue 9327](https://github.com/firefly-iii/firefly-iii/issues/9327) (Add Link to Search-Page to the help file) reported by @nottheend
|
||||||
|
- [Issue 9713](https://github.com/firefly-iii/firefly-iii/issues/9713) (Many decimal points in amounts) reported by @memo-567
|
||||||
|
- [Issue 9736](https://github.com/firefly-iii/firefly-iii/issues/9736) (Wrong `finalAccountBalance` result) reported by @gthbusrr
|
||||||
|
- [Discussion 9737](https://github.com/orgs/firefly-iii/discussions/9737) (API returns 0 as current balance) started by @eps90
|
||||||
|
- [Issue 9745](https://github.com/firefly-iii/firefly-iii/issues/9745) (Type mismatch in period overview) reported by @electrofloat
|
||||||
|
- [Issue 9747](https://github.com/firefly-iii/firefly-iii/issues/9747) (Data entry issues with exchange rates) reported by @Azmodeszer
|
||||||
|
- [Issue 9751](https://github.com/firefly-iii/firefly-iii/issues/9751) (Net worth changes since 6.2 update) reported by @ahmaddxb
|
||||||
|
- [Issue 9754](https://github.com/firefly-iii/firefly-iii/issues/9754) (Deleting account - Attachments remain) reported by @memo-567
|
||||||
|
- [Issue 9762](https://github.com/firefly-iii/firefly-iii/issues/9762) (Piggy bank show: start/target date not displayed) reported by @Simeam
|
||||||
|
- Various other balance related fixes.
|
||||||
|
|
||||||
|
## 6.2.2 - 2025-02-02
|
||||||
|
|
||||||
|
> ⚠️ _This release comes with many changes, small and large. I expect you will run into issue, and I appreciate your feedback and your patience as I fix them. I've tested many things, but I'm 100% sure I've missed things. Please open [an issue here](https://github.com/firefly-iii/firefly-iii/issues/new?template=bug.yml) if you run into problems._
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- [Issue 9713](https://github.com/firefly-iii/firefly-iii/issues/9713) (Many decimal points in amounts) reported by @memo-567
|
||||||
|
- [Discussion 9727](https://github.com/orgs/firefly-iii/discussions/9727) (Odd behavior from graphs) started by @jbrandwi
|
||||||
|
- [Issue 9729](https://github.com/firefly-iii/firefly-iii/issues/9729) (Type mismatch in transaction collector) reported by @electrofloat
|
||||||
|
- [Issue 9730](https://github.com/firefly-iii/firefly-iii/issues/9730) (API: `PiggyBankAccountRead.id` should return string, returns int) reported by @dreautall
|
||||||
|
- [Issue 9731](https://github.com/firefly-iii/firefly-iii/issues/9731) ($userGroup must not be accessed before initialization) reported by @Azmodeszer
|
||||||
|
- [Issue 9732](https://github.com/firefly-iii/firefly-iii/issues/9732) (Editing dates of a piggy bank does not save) reported by @Simeam
|
||||||
|
- [Issue 9736](https://github.com/firefly-iii/firefly-iii/issues/9736) (Wrong `finalAccountBalance` result) reported by @gthbusrr
|
||||||
|
- [Issue 9738](https://github.com/firefly-iii/firefly-iii/issues/9738) (Missing pagination controls on exchange rate page) reported by @dicksonleong
|
||||||
|
- [Discussion 9744](https://github.com/orgs/firefly-iii/discussions/9744) (Downloading exchange rates results in 404 error) started by @electrofloat
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- [PR 9743](https://github.com/firefly-iii/firefly-iii/pull/9743) (Feature nordic currencies) reported by @mansehr
|
||||||
|
|
||||||
|
|
||||||
## 6.2.1 - 2025-02-01
|
## 6.2.1 - 2025-02-01
|
||||||
|
|
||||||
> ⚠️ _This release comes with many changes, small and large. I expect you will run into issue, and I appreciate your feedback and your patience as I fix them. I've tested many things, but I'm 100% sure I've missed things. Please open [an issue here](https://github.com/firefly-iii/firefly-iii/issues/new?template=bug.yml) if you run into problems._
|
> ⚠️ _This release comes with many changes, small and large. I expect you will run into issue, and I appreciate your feedback and your patience as I fix them. I've tested many things, but I'm 100% sure I've missed things. Please open [an issue here](https://github.com/firefly-iii/firefly-iii/issues/new?template=bug.yml) if you run into problems._
|
||||||
|
12
composer.lock
generated
12
composer.lock
generated
@@ -1571,16 +1571,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/uri-template",
|
"name": "guzzlehttp/uri-template",
|
||||||
"version": "v1.0.3",
|
"version": "v1.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/guzzle/uri-template.git",
|
"url": "https://github.com/guzzle/uri-template.git",
|
||||||
"reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c"
|
"reference": "30e286560c137526eccd4ce21b2de477ab0676d2"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c",
|
"url": "https://api.github.com/repos/guzzle/uri-template/zipball/30e286560c137526eccd4ce21b2de477ab0676d2",
|
||||||
"reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c",
|
"reference": "30e286560c137526eccd4ce21b2de477ab0676d2",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1637,7 +1637,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/guzzle/uri-template/issues",
|
"issues": "https://github.com/guzzle/uri-template/issues",
|
||||||
"source": "https://github.com/guzzle/uri-template/tree/v1.0.3"
|
"source": "https://github.com/guzzle/uri-template/tree/v1.0.4"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1653,7 +1653,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2023-12-03T19:50:20+00:00"
|
"time": "2025-02-03T10:55:03+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "jc5/google2fa-laravel",
|
"name": "jc5/google2fa-laravel",
|
||||||
|
@@ -81,7 +81,7 @@ return [
|
|||||||
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
||||||
// see cer.php for exchange rates feature flag.
|
// see cer.php for exchange rates feature flag.
|
||||||
],
|
],
|
||||||
'version' => '6.2.1',
|
'version' => '6.2.3',
|
||||||
'api_version' => '2.1.0', // field is no longer used.
|
'api_version' => '2.1.0', // field is no longer used.
|
||||||
'db_version' => 25,
|
'db_version' => 25,
|
||||||
|
|
||||||
|
@@ -50,33 +50,60 @@ return new class () extends Migration {
|
|||||||
});
|
});
|
||||||
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
||||||
// 3. add currency
|
// 3. add currency
|
||||||
|
if (!Schema::hasColumn('piggy_banks', 'transaction_currency_id')) {
|
||||||
$table->integer('transaction_currency_id', false, true)->after('account_id')->nullable();
|
$table->integer('transaction_currency_id', false, true)->after('account_id')->nullable();
|
||||||
|
}
|
||||||
|
if (!self::hasForeign('piggy_banks', 'unique_currency')) {
|
||||||
$table->foreign('transaction_currency_id', 'unique_currency')->references('id')->on('transaction_currencies')->onDelete('cascade');
|
$table->foreign('transaction_currency_id', 'unique_currency')->references('id')->on('transaction_currencies')->onDelete('cascade');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
||||||
// 4. rename columns
|
// 4. rename columns
|
||||||
|
if (Schema::hasColumn('piggy_banks', 'targetamount') && !Schema::hasColumn('piggy_banks', 'target_amount')) {
|
||||||
$table->renameColumn('targetamount', 'target_amount');
|
$table->renameColumn('targetamount', 'target_amount');
|
||||||
|
}
|
||||||
|
if (Schema::hasColumn('piggy_banks', 'startdate') && !Schema::hasColumn('piggy_banks', 'start_date')) {
|
||||||
$table->renameColumn('startdate', 'start_date');
|
$table->renameColumn('startdate', 'start_date');
|
||||||
|
}
|
||||||
|
if (Schema::hasColumn('piggy_banks', 'targetdate') && !Schema::hasColumn('piggy_banks', 'target_date')) {
|
||||||
$table->renameColumn('targetdate', 'target_date');
|
$table->renameColumn('targetdate', 'target_date');
|
||||||
|
}
|
||||||
|
if (Schema::hasColumn('piggy_banks', 'targetdate') && !Schema::hasColumn('startdate_tz', 'start_date_tz')) {
|
||||||
$table->renameColumn('startdate_tz', 'start_date_tz');
|
$table->renameColumn('startdate_tz', 'start_date_tz');
|
||||||
|
}
|
||||||
|
if (Schema::hasColumn('piggy_banks', 'targetdate_tz') && !Schema::hasColumn('target_date_tz', 'start_date_tz')) {
|
||||||
$table->renameColumn('targetdate_tz', 'target_date_tz');
|
$table->renameColumn('targetdate_tz', 'target_date_tz');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
Schema::table('piggy_banks', static function (Blueprint $table): void {
|
||||||
// 5. add new index
|
// 5. add new index
|
||||||
|
if (!self::hasForeign('piggy_banks', 'piggy_banks_account_id_foreign')) {
|
||||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('set null');
|
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('set null');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// rename some fields in piggy bank reps.
|
// rename some fields in piggy bank reps.
|
||||||
Schema::table('piggy_bank_repetitions', static function (Blueprint $table): void {
|
Schema::table('piggy_bank_repetitions', static function (Blueprint $table): void {
|
||||||
// 6. rename columns
|
// 6. rename columns
|
||||||
|
if (Schema::hasColumn('piggy_bank_repetitions', 'currentamount') && !Schema::hasColumn('piggy_bank_repetitions', 'current_amount')) {
|
||||||
$table->renameColumn('currentamount', 'current_amount');
|
$table->renameColumn('currentamount', 'current_amount');
|
||||||
|
}
|
||||||
|
if (Schema::hasColumn('piggy_bank_repetitions', 'startdate') && !Schema::hasColumn('piggy_bank_repetitions', 'start_date')) {
|
||||||
$table->renameColumn('startdate', 'start_date');
|
$table->renameColumn('startdate', 'start_date');
|
||||||
|
}
|
||||||
|
if (Schema::hasColumn('piggy_bank_repetitions', 'targetdate') && !Schema::hasColumn('piggy_bank_repetitions', 'target_date')) {
|
||||||
$table->renameColumn('targetdate', 'target_date');
|
$table->renameColumn('targetdate', 'target_date');
|
||||||
|
}
|
||||||
|
if (Schema::hasColumn('piggy_bank_repetitions', 'startdate_tz') && !Schema::hasColumn('piggy_bank_repetitions', 'start_date_tz')) {
|
||||||
$table->renameColumn('startdate_tz', 'start_date_tz');
|
$table->renameColumn('startdate_tz', 'start_date_tz');
|
||||||
|
}
|
||||||
|
if (Schema::hasColumn('piggy_bank_repetitions', 'targetdate_tz') && !Schema::hasColumn('piggy_bank_repetitions', 'target_date_tz')) {
|
||||||
$table->renameColumn('targetdate_tz', 'target_date_tz');
|
$table->renameColumn('targetdate_tz', 'target_date_tz');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// create table account_piggy_bank
|
// create table account_piggy_bank
|
||||||
|
if (!Schema::hasTable('account_piggy_bank')) {
|
||||||
Schema::create('account_piggy_bank', static function (Blueprint $table): void {
|
Schema::create('account_piggy_bank', static function (Blueprint $table): void {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->integer('account_id', false, true);
|
$table->integer('account_id', false, true);
|
||||||
@@ -86,6 +113,7 @@ return new class () extends Migration {
|
|||||||
$table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade');
|
$table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade');
|
||||||
$table->unique(['account_id', 'piggy_bank_id'], 'unique_piggy_save');
|
$table->unique(['account_id', 'piggy_bank_id'], 'unique_piggy_save');
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,8 +41,6 @@ return new class () extends Migration {
|
|||||||
'piggy_banks' => ['native_target_amount'], // works
|
'piggy_banks' => ['native_target_amount'], // works
|
||||||
'transactions' => ['native_amount', 'native_foreign_amount'], // works
|
'transactions' => ['native_amount', 'native_foreign_amount'], // works
|
||||||
|
|
||||||
// TODO button to recalculate all native amounts on selected pages?
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,9 +50,11 @@ return new class () extends Migration {
|
|||||||
{
|
{
|
||||||
foreach ($this->tables as $table => $fields) {
|
foreach ($this->tables as $table => $fields) {
|
||||||
foreach ($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
Schema::table($table, static function (Blueprint $table) use ($field): void {
|
Schema::table($table, static function (Blueprint $tableObject) use ($table, $field): void {
|
||||||
// add amount column
|
// add amount column
|
||||||
$table->decimal($field, 32, 12)->nullable();
|
if (!Schema::hasColumn($table, $field)) {
|
||||||
|
$tableObject->decimal($field, 32, 12)->nullable();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,9 @@ class TransactionCurrencySeeder extends Seeder
|
|||||||
$currencies[] = ['code' => 'PLN', 'name' => 'Polish złoty', 'symbol' => 'zł', 'decimal_places' => 2];
|
$currencies[] = ['code' => 'PLN', 'name' => 'Polish złoty', 'symbol' => 'zł', 'decimal_places' => 2];
|
||||||
$currencies[] = ['code' => 'TRY', 'name' => 'Turkish lira', 'symbol' => '₺', 'decimal_places' => 2];
|
$currencies[] = ['code' => 'TRY', 'name' => 'Turkish lira', 'symbol' => '₺', 'decimal_places' => 2];
|
||||||
$currencies[] = ['code' => 'DKK', 'name' => 'Dansk krone', 'symbol' => 'kr.', 'decimal_places' => 2];
|
$currencies[] = ['code' => 'DKK', 'name' => 'Dansk krone', 'symbol' => 'kr.', 'decimal_places' => 2];
|
||||||
|
$currencies[] = ['code' => 'ISK', 'name' => 'Íslensk króna', 'symbol' => 'kr.', 'decimal_places' => 2];
|
||||||
|
$currencies[] = ['code' => 'NOK', 'name' => 'Norsk krone', 'symbol' => 'kr.', 'decimal_places' => 2];
|
||||||
|
$currencies[] = ['code' => 'SEK', 'name' => 'Svensk krona', 'symbol' => 'kr.', 'decimal_places' => 2];
|
||||||
$currencies[] = ['code' => 'RON', 'name' => 'Romanian leu', 'symbol' => 'lei', 'decimal_places' => 2];
|
$currencies[] = ['code' => 'RON', 'name' => 'Romanian leu', 'symbol' => 'lei', 'decimal_places' => 2];
|
||||||
|
|
||||||
// american currencies
|
// american currencies
|
||||||
|
200
package-lock.json
generated
200
package-lock.json
generated
@@ -2591,9 +2591,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.2.tgz",
|
||||||
"integrity": "sha512-Eeao7ewDq79jVEsrtWIj5RNqB8p2knlm9fhR6uJ2gqP7UfbLrTrxevudVrEPDM7Wkpn/HpRC2QfazH7MXLz3vQ==",
|
"integrity": "sha512-6Fyg9yQbwJR+ykVdT9sid1oc2ewejS6h4wzQltmJfSW53N60G/ah9pngXGANdy9/aaE/TcUFpWosdm7JXS1WTQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -2605,9 +2605,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm64": {
|
"node_modules/@rollup/rollup-android-arm64": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.2.tgz",
|
||||||
"integrity": "sha512-yVh0Kf1f0Fq4tWNf6mWcbQBCLDpDrDEl88lzPgKhrgTcDrTtlmun92ywEF9dCjmYO3EFiSuJeeo9cYRxl2FswA==",
|
"integrity": "sha512-K5GfWe+vtQ3kyEbihrimM38UgX57UqHp+oME7X/EX9Im6suwZfa7Hsr8AtzbJvukTpwMGs+4s29YMSO3rwWtsw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -2619,9 +2619,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.2.tgz",
|
||||||
"integrity": "sha512-gCs0ErAZ9s0Osejpc3qahTsqIPUDjSKIyxK/0BGKvL+Tn0n3Kwvj8BrCv7Y5sR1Ypz1K2qz9Ny0VvkVyoXBVUQ==",
|
"integrity": "sha512-PSN58XG/V/tzqDb9kDGutUruycgylMlUE59f40ny6QIRNsTEIZsrNQTJKUN2keMMSmlzgunMFqyaGLmly39sug==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -2633,9 +2633,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-x64": {
|
"node_modules/@rollup/rollup-darwin-x64": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.2.tgz",
|
||||||
"integrity": "sha512-aIB5Anc8hngk15t3GUkiO4pv42ykXHfmpXGS+CzM9CTyiWyT8HIS5ygRAy7KcFb/wiw4Br+vh1byqcHRTfq2tQ==",
|
"integrity": "sha512-gQhK788rQJm9pzmXyfBB84VHViDERhAhzGafw+E5mUpnGKuxZGkMVDa3wgDFKT6ukLC5V7QTifzsUKdNVxp5qQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -2647,9 +2647,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.2.tgz",
|
||||||
"integrity": "sha512-kpdsUdMlVJMRMaOf/tIvxk8TQdzHhY47imwmASOuMajg/GXpw8GKNd8LNwIHE5Yd1onehNpcUB9jHY6wgw9nHQ==",
|
"integrity": "sha512-eiaHgQwGPpxLC3+zTAcdKl4VsBl3r0AiJOd1Um/ArEzAjN/dbPK1nROHrVkdnoE6p7Svvn04w3f/jEZSTVHunA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -2661,9 +2661,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.2.tgz",
|
||||||
"integrity": "sha512-D0RDyHygOBCQiqookcPevrvgEarN0CttBecG4chOeIYCNtlKHmf5oi5kAVpXV7qs0Xh/WO2RnxeicZPtT50V0g==",
|
"integrity": "sha512-lhdiwQ+jf8pewYOTG4bag0Qd68Jn1v2gO1i0mTuiD+Qkt5vNfHVK/jrT7uVvycV8ZchlzXp5HDVmhpzjC6mh0g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -2675,9 +2675,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.2.tgz",
|
||||||
"integrity": "sha512-mCIw8j5LPDXmCOW8mfMZwT6F/Kza03EnSr4wGYEswrEfjTfVsFOxvgYfuRMxTuUF/XmRb9WSMD5GhCWDe2iNrg==",
|
"integrity": "sha512-lfqTpWjSvbgQP1vqGTXdv+/kxIznKXZlI109WkIFPbud41bjigjNmOAAKoazmRGx+k9e3rtIdbq2pQZPV1pMig==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -2689,9 +2689,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.2.tgz",
|
||||||
"integrity": "sha512-AwwldAu4aCJPob7zmjuDUMvvuatgs8B/QiVB0KwkUarAcPB3W+ToOT+18TQwY4z09Al7G0BvCcmLRop5zBLTag==",
|
"integrity": "sha512-RGjqULqIurqqv+NJTyuPgdZhka8ImMLB32YwUle2BPTDqDoXNgwFjdjQC59FbSk08z0IqlRJjrJ0AvDQ5W5lpw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -2703,9 +2703,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.2.tgz",
|
||||||
"integrity": "sha512-e7kDUGVP+xw05pV65ZKb0zulRploU3gTu6qH1qL58PrULDGxULIS0OSDQJLH7WiFnpd3ZKUU4VM3u/Z7Zw+e7Q==",
|
"integrity": "sha512-ZvkPiheyXtXlFqHpsdgscx+tZ7hoR59vOettvArinEspq5fxSDSgfF+L5wqqJ9R4t+n53nyn0sKxeXlik7AY9Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -2717,9 +2717,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.2.tgz",
|
||||||
"integrity": "sha512-SXYJw3zpwHgaBqTXeAZ31qfW/v50wq4HhNVvKFhRr5MnptRX2Af4KebLWR1wpxGJtLgfS2hEPuALRIY3LPAAcA==",
|
"integrity": "sha512-UlFk+E46TZEoxD9ufLKDBzfSG7Ki03fo6hsNRRRHF+KuvNZ5vd1RRVQm8YZlGsjcJG8R252XFK0xNPay+4WV7w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -2731,9 +2731,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.2.tgz",
|
||||||
"integrity": "sha512-e5XiCinINCI4RdyU3sFyBH4zzz7LiQRvHqDtRe9Dt8o/8hTBaYpdPimayF00eY2qy5j4PaaWK0azRgUench6WQ==",
|
"integrity": "sha512-hJhfsD9ykx59jZuuoQgYT1GEcNNi3RCoEmbo5OGfG8RlHOiVS7iVNev9rhLKh7UBYq409f4uEw0cclTXx8nh8Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
@@ -2745,9 +2745,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.2.tgz",
|
||||||
"integrity": "sha512-3SWN3e0bAsm9ToprLFBSro8nJe6YN+5xmB11N4FfNf92wvLye/+Rh5JGQtKOpwLKt6e61R1RBc9g+luLJsc23A==",
|
"integrity": "sha512-g/O5IpgtrQqPegvqopvmdCF9vneLE7eqYfdPWW8yjPS8f63DNam3U4ARL1PNNB64XHZDHKpvO2Giftf43puB8Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@@ -2759,9 +2759,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.2.tgz",
|
||||||
"integrity": "sha512-B1Oqt3GLh7qmhvfnc2WQla4NuHlcxAD5LyueUi5WtMc76ZWY+6qDtQYqnxARx9r+7mDGfamD+8kTJO0pKUJeJA==",
|
"integrity": "sha512-bSQijDC96M6PuooOuXHpvXUYiIwsnDmqGU8+br2U7iPoykNi9JtMUpN7K6xml29e0evK0/g0D1qbAUzWZFHY5Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -2773,9 +2773,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.2.tgz",
|
||||||
"integrity": "sha512-UfUCo0h/uj48Jq2lnhX0AOhZPSTAq3Eostas+XZ+GGk22pI+Op1Y6cxQ1JkUuKYu2iU+mXj1QjPrZm9nNWV9rg==",
|
"integrity": "sha512-49TtdeVAsdRuiUHXPrFVucaP4SivazetGUVH8CIxVsNsaPHV4PFkpLmH9LeqU/R4Nbgky9lzX5Xe1NrzLyraVA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@@ -2787,9 +2787,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.2.tgz",
|
||||||
"integrity": "sha512-chZLTUIPbgcpm+Z7ALmomXW8Zh+wE2icrG+K6nt/HenPLmtwCajhQC5flNSk1Xy5EDMt/QAOz2MhzfOfJOLSiA==",
|
"integrity": "sha512-j+jFdfOycLIQ7FWKka9Zd3qvsIyugg5LeZuHF6kFlXo6MSOc6R1w37YUVy8VpAKd81LMWGi5g9J25P09M0SSIw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -2801,9 +2801,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.2.tgz",
|
||||||
"integrity": "sha512-jo0UolK70O28BifvEsFD/8r25shFezl0aUk2t0VJzREWHkq19e+pcLu4kX5HiVXNz5qqkD+aAq04Ct8rkxgbyQ==",
|
"integrity": "sha512-aDPHyM/D2SpXfSNCVWCxyHmOqN9qb7SWkY1+vaXqMNMXslZYnwh9V/UCudl6psyG0v6Ukj7pXanIpfZwCOEMUg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -2815,9 +2815,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.2.tgz",
|
||||||
"integrity": "sha512-Vmg0NhAap2S54JojJchiu5An54qa6t/oKT7LmDaWggpIcaiL8WcWHEN6OQrfTdL6mQ2GFyH7j2T5/3YPEDOOGA==",
|
"integrity": "sha512-LQRkCyUBnAo7r8dbEdtNU08EKLCJMgAk2oP5H3R7BnUlKLqgR3dUjrLBVirmc1RK6U6qhtDw29Dimeer8d5hzQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -2829,9 +2829,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.2.tgz",
|
||||||
"integrity": "sha512-CV2aqhDDOsABKHKhNcs1SZFryffQf8vK2XrxP6lxC99ELZAdvsDgPklIBfd65R8R+qvOm1SmLaZ/Fdq961+m7A==",
|
"integrity": "sha512-wt8OhpQUi6JuPFkm1wbVi1BByeag87LDFzeKSXzIdGcX4bMLqORTtKxLoCbV57BHYNSUSOKlSL4BYYUghainYA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@@ -2843,9 +2843,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.2.tgz",
|
||||||
"integrity": "sha512-g2ASy1QwHP88y5KWvblUolJz9rN+i4ZOsYzkEwcNfaNooxNUXG+ON6F5xFo0NIItpHqxcdAyls05VXpBnludGw==",
|
"integrity": "sha512-rUrqINax0TvrPBXrFKg0YbQx18NpPN3NNrgmaao9xRNbTwek7lOXObhx8tQy8gelmQ/gLaGy1WptpU2eKJZImg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -3133,9 +3133,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.13.0",
|
"version": "22.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
|
||||||
"integrity": "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==",
|
"integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -4448,9 +4448,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001696",
|
"version": "1.0.30001697",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001697.tgz",
|
||||||
"integrity": "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==",
|
"integrity": "sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -5663,9 +5663,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.90",
|
"version": "1.5.92",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.90.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.92.tgz",
|
||||||
"integrity": "sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug==",
|
"integrity": "sha512-BeHgmNobs05N1HMmMZ7YIuHfYBGlq/UmvlsTgg+fsbFs9xVMj+xJHFg19GN04+9Q+r8Xnh9LXqaYIyEWElnNgQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@@ -5720,9 +5720,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/enhanced-resolve": {
|
"node_modules/enhanced-resolve": {
|
||||||
"version": "5.18.0",
|
"version": "5.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
|
||||||
"integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==",
|
"integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -7159,9 +7159,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
||||||
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -8387,9 +8387,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.13.3",
|
"version": "1.13.4",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||||
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
|
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -9987,9 +9987,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.34.0",
|
"version": "4.34.2",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.2.tgz",
|
||||||
"integrity": "sha512-+4C/cgJ9w6sudisA0nZz0+O7lTP9a3CzNLsoDwaRumM8QHwghUsu6tqHXiTmNUp/rqNiM14++7dkzHDyCRs0Jg==",
|
"integrity": "sha512-sBDUoxZEaqLu9QeNalL8v3jw6WjPku4wfZGyTU7l7m1oC+rpRihXc/n/H+4148ZkGz5Xli8CHMns//fFGKvpIQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -10003,25 +10003,25 @@
|
|||||||
"npm": ">=8.0.0"
|
"npm": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rollup/rollup-android-arm-eabi": "4.34.0",
|
"@rollup/rollup-android-arm-eabi": "4.34.2",
|
||||||
"@rollup/rollup-android-arm64": "4.34.0",
|
"@rollup/rollup-android-arm64": "4.34.2",
|
||||||
"@rollup/rollup-darwin-arm64": "4.34.0",
|
"@rollup/rollup-darwin-arm64": "4.34.2",
|
||||||
"@rollup/rollup-darwin-x64": "4.34.0",
|
"@rollup/rollup-darwin-x64": "4.34.2",
|
||||||
"@rollup/rollup-freebsd-arm64": "4.34.0",
|
"@rollup/rollup-freebsd-arm64": "4.34.2",
|
||||||
"@rollup/rollup-freebsd-x64": "4.34.0",
|
"@rollup/rollup-freebsd-x64": "4.34.2",
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": "4.34.0",
|
"@rollup/rollup-linux-arm-gnueabihf": "4.34.2",
|
||||||
"@rollup/rollup-linux-arm-musleabihf": "4.34.0",
|
"@rollup/rollup-linux-arm-musleabihf": "4.34.2",
|
||||||
"@rollup/rollup-linux-arm64-gnu": "4.34.0",
|
"@rollup/rollup-linux-arm64-gnu": "4.34.2",
|
||||||
"@rollup/rollup-linux-arm64-musl": "4.34.0",
|
"@rollup/rollup-linux-arm64-musl": "4.34.2",
|
||||||
"@rollup/rollup-linux-loongarch64-gnu": "4.34.0",
|
"@rollup/rollup-linux-loongarch64-gnu": "4.34.2",
|
||||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.34.0",
|
"@rollup/rollup-linux-powerpc64le-gnu": "4.34.2",
|
||||||
"@rollup/rollup-linux-riscv64-gnu": "4.34.0",
|
"@rollup/rollup-linux-riscv64-gnu": "4.34.2",
|
||||||
"@rollup/rollup-linux-s390x-gnu": "4.34.0",
|
"@rollup/rollup-linux-s390x-gnu": "4.34.2",
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.34.0",
|
"@rollup/rollup-linux-x64-gnu": "4.34.2",
|
||||||
"@rollup/rollup-linux-x64-musl": "4.34.0",
|
"@rollup/rollup-linux-x64-musl": "4.34.2",
|
||||||
"@rollup/rollup-win32-arm64-msvc": "4.34.0",
|
"@rollup/rollup-win32-arm64-msvc": "4.34.2",
|
||||||
"@rollup/rollup-win32-ia32-msvc": "4.34.0",
|
"@rollup/rollup-win32-ia32-msvc": "4.34.2",
|
||||||
"@rollup/rollup-win32-x64-msvc": "4.34.0",
|
"@rollup/rollup-win32-x64-msvc": "4.34.2",
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -10168,9 +10168,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.7.0",
|
"version": "7.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||||
"integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==",
|
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@@ -57,6 +57,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currencies: [],
|
currencies: [],
|
||||||
|
page: 1,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -65,6 +66,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
getCurrencies: function () {
|
getCurrencies: function () {
|
||||||
this.currencies = [];
|
this.currencies = [];
|
||||||
|
// start with page one, loop for the rest.
|
||||||
this.downloadCurrencies(1);
|
this.downloadCurrencies(1);
|
||||||
},
|
},
|
||||||
downloadCurrencies: function (page) {
|
downloadCurrencies: function (page) {
|
||||||
|
@@ -42,6 +42,27 @@
|
|||||||
<h3 class="box-title">{{ $t('firefly.header_exchange_rates_table') }}</h3>
|
<h3 class="box-title">{{ $t('firefly.header_exchange_rates_table') }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body no-padding">
|
<div class="box-body no-padding">
|
||||||
|
<nav v-if="totalPages > 1">
|
||||||
|
<ul class="pagination">
|
||||||
|
<li v-if="1 === this.page" class="page-item disabled" aria-disabled="true" :aria-label="$t('pagination.previous')">
|
||||||
|
<span class="page-link" aria-hidden="true">‹</span>
|
||||||
|
</li>
|
||||||
|
<li class="page-item" v-if="1 !== this.page">
|
||||||
|
<a class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page-1)" rel="prev" :aria-label="$t('pagination.next')">‹</a>
|
||||||
|
</li>
|
||||||
|
<li v-for="item in this.totalPages" :class="item === page ? 'page-item active' : 'page-item'" aria-current="page">
|
||||||
|
<span v-if="item === page" class="page-link" v-text="item"></span>
|
||||||
|
<a v-if="item !== page" class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + item" v-text="item"></a>
|
||||||
|
</li>
|
||||||
|
<li v-if="totalPages !== page" class="page-item">
|
||||||
|
<a class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page+1)" rel="next" :aria-label="$t('pagination.next')">›</a>
|
||||||
|
</li>
|
||||||
|
<li v-if="totalPages === page" class="page-item disabled" aria-disabled="true" :aria-label="$t('pagination.next')">
|
||||||
|
<span class="page-link" aria-hidden="true">›</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
<table class="table table-responsive table-hover">
|
<table class="table table-responsive table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -76,10 +97,10 @@
|
|||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" class="form-control" min="0" v-model="rate.rate">
|
<input type="number" class="form-control" min="0" step="any" v-model="rate.rate">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" class="form-control" min="0" v-model="rate.inverse">
|
<input type="number" class="form-control" min="0" step="any" v-model="rate.inverse">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
@@ -98,6 +119,28 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<nav v-if="totalPages > 1">
|
||||||
|
<ul class="pagination">
|
||||||
|
<li v-if="1 === this.page" class="page-item disabled" aria-disabled="true" :aria-label="$t('pagination.previous')">
|
||||||
|
<span class="page-link" aria-hidden="true">‹</span>
|
||||||
|
</li>
|
||||||
|
<li class="page-item" v-if="1 !== this.page">
|
||||||
|
<a class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page-1)" rel="prev" :aria-label="$t('pagination.next')">‹</a>
|
||||||
|
</li>
|
||||||
|
<li v-for="item in this.totalPages" :class="item === page ? 'page-item active' : 'page-item'" aria-current="page">
|
||||||
|
<span v-if="item === page" class="page-link" v-text="item"></span>
|
||||||
|
<a v-if="item !== page" class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + item" v-text="item"></a>
|
||||||
|
</li>
|
||||||
|
<li v-if="totalPages !== page" class="page-item">
|
||||||
|
<a class="page-link" :href="'/exchange-rates/'+from_code+'/'+to_code+'?page=' + (this.page+1)" rel="next" :aria-label="$t('pagination.next')">›</a>
|
||||||
|
</li>
|
||||||
|
<li v-if="totalPages === page" class="page-item disabled" aria-disabled="true" :aria-label="$t('pagination.next')">
|
||||||
|
<span class="page-link" aria-hidden="true">›</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -167,6 +210,8 @@ export default {
|
|||||||
loading: true,
|
loading: true,
|
||||||
posting: false,
|
posting: false,
|
||||||
updating: false,
|
updating: false,
|
||||||
|
page: 1,
|
||||||
|
totalPages: 1,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -175,8 +220,16 @@ export default {
|
|||||||
let parts = window.location.href.split('/');
|
let parts = window.location.href.split('/');
|
||||||
this.from_code = parts[parts.length - 2].substring(0, 3);
|
this.from_code = parts[parts.length - 2].substring(0, 3);
|
||||||
this.to_code = parts[parts.length - 1].substring(0, 3);
|
this.to_code = parts[parts.length - 1].substring(0, 3);
|
||||||
|
|
||||||
|
const params = new Proxy(new URLSearchParams(window.location.search), {
|
||||||
|
get: (searchParams, prop) => searchParams.get(prop),
|
||||||
|
});
|
||||||
|
this.page = parseInt(params.page ?? 1);
|
||||||
|
|
||||||
|
|
||||||
this.downloadCurrencies();
|
this.downloadCurrencies();
|
||||||
this.downloadRates(1);
|
this.rates = [];
|
||||||
|
this.downloadRates(this.page);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
submitRate: function(e) {
|
submitRate: function(e) {
|
||||||
@@ -203,16 +256,11 @@ export default {
|
|||||||
return ('' === this.rates[index].rate && '' === this.rates[index].inverse) || this.updating;
|
return ('' === this.rates[index].rate && '' === this.rates[index].inverse) || this.updating;
|
||||||
},
|
},
|
||||||
updateRate: function (index) {
|
updateRate: function (index) {
|
||||||
// console.log('Update!');
|
|
||||||
// console.log(this.rates[index].key);
|
|
||||||
let parts = this.spliceKey(this.rates[index].key);
|
let parts = this.spliceKey(this.rates[index].key);
|
||||||
if (0 === parts.length) {
|
if (0 === parts.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ('' !== this.rates[index].rate) {
|
if ('' !== this.rates[index].rate) {
|
||||||
// update rate
|
|
||||||
// console.log('Rate is ' + this.rates[index].rate);
|
|
||||||
// console.log('ID is ' + this.rates[index].rate_id);
|
|
||||||
this.updating = true;
|
this.updating = true;
|
||||||
axios.put("./api/v1/exchange-rates/" + this.rates[index].rate_id, {rate: this.rates[index].rate})
|
axios.put("./api/v1/exchange-rates/" + this.rates[index].rate_id, {rate: this.rates[index].rate})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -220,9 +268,6 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if ('' !== this.rates[index].inverse) {
|
if ('' !== this.rates[index].inverse) {
|
||||||
// update inverse
|
|
||||||
// console.log('Inverse is ' + this.rates[index].inverse);
|
|
||||||
// console.log('Inverse ID is ' + this.rates[index].inverse_id);
|
|
||||||
this.updating = true;
|
this.updating = true;
|
||||||
axios.put("./api/v1/exchange-rates/" + this.rates[index].inverse_id, {rate: this.rates[index].inverse})
|
axios.put("./api/v1/exchange-rates/" + this.rates[index].inverse_id, {rate: this.rates[index].inverse})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -281,7 +326,6 @@ export default {
|
|||||||
},
|
},
|
||||||
downloadRates: function (page) {
|
downloadRates: function (page) {
|
||||||
this.tempRates = {};
|
this.tempRates = {};
|
||||||
this.rates = [];
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
axios.get("./api/v1/exchange-rates/rates/" + this.from_code + '/' + this.to_code + '?page=' + page).then((response) => {
|
axios.get("./api/v1/exchange-rates/rates/" + this.from_code + '/' + this.to_code + '?page=' + page).then((response) => {
|
||||||
for (let i in response.data.data) {
|
for (let i in response.data.data) {
|
||||||
@@ -334,13 +378,10 @@ export default {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parseInt(response.data.meta.pagination.current_page) < parseInt(response.data.meta.pagination.total_pages)) {
|
this.totalPages = parseInt(response.data.meta.pagination.total_pages);
|
||||||
this.downloadRates(page + 1);
|
|
||||||
}
|
|
||||||
if (parseInt(response.data.meta.pagination.current_page) === parseInt(response.data.meta.pagination.total_pages)) {
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.rates = Object.values(this.tempRates);
|
this.rates = Object.values(this.tempRates);
|
||||||
}
|
console.log('Do not download more pages. Now on page ' + this.page + ' of ' + this.totalPages);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -138,7 +138,7 @@
|
|||||||
"visit_webhook_url": "Webhook-URL besuchen",
|
"visit_webhook_url": "Webhook-URL besuchen",
|
||||||
"reset_webhook_secret": "Webhook Secret zur\u00fccksetzen",
|
"reset_webhook_secret": "Webhook Secret zur\u00fccksetzen",
|
||||||
"header_exchange_rates": "Wechselkurse",
|
"header_exchange_rates": "Wechselkurse",
|
||||||
"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_intro": "Firefly III unterst\u00fctzt das Herunterladen und Verwenden von Wechselkursen. Lesen Sie mehr dar\u00fcber in <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\"> der Dokumentation<\/a>.",
|
||||||
"exchange_rates_from_to": "Zwischen {from} und {to} (und umgekehrt)",
|
"exchange_rates_from_to": "Zwischen {from} und {to} (und umgekehrt)",
|
||||||
"exchange_rates_intro_rates": "Firefly III verwendet die folgenden Wechselkurse. Der Kehrwert wird automatisch berechnet, wenn er nicht angegeben wurde. Wenn f\u00fcr das Datum der Transaktion kein Wechselkurs vorhanden ist, sucht Firefly III in der Vergangenheit nach einem Kurs. Wenn keine vorhanden sind, wird der Kurs \u201e1\u201c verwendet.",
|
"exchange_rates_intro_rates": "Firefly III verwendet die folgenden Wechselkurse. Der Kehrwert wird automatisch berechnet, wenn er nicht angegeben wurde. Wenn f\u00fcr das Datum der Transaktion kein Wechselkurs vorhanden ist, sucht Firefly III in der Vergangenheit nach einem Kurs. Wenn keine vorhanden sind, wird der Kurs \u201e1\u201c verwendet.",
|
||||||
"header_exchange_rates_rates": "Wechselkurse",
|
"header_exchange_rates_rates": "Wechselkurse",
|
||||||
|
@@ -138,7 +138,7 @@
|
|||||||
"visit_webhook_url": "Visiter l'URL du webhook",
|
"visit_webhook_url": "Visiter l'URL du webhook",
|
||||||
"reset_webhook_secret": "R\u00e9initialiser le secret du webhook",
|
"reset_webhook_secret": "R\u00e9initialiser le secret du webhook",
|
||||||
"header_exchange_rates": "Taux de change",
|
"header_exchange_rates": "Taux de change",
|
||||||
"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_intro": "Firefly III prend en charge le chargement et l'utilisation des taux de change. En savoir plus \u00e0 ce sujet dans <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">la documentation<\/a>.",
|
||||||
"exchange_rates_from_to": "Entre {from} et {to} (et l'inverse)",
|
"exchange_rates_from_to": "Entre {from} et {to} (et l'inverse)",
|
||||||
"exchange_rates_intro_rates": "Firefly III utilise les taux de change suivants. L'inverse est calcul\u00e9 automatiquement lorsqu'il n'est pas fourni. Si aucun taux de change n'existe pour la date de la transaction, Firefly III reviendra dans le temps pour en trouver un. Si aucun n'est pr\u00e9sent, le taux \"1\" sera utilis\u00e9.",
|
"exchange_rates_intro_rates": "Firefly III utilise les taux de change suivants. L'inverse est calcul\u00e9 automatiquement lorsqu'il n'est pas fourni. Si aucun taux de change n'existe pour la date de la transaction, Firefly III reviendra dans le temps pour en trouver un. Si aucun n'est pr\u00e9sent, le taux \"1\" sera utilis\u00e9.",
|
||||||
"header_exchange_rates_rates": "Taux de change",
|
"header_exchange_rates_rates": "Taux de change",
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
"apply_rules_checkbox": "Zastosuj regu\u0142y",
|
"apply_rules_checkbox": "Zastosuj regu\u0142y",
|
||||||
"fire_webhooks_checkbox": "Uruchom webhooki",
|
"fire_webhooks_checkbox": "Uruchom webhooki",
|
||||||
"no_budget_pointer": "Wygl\u0105da na to, \u017ce nie masz jeszcze bud\u017cet\u00f3w. Powiniene\u015b utworzy\u0107 kilka na stronie <a href=\"budgets\">bud\u017cet\u00f3w<\/a>. Bud\u017cety mog\u0105 Ci pom\u00f3c \u015bledzi\u0107 wydatki.",
|
"no_budget_pointer": "Wygl\u0105da na to, \u017ce nie masz jeszcze bud\u017cet\u00f3w. Powiniene\u015b utworzy\u0107 kilka na stronie <a href=\"budgets\">bud\u017cet\u00f3w<\/a>. Bud\u017cety mog\u0105 Ci pom\u00f3c \u015bledzi\u0107 wydatki.",
|
||||||
"no_bill_pointer": "You seem to have no subscription yet. You should create some on the <a href=\"subscriptions\">subscription<\/a>-page. Subscriptions can help you keep track of expenses.",
|
"no_bill_pointer": "Wygl\u0105da na to, \u017ce nie masz jeszcze subskrypcji. Powiniene\u015b utworzy\u0107 j\u0105 na stronie <a href=\"subscriptions\">subskrypcji<\/a>. Subskrypcje mog\u0105 pom\u00f3c Ci \u015bledzi\u0107 wydatki.",
|
||||||
"source_account": "Konto \u017ar\u00f3d\u0142owe",
|
"source_account": "Konto \u017ar\u00f3d\u0142owe",
|
||||||
"hidden_fields_preferences": "Mo\u017cesz w\u0142\u0105czy\u0107 wi\u0119cej opcji transakcji w swoich <a href=\"preferences\">ustawieniach<\/a>.",
|
"hidden_fields_preferences": "Mo\u017cesz w\u0142\u0105czy\u0107 wi\u0119cej opcji transakcji w swoich <a href=\"preferences\">ustawieniach<\/a>.",
|
||||||
"destination_account": "Konto docelowe",
|
"destination_account": "Konto docelowe",
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
"url": "URL",
|
"url": "URL",
|
||||||
"active": "Aktywny",
|
"active": "Aktywny",
|
||||||
"interest_date": "Data odsetek",
|
"interest_date": "Data odsetek",
|
||||||
"administration_currency": "Native currency",
|
"administration_currency": "Waluta natywna",
|
||||||
"title": "Tytu\u0142",
|
"title": "Tytu\u0142",
|
||||||
"date": "Data",
|
"date": "Data",
|
||||||
"book_date": "Data ksi\u0119gowania",
|
"book_date": "Data ksi\u0119gowania",
|
||||||
@@ -166,12 +166,12 @@
|
|||||||
"webhook_delivery": "Dor\u0119czenie",
|
"webhook_delivery": "Dor\u0119czenie",
|
||||||
"from_currency_to_currency": "{from} → {to}",
|
"from_currency_to_currency": "{from} → {to}",
|
||||||
"to_currency_from_currency": "{to} → {from}",
|
"to_currency_from_currency": "{to} → {from}",
|
||||||
"rate": "Rate"
|
"rate": "Kurs"
|
||||||
},
|
},
|
||||||
"list": {
|
"list": {
|
||||||
"title": "Tytu\u0142",
|
"title": "Tytu\u0142",
|
||||||
"active": "Jest aktywny?",
|
"active": "Jest aktywny?",
|
||||||
"native_currency": "Native currency",
|
"native_currency": "Waluta natywna",
|
||||||
"trigger": "Wyzwalacz",
|
"trigger": "Wyzwalacz",
|
||||||
"response": "Odpowied\u017a",
|
"response": "Odpowied\u017a",
|
||||||
"delivery": "Dor\u0119czenie",
|
"delivery": "Dor\u0119czenie",
|
||||||
|
@@ -138,7 +138,7 @@
|
|||||||
"visit_webhook_url": "Obi\u0161\u010dite URL webhooka",
|
"visit_webhook_url": "Obi\u0161\u010dite URL webhooka",
|
||||||
"reset_webhook_secret": "Ponastavi skrivno kodo webhooka",
|
"reset_webhook_secret": "Ponastavi skrivno kodo webhooka",
|
||||||
"header_exchange_rates": "Menjalni te\u010daji",
|
"header_exchange_rates": "Menjalni te\u010daji",
|
||||||
"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_intro": "Firefly III podpira prenos in uporabo menjalnih te\u010dajev. Preberite ve\u010d o tem v <a href=\"https:\/\/docs.firefly-iii.org\/explanation\/financial-concepts\/exchange-rates\/\">dokumentaciji<\/a>.",
|
||||||
"exchange_rates_from_to": "Med {from} in {to} (in obratno)",
|
"exchange_rates_from_to": "Med {from} in {to} (in obratno)",
|
||||||
"exchange_rates_intro_rates": "Firefly III uporablja naslednje menjalne te\u010daje. Obratna vrednost se samodejno izra\u010duna, \u010de ni na voljo. \u010ce na dan transakcije ni menjalnega te\u010daja, se bo Firefly III vrnil v preteklost, da bi ga na\u0161el. \u010ce jih ni, se uporabi te\u010daj \"1\".",
|
"exchange_rates_intro_rates": "Firefly III uporablja naslednje menjalne te\u010daje. Obratna vrednost se samodejno izra\u010duna, \u010de ni na voljo. \u010ce na dan transakcije ni menjalnega te\u010daja, se bo Firefly III vrnil v preteklost, da bi ga na\u0161el. \u010ce jih ni, se uporabi te\u010daj \"1\".",
|
||||||
"header_exchange_rates_rates": "Menjalni te\u010daji",
|
"header_exchange_rates_rates": "Menjalni te\u010daji",
|
||||||
|
@@ -733,7 +733,7 @@ return [
|
|||||||
// END
|
// END
|
||||||
'general_search_error' => 'An error occurred while searching. Please check the log files for more information.',
|
'general_search_error' => 'An error occurred while searching. Please check the log files for more information.',
|
||||||
'search_box' => 'Search',
|
'search_box' => 'Search',
|
||||||
'search_box_intro' => 'Welcome to the search function of Firefly III. Enter your search query in the box. Make sure you check out the help file because the search is pretty advanced.',
|
'search_box_intro' => 'Welcome to the search function of Firefly III. Enter your search query in the box. <a href="https://docs.firefly-iii.org/how-to/firefly-iii/features/search/">Make sure you check out the help file</a> because the search is pretty advanced.',
|
||||||
'search_error' => 'Error while searching',
|
'search_error' => 'Error while searching',
|
||||||
'search_searching' => 'Searching ...',
|
'search_searching' => 'Searching ...',
|
||||||
'search_results' => 'Search results',
|
'search_results' => 'Search results',
|
||||||
|
@@ -36,8 +36,8 @@
|
|||||||
<h3 class="box-title">{{ 'optionalFields'|_ }}</h3>
|
<h3 class="box-title">{{ 'optionalFields'|_ }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
{{ ExpandedForm.date('startdate') }}
|
{{ ExpandedForm.date('start_date') }}
|
||||||
{{ ExpandedForm.date('targetdate') }}
|
{{ ExpandedForm.date('target_date') }}
|
||||||
{{ ExpandedForm.textarea('notes', null, {helpText: trans('firefly.field_supports_markdown')}) }}
|
{{ ExpandedForm.textarea('notes', null, {helpText: trans('firefly.field_supports_markdown')}) }}
|
||||||
{{ ExpandedForm.file('attachments[]', {'multiple': 'multiple','helpText': trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }) }}
|
{{ ExpandedForm.file('attachments[]', {'multiple': 'multiple','helpText': trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }) }}
|
||||||
{{ ExpandedForm.objectGroup() }}
|
{{ ExpandedForm.objectGroup() }}
|
||||||
|
@@ -71,8 +71,8 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ 'start_date'|_ }}</td>
|
<td>{{ 'start_date'|_ }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if piggyBank.startdate %}
|
{% if piggyBank.start_date %}
|
||||||
{{ piggyBank.startdate.isoFormat(monthAndDayFormat) }}
|
{{ piggyBank.start_date.isoFormat(monthAndDayFormat) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<em>{{ 'no_start_date'|_ }}</em>
|
<em>{{ 'no_start_date'|_ }}</em>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -81,14 +81,14 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ 'target_date'|_ }}</td>
|
<td>{{ 'target_date'|_ }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if piggyBank.targetdate %}
|
{% if piggyBank.target_date %}
|
||||||
{{ piggyBank.targetdate.isoFormat(monthAndDayFormat) }}
|
{{ piggyBank.target_date.isoFormat(monthAndDayFormat) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<em>{{ 'no_target_date'|_ }}</em>
|
<em>{{ 'no_target_date'|_ }}</em>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if piggyBank.targetdate and piggy.save_per_month %}
|
{% if piggyBank.target_date and piggy.save_per_month %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ 'suggested_amount'|_ }}</td>
|
<td>{{ 'suggested_amount'|_ }}</td>
|
||||||
<td>
|
<td>
|
||||||
|
Reference in New Issue
Block a user