Category chart will also convert.

This commit is contained in:
James Cole
2025-07-30 10:20:35 +02:00
parent 30da3f4399
commit 1a633e64ef
2 changed files with 46 additions and 32 deletions

View File

@@ -25,17 +25,20 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Chart; namespace FireflyIII\Api\V1\Controllers\Chart;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Api\V2\Controllers\Controller; use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V2\Request\Generic\DateRequest; use FireflyIII\Api\V2\Request\Generic\DateRequest;
use FireflyIII\Enums\AccountTypeEnum; use FireflyIII\Enums\AccountTypeEnum;
use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\CleansChartData; use FireflyIII\Support\Http\Api\CleansChartData;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait; use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
/** /**
* Class BudgetController * Class BudgetController
@@ -45,6 +48,8 @@ class CategoryController extends Controller
use CleansChartData; use CleansChartData;
use ValidatesUserGroupTrait; use ValidatesUserGroupTrait;
protected array $acceptedRoles = [UserRoleEnum::READ_ONLY];
private AccountRepositoryInterface $accountRepos; private AccountRepositoryInterface $accountRepos;
private CurrencyRepositoryInterface $currencyRepos; private CurrencyRepositoryInterface $currencyRepos;
@@ -79,9 +84,10 @@ class CategoryController extends Controller
/** @var Carbon $end */ /** @var Carbon $end */
$end = $this->parameters->get('end'); $end = $this->parameters->get('end');
$accounts = $this->accountRepos->getAccountsByType([AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::ASSET->value, AccountTypeEnum::DEFAULT->value]); $accounts = $this->accountRepos->getAccountsByType([AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::ASSET->value]);
$currencies = []; $currencies = [];
$return = []; $return = [];
$converter = new ExchangeRateConverter();
// get journals for entire period: // get journals for entire period:
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
@@ -93,20 +99,40 @@ class CategoryController extends Controller
/** @var array $journal */ /** @var array $journal */
foreach ($journals as $journal) { foreach ($journals as $journal) {
$currencyId = (int) $journal['currency_id']; // find journal:
$currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId); $journalCurrencyId = (int)$journal['currency_id'];
$currencies[$currencyId] = $currency; $currency = $currencies[$journalCurrencyId] ?? $this->currencyRepos->find($journalCurrencyId);
$categoryName = $journal['category_name'] ?? (string) trans('firefly.no_category'); $currencies[$journalCurrencyId] = $currency;
$currencyId = (int)$currency->id;
$currencyName = (string)$currency->name;
$currencyCode = (string)$currency->code;
$currencySymbol = (string)$currency->symbol;
$currencyDecimalPlaces = (int)$currency->decimal_places;
$amount = app('steam')->positive($journal['amount']); $amount = app('steam')->positive($journal['amount']);
$key = sprintf('%s-%s', $categoryName, $currency->code);
// overrule if necessary:
if ($this->convertToNative && $journalCurrencyId !== $this->nativeCurrency->id) {
$currencyId = (int)$this->nativeCurrency->id;
$currencyName = (string)$this->nativeCurrency->name;
$currencyCode = (string)$this->nativeCurrency->code;
$currencySymbol = (string)$this->nativeCurrency->symbol;
$currencyDecimalPlaces = (int)$this->nativeCurrency->decimal_places;
$convertedAmount = $converter->convert($currency, $this->nativeCurrency, $journal['date'], $amount);
Log::debug(sprintf('Converted %s %s to %s %s', $journal['currency_code'], $amount, $this->nativeCurrency->code, $convertedAmount));
$amount = $convertedAmount;
}
$categoryName = $journal['category_name'] ?? (string)trans('firefly.no_category');
$key = sprintf('%s-%s', $categoryName, $currencyCode);
// create arrays // create arrays
$return[$key] ??= [ $return[$key] ??= [
'label' => $categoryName, 'label' => $categoryName,
'currency_id' => (string) $currency->id, 'currency_id' => (string)$currencyId,
'currency_code' => $currency->code, 'currency_code' => $currencyCode,
'currency_name' => $currency->name, 'currency_name' => $currencyName,
'currency_symbol' => $currency->symbol, 'currency_symbol' => $currencySymbol,
'currency_decimal_places' => $currency->decimal_places, 'currency_decimal_places' => $currencyDecimalPlaces,
'period' => null, 'period' => null,
'start' => $start->toAtomString(), 'start' => $start->toAtomString(),
'end' => $end->toAtomString(), 'end' => $end->toAtomString(),

View File

@@ -54,11 +54,6 @@ export default () => ({
if (data.hasOwnProperty(i)) { if (data.hasOwnProperty(i)) {
let current = data[i]; let current = data[i];
let code = current.currency_code; let code = current.currency_code;
// only use native code when doing auto conversion.
if (this.convertToNative) {
code = current.native_currency_code;
}
if (!series.hasOwnProperty(code)) { if (!series.hasOwnProperty(code)) {
series[code] = { series[code] = {
name: code, name: code,
@@ -76,9 +71,6 @@ export default () => ({
let yAxis = 'y'; let yAxis = 'y';
let current = data[i]; let current = data[i];
let code = current.currency_code; let code = current.currency_code;
if (this.convertToNative) {
code = current.native_currency_code;
}
// loop series, add 0 if not present or add actual amount. // loop series, add 0 if not present or add actual amount.
for (const ii in series) { for (const ii in series) {
@@ -88,10 +80,6 @@ export default () => ({
// this series' currency matches this column's currency. // this series' currency matches this column's currency.
amount = parseFloat(current.amount); amount = parseFloat(current.amount);
yAxis = 'y' + current.currency_code; yAxis = 'y' + current.currency_code;
if (this.convertToNative) {
amount = parseFloat(current.native_amount);
yAxis = 'y' + current.native_currency_code;
}
} }
if (series[ii].data.hasOwnProperty(current.label)) { if (series[ii].data.hasOwnProperty(current.label)) {
// there is a value for this particular currency. The amount from this column will be added. // there is a value for this particular currency. The amount from this column will be added.