Compare commits

..

23 Commits

Author SHA1 Message Date
github-actions
3bec106840 Auto commit for release 'v6.2.2' on 2025-02-02 2025-02-02 16:20:11 +01:00
James Cole
fb01c36be1 Update changelog and manifest [skip ci] 2025-02-02 16:14:32 +01:00
James Cole
26d851e69e Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-02-02 16:14:09 +01:00
James Cole
28c18c046b Fix #9744 2025-02-02 16:13:56 +01:00
github-actions
318cef7e3b Auto commit for release 'develop' on 2025-02-02 2025-02-02 16:06:22 +01:00
James Cole
e8dc8f25be Update changelog [skip ci] 2025-02-02 16:02:45 +01:00
James Cole
10ccc30240 Fix #9738 2025-02-02 16:02:17 +01:00
James Cole
5adc877d5e Merge pull request #9743 from mansehr/feature-nordic-currencies
Feature nordic currencies
2025-02-02 15:23:05 +01:00
SoftBrix
30923afb2b Added ISK 2025-02-02 14:48:01 +01:00
SoftBrix
4eb6813b43 Added NOK 2025-02-02 14:46:26 +01:00
James Cole
7521a31619 Expand changelog. 2025-02-02 06:48:57 +01:00
James Cole
fc05beb452 Fix #9727 2025-02-02 06:24:10 +01:00
James Cole
1103428a83 Smaller issue replies. 2025-02-02 05:41:54 +01:00
James Cole
d06d521bf0 Merge branch 'main' into develop 2025-02-02 05:39:41 +01:00
James Cole
8f64f1c0eb Expand explanation. 2025-02-02 05:39:33 +01:00
James Cole
d11c232171 Fix https://github.com/firefly-iii/firefly-iii/issues/9736 2025-02-02 05:38:47 +01:00
SoftBrix
93c73248de Added SEK 2025-02-02 00:03:31 +01:00
James Cole
5bed081ab9 Fix https://github.com/firefly-iii/firefly-iii/issues/9731 2025-02-01 21:14:28 +01:00
James Cole
c5188c503e Fix https://github.com/firefly-iii/firefly-iii/issues/9713 2025-02-01 21:06:06 +01:00
James Cole
98ffcac7b6 Fix https://github.com/firefly-iii/firefly-iii/issues/9729 2025-02-01 20:58:35 +01:00
James Cole
df1e81d611 Fix https://github.com/firefly-iii/firefly-iii/issues/9730 2025-02-01 20:52:41 +01:00
James Cole
9711170b08 Fix https://github.com/firefly-iii/firefly-iii/issues/9732 2025-02-01 20:43:20 +01:00
github-actions
e43264bdce Auto commit for release 'develop' on 2025-02-01 2025-02-01 19:12:18 +01:00
31 changed files with 185 additions and 71 deletions

View File

@@ -9,9 +9,9 @@ fixed:
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.
feature:
@@ -23,7 +23,7 @@ feature:
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.
@@ -54,7 +54,7 @@ enhancement:
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.

View File

@@ -3,6 +3,9 @@
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.
## 2025
- SoftBrix
## 2024
- Sobuno
- TasneemTantawy

View File

@@ -83,6 +83,9 @@ class AccountController extends Controller
$return = [];
$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 */
foreach ($result as $account) {
$nameWithBalance = $account->name;

View File

@@ -32,6 +32,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\Preference;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Api\ApiSupport;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
@@ -80,6 +81,10 @@ class AccountController extends Controller
/** @var Carbon $end */
$end = $dates['end'];
// set dates to end of day + start of day:
$start->startOfDay();
$end->endOfDay();
// user's preferences
$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.
$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];
while ($currentStart <= $end) {
$format = $currentStart->format('Y-m-d');

View File

@@ -57,11 +57,11 @@ class IndexController extends Controller
public function index(): JsonResponse
{
$piggies = $this->repository->getAll();
$entries = $this->repository->getAll();
$pageSize = $this->parameters->get('limit');
$count = $piggies->count();
$piggies = $piggies->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($piggies, $count, $pageSize, $this->parameters->get('page'));
$count = $entries->count();
$entries = $entries->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($entries, $count, $pageSize, $this->parameters->get('page'));
$transformer = new ExchangeRateTransformer();
$transformer->setParameters($this->parameters); // give params to transformer

View File

@@ -31,6 +31,7 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
use FireflyIII\Support\Chart\ChartData;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Api\CleansChartData;
use FireflyIII\Support\Http\Api\CollectsAccountsFromFilter;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
@@ -118,7 +119,7 @@ class AccountController extends Controller
'native_entries' => [],
];
$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'];
$previousNative = array_values($range)[0]['native_balance'];

View File

@@ -54,6 +54,9 @@ class MonthReportGenerator implements ReportGeneratorInterface
$dayBefore = clone $this->start;
$dayBefore->subDay();
// move to end of day
$dayBefore->endOfDay();
/** @var Account $account */
foreach ($this->accounts as $account) {
// balance the day before:

View File

@@ -52,6 +52,7 @@ class AccountObserver
$currency = $repository->getAccountCurrency($account);
if (null !== $currency && $currency->id !== $userCurrency->id && '' !== (string) $account->virtual_balance && 0 !== bccomp($account->virtual_balance, '0')) {
$converter = new ExchangeRateConverter();
$converter->setUserGroup($account->user->userGroup);
$converter->setIgnoreSettings(true);
$account->native_virtual_balance = $converter->convert($currency, $userCurrency, today(), $account->virtual_balance);

View File

@@ -52,6 +52,7 @@ class AutoBudgetObserver
$autoBudget->native_amount = null;
if ($autoBudget->transactionCurrency->id !== $userCurrency->id) {
$converter = new ExchangeRateConverter();
$converter->setUserGroup($autoBudget->budget->user->userGroup);
$converter->setIgnoreSettings(true);
$autoBudget->native_amount = $converter->convert($autoBudget->transactionCurrency, $userCurrency, today(), $autoBudget->amount);
}

View File

@@ -64,6 +64,7 @@ class BillObserver
$bill->native_amount_max = null;
if ($bill->transactionCurrency->id !== $userCurrency->id) {
$converter = new ExchangeRateConverter();
$converter->setUserGroup($bill->user->userGroup);
$converter->setIgnoreSettings(true);
$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);

View File

@@ -54,6 +54,7 @@ class BudgetLimitObserver
$budgetLimit->native_amount = null;
if ($budgetLimit->transactionCurrency->id !== $userCurrency->id) {
$converter = new ExchangeRateConverter();
$converter->setUserGroup($budgetLimit->budget->user->userGroup);
$converter->setIgnoreSettings(true);
$budgetLimit->native_amount = $converter->convert($budgetLimit->transactionCurrency, $userCurrency, today(), $budgetLimit->amount);
}

View File

@@ -52,6 +52,7 @@ class PiggyBankEventObserver
$event->native_amount = null;
if ($event->piggyBank->transactionCurrency->id !== $userCurrency->id) {
$converter = new ExchangeRateConverter();
$converter->setUserGroup($event->piggyBank->accounts()->first()->user->userGroup);
$converter->setIgnoreSettings(true);
$event->native_amount = $converter->convert($event->piggyBank->transactionCurrency, $userCurrency, today(), $event->amount);
}

View File

@@ -714,6 +714,9 @@ class GroupCollector implements GroupCollectorInterface
if (null === $transaction['amount']) {
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:
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]['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]['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']) {
$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_decimal_places'] = $transaction['foreign_currency_decimal_places'];
$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'], $transaction['foreign_amount']);
$groups[$groudId]['sums'][$currencyId]['native_amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['native_foreign_amount']);
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $foreignAmount);
$groups[$groudId]['sums'][$currencyId]['native_amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $nativeForeignAmount);
}
}
}

View File

@@ -108,11 +108,14 @@ class ReconcileController extends Controller
if ($end->lt($start)) {
[$start, $end] = [$end, $start];
}
// move dates to end of day and start of day:
$start->startOfDay();
$end->endOfDay();
$startDate = clone $start;
$startDate->subDay();
$startBalance = Steam::finalAccountBalance($account, $startDate)['balance'];
$endBalance = Steam::finalAccountBalance($account, $end)['balance'];
$startBalance = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places);
$endBalance = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places);
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
$subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]);

View File

@@ -93,6 +93,11 @@ class ShowController extends Controller
if ($end->lt($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);
$attachments = $this->repository->getAttachments($account);
$today = today(config('app.timezone'));
@@ -181,6 +186,8 @@ class ShowController extends Controller
$subTitle = (string) trans('firefly.all_journals_for_account', ['name' => $account->name]);
$periods = new Collection();
$end->endOfDay();
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->setLimit($pageSize)->setPage($page)->withAccountInformation()->withCategoryInformation();

View File

@@ -35,7 +35,6 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Controllers\AugumentData;
use FireflyIII\Support\Http\Controllers\ChartGeneration;
@@ -416,7 +415,9 @@ class AccountController extends Controller
*/
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 = [];
$cache = new CacheProperties();
$cache->addProperty('chart.account.period');
@@ -425,7 +426,7 @@ class AccountController extends Controller
$cache->addProperty($this->convertToNative);
$cache->addProperty($account->id);
if ($cache->has()) {
return response()->json($cache->get());
// return response()->json($cache->get());
}
// collect and filter balances for the entire period.
@@ -442,11 +443,8 @@ class AccountController extends Controller
$format = (string) trans('config.month_and_day_js', [], $locale);
$accountCurrency = $this->accountRepository->getAccountCurrency($account);
Log::debug('One');
$range = Steam::finalAccountBalanceInRange($account, $start, $end, $this->convertToNative);
Log::debug('Two');
$range = Steam::filterAccountBalances($range, $account, $this->convertToNative, $accountCurrency);
Log::debug('Three');
// temp, get end balance.
Log::debug('temp get end balance');
@@ -462,25 +460,32 @@ class AccountController extends Controller
Log::debug('Balances exist at:');
foreach ($range as $key => $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)) {
$momentBalance = $previous;
$theDate = $current->format('Y-m-d');
while ($carbon->lte($current) && array_key_exists($expectedIndex, $newRange)) {
$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;
}
// $theDate = $current->format('Y-m-d');
Log::debug(sprintf('Now at %s, with momentBalance %s', $current->format('Y-m-d H:i:s'), json_encode($momentBalance)));
// 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);
$previous = $momentBalance;
Log::debug(sprintf('Now at %s', $theDate), $momentBalance);
// process each balance thing.
foreach ($momentBalance as $key => $amount) {
$label = $current->isoFormat($format);
@@ -489,8 +494,6 @@ class AccountController extends Controller
$current = app('navigation')->addPeriod($current, $step, 0);
// here too, to fix #8041, the data is corrected to the end of the period.
$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.');
// second loop (yes) to create nice array with info! Yay!

View File

@@ -189,9 +189,10 @@ class ReconcileController extends Controller
if ($end->lt($start)) {
[$end, $start] = [$start, $end];
}
$start->startOfDay();
$end->endOfDay();
$startDate = clone $start;
$startDate->subDay();
$end->endOfDay();
$currency = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency;
$startBalance = Steam::finalAccountBalance($account, $startDate)['balance'];

View File

@@ -83,6 +83,8 @@ class ReportController extends Controller
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
}
$this->repository->cleanupBudgets();
$start->startOfDay();
$end->endOfDay();
app('view')->share(
'subTitle',
@@ -114,6 +116,8 @@ class ReportController extends Controller
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
}
$this->repository->cleanupBudgets();
$start->startOfDay();
$end->endOfDay();
app('view')->share(
'subTitle',
@@ -146,6 +150,8 @@ class ReportController extends Controller
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
}
$this->repository->cleanupBudgets();
$start->startOfDay();
$end->endOfDay();
app('view')->share(
'subTitle',
@@ -179,6 +185,8 @@ class ReportController extends Controller
}
$this->repository->cleanupBudgets();
$start->startOfDay();
$end->endOfDay();
app('view')->share(
'subTitle',
@@ -211,6 +219,8 @@ class ReportController extends Controller
}
$this->repository->cleanupBudgets();
$start->startOfDay();
$end->endOfDay();
app('view')->share(
'subTitle',
@@ -367,6 +377,8 @@ class ReportController extends Controller
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
}
$this->repository->cleanupBudgets();
$start->startOfDay();
$end->endOfDay();
app('view')->share(
'subTitle',

View File

@@ -57,7 +57,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
*/
public function getCompleteSet(): Collection
{
return TransactionCurrency::orderBy('code', 'ASC')->get();
return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get();
}
/**

View File

@@ -108,6 +108,6 @@ class ExchangeRateRepository implements ExchangeRateRepositoryInterface
#[\Override]
public function getAll(): Collection
{
return $this->userGroup->currencyExchangeRates()->get();
return $this->userGroup->currencyExchangeRates()->orderBy('date', 'ASC')->get();
}
}

View File

@@ -410,11 +410,11 @@ class Steam
$defaultCurrency = app('amount')->getNativeCurrency();
if ($convertToNative) {
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]);
}
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']);
}
@@ -426,13 +426,13 @@ class Steam
if (!$convertToNative) {
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';
unset($set['native_balance'], $set[$defaultCurrency->code]);
}
if (null !== $currency) {
Log::debug(sprintf('Unset native_balance + defaultCurrency + currencyCode balance for account #%d', $account->id));
// Log::debug(sprintf('Unset native_balance + defaultCurrency + currencyCode balance for account #%d', $account->id));
unset($set['native_balance'], $set[$defaultCurrency->code], $set[$currency->code]);
}
}

View File

@@ -132,7 +132,7 @@ class PiggyBankTransformer extends AbstractTransformer
$return = [];
foreach ($piggyBank->accounts()->get() as $account) {
$return[] = [
'id' => $account->id,
'id' => (string) $account->id,
'name' => $account->name,
'current_amount' => (string) $account->pivot->current_amount,
'native_current_amount' => (string) $account->pivot->native_current_amount,

View File

@@ -3,6 +3,27 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## 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
- #9713
- #9727
- #9729
- #9730
- #9731
- #9732
- #9736
- #9738
- #9744
### Added
- #9743
## 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._

View File

@@ -81,7 +81,7 @@ return [
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
// see cer.php for exchange rates feature flag.
],
'version' => '6.2.1',
'version' => '6.2.2',
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 25,

View File

@@ -42,6 +42,9 @@ class TransactionCurrencySeeder extends Seeder
$currencies[] = ['code' => 'PLN', 'name' => 'Polish złoty', 'symbol' => 'zł', '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' => '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];
// american currencies

6
package-lock.json generated
View File

@@ -7159,9 +7159,9 @@
"license": "MIT"
},
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@@ -57,6 +57,7 @@ export default {
data() {
return {
currencies: [],
page: 1,
};
},
mounted() {
@@ -65,6 +66,7 @@ export default {
methods: {
getCurrencies: function () {
this.currencies = [];
// start with page one, loop for the rest.
this.downloadCurrencies(1);
},
downloadCurrencies: function (page) {

View File

@@ -42,6 +42,27 @@
<h3 class="box-title">{{ $t('firefly.header_exchange_rates_table') }}</h3>
</div>
<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">&lsaquo;</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')">&lsaquo;</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')">&rsaquo;</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">&rsaquo;</span>
</li>
</ul>
</nav>
<table class="table table-responsive table-hover">
<thead>
<tr>
@@ -98,6 +119,28 @@
</tr>
</tbody>
</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">&lsaquo;</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')">&lsaquo;</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')">&rsaquo;</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">&rsaquo;</span>
</li>
</ul>
</nav>
</div>
</div>
</div>
@@ -167,6 +210,8 @@ export default {
loading: true,
posting: false,
updating: false,
page: 1,
totalPages: 1,
};
},
mounted() {
@@ -175,8 +220,16 @@ export default {
let parts = window.location.href.split('/');
this.from_code = parts[parts.length - 2].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.downloadRates(1);
this.rates = [];
this.downloadRates(this.page);
},
methods: {
submitRate: function(e) {
@@ -203,16 +256,11 @@ export default {
return ('' === this.rates[index].rate && '' === this.rates[index].inverse) || this.updating;
},
updateRate: function (index) {
// console.log('Update!');
// console.log(this.rates[index].key);
let parts = this.spliceKey(this.rates[index].key);
if (0 === parts.length) {
return;
}
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;
axios.put("./api/v1/exchange-rates/" + this.rates[index].rate_id, {rate: this.rates[index].rate})
.then(() => {
@@ -220,9 +268,6 @@ export default {
});
}
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;
axios.put("./api/v1/exchange-rates/" + this.rates[index].inverse_id, {rate: this.rates[index].inverse})
.then(() => {
@@ -281,7 +326,6 @@ export default {
},
downloadRates: function (page) {
this.tempRates = {};
this.rates = [];
this.loading = true;
axios.get("./api/v1/exchange-rates/rates/" + this.from_code + '/' + this.to_code + '?page=' + page).then((response) => {
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.downloadRates(page + 1);
}
if (parseInt(response.data.meta.pagination.current_page) === parseInt(response.data.meta.pagination.total_pages)) {
this.loading = false;
this.rates = Object.values(this.tempRates);
}
this.totalPages = parseInt(response.data.meta.pagination.total_pages);
this.loading = false;
this.rates = Object.values(this.tempRates);
console.log('Do not download more pages. Now on page ' + this.page + ' of ' + this.totalPages);
});
}
},

View File

@@ -138,7 +138,7 @@
"visit_webhook_url": "Webhook-URL besuchen",
"reset_webhook_secret": "Webhook Secret zur\u00fccksetzen",
"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_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",

View File

@@ -138,7 +138,7 @@
"visit_webhook_url": "Visiter l'URL du webhook",
"reset_webhook_secret": "R\u00e9initialiser le secret du webhook",
"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_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",

View File

@@ -36,8 +36,8 @@
<h3 class="box-title">{{ 'optionalFields'|_ }}</h3>
</div>
<div class="box-body">
{{ ExpandedForm.date('startdate') }}
{{ ExpandedForm.date('targetdate') }}
{{ ExpandedForm.date('start_date') }}
{{ ExpandedForm.date('target_date') }}
{{ 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.objectGroup() }}