This commit is contained in:
James Cole
2025-04-21 08:03:32 +02:00
parent efc516eb3b
commit c25adf0a56
8 changed files with 51 additions and 21 deletions

View File

@@ -177,7 +177,7 @@ class IndexController extends Controller
$array['end_date'] = $entry->end_date; $array['end_date'] = $entry->end_date;
// spent in period: // spent in period:
$spentArr = $this->opsRepository->sumExpenses($entry->start_date, $entry->end_date, null, null, $entry->transactionCurrency); $spentArr = $this->opsRepository->sumExpenses($entry->start_date, $entry->end_date, null, null, $entry->transactionCurrency, false);
$array['spent'] = $spentArr[$entry->transaction_currency_id]['sum'] ?? '0'; $array['spent'] = $spentArr[$entry->transaction_currency_id]['sum'] ?? '0';
$array['native_spent'] = $this->convertToNative && $entry->transaction_currency_id !== $this->defaultCurrency->id ? $converter->convert($entry->transactionCurrency, $this->defaultCurrency, $entry->start_date, $array['spent']) : null; $array['native_spent'] = $this->convertToNative && $entry->transaction_currency_id !== $this->defaultCurrency->id ? $converter->convert($entry->transactionCurrency, $this->defaultCurrency, $entry->start_date, $array['spent']) : null;
// budgeted in period: // budgeted in period:
@@ -235,7 +235,7 @@ class IndexController extends Controller
/** @var TransactionCurrency $currency */ /** @var TransactionCurrency $currency */
foreach ($currencies as $currency) { foreach ($currencies as $currency) {
$spentArr = $this->opsRepository->sumExpenses($start, $end, null, new Collection([$current]), $currency); $spentArr = $this->opsRepository->sumExpenses($start, $end, null, new Collection([$current]), $currency, false);
if (array_key_exists($currency->id, $spentArr) && array_key_exists('sum', $spentArr[$currency->id])) { if (array_key_exists($currency->id, $spentArr) && array_key_exists('sum', $spentArr[$currency->id])) {
$array['spent'][$currency->id]['spent'] = $spentArr[$currency->id]['sum']; $array['spent'][$currency->id]['spent'] = $spentArr[$currency->id]['sum'];
$array['spent'][$currency->id]['currency_id'] = $currency->id; $array['spent'][$currency->id]['currency_id'] = $currency->id;

View File

@@ -175,6 +175,7 @@ class ShowController extends Controller
throw new FireflyException('This budget limit is not part of this budget.'); throw new FireflyException('This budget limit is not part of this budget.');
} }
$currencySymbol = $budgetLimit->transactionCurrency->symbol;
$page = (int) $request->get('page'); $page = (int) $request->get('page');
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data; $pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
$subTitle = trans( $subTitle = trans(
@@ -186,6 +187,9 @@ class ShowController extends Controller
'currency' => $budgetLimit->transactionCurrency->name, 'currency' => $budgetLimit->transactionCurrency->name,
] ]
); );
if($this->convertToNative) {
$currencySymbol = $this->defaultCurrency->symbol;
}
// collector: // collector:
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
@@ -203,6 +207,6 @@ class ShowController extends Controller
$attachments = $this->repository->getAttachments($budget); $attachments = $this->repository->getAttachments($budget);
$limits = $this->getLimits($budget, $start, $end); $limits = $this->getLimits($budget, $start, $end);
return view('budgets.show', compact('limits', 'attachments', 'budget', 'budgetLimit', 'groups', 'subTitle')); return view('budgets.show', compact('limits', 'attachments', 'budget', 'budgetLimit', 'groups', 'subTitle', 'currencySymbol'));
} }
} }

View File

@@ -164,7 +164,7 @@ class BudgetController extends Controller
$cache->addProperty($budget->id); $cache->addProperty($budget->id);
if ($cache->has()) { if ($cache->has()) {
return response()->json($cache->get()); return response()->json($cache->get());
} }
$locale = app('steam')->getLocale(); $locale = app('steam')->getLocale();
$entries = []; $entries = [];
@@ -172,13 +172,13 @@ class BudgetController extends Controller
$budgetCollection = new Collection([$budget]); $budgetCollection = new Collection([$budget]);
$currency = $budgetLimit->transactionCurrency; $currency = $budgetLimit->transactionCurrency;
if ($this->convertToNative) { if ($this->convertToNative) {
$amount = $budgetLimit->native_amount ?? '0'; $amount = $budgetLimit->native_amount ?? $amount;
$currency = $this->defaultCurrency; $currency = $this->defaultCurrency;
} }
while ($start <= $end) { while ($start <= $end) {
$current = clone $start; $current = clone $start;
$expenses = $this->opsRepository->sumExpenses($current, $current, null, $budgetCollection, $budgetLimit->transactionCurrency); $expenses = $this->opsRepository->sumExpenses($current, $current, null, $budgetCollection, $budgetLimit->transactionCurrency, $this->convertToNative);
$spent = $expenses[$currency->id]['sum'] ?? '0'; $spent = $expenses[$currency->id]['sum'] ?? '0';
$amount = bcadd($amount, $spent); $amount = bcadd($amount, $spent);
$format = $start->isoFormat((string) trans('config.month_and_day_js', [], $locale)); $format = $start->isoFormat((string) trans('config.month_and_day_js', [], $locale));
@@ -191,6 +191,7 @@ class BudgetController extends Controller
$data['datasets'][0]['currency_symbol'] = $currency->symbol; $data['datasets'][0]['currency_symbol'] = $currency->symbol;
$data['datasets'][0]['currency_code'] = $currency->code; $data['datasets'][0]['currency_code'] = $currency->code;
$cache->store($data); $cache->store($data);
//var_dump($data);exit;
return response()->json($data); return response()->json($data);
} }
@@ -214,7 +215,7 @@ class BudgetController extends Controller
if (null !== $budgetLimit) { if (null !== $budgetLimit) {
$start = $budgetLimit->start_date; $start = $budgetLimit->start_date;
$end = $budgetLimit->end_date; $end = $budgetLimit->end_date;
$collector->setRange($budgetLimit->start_date, $budgetLimit->end_date)->setCurrency($budgetLimit->transactionCurrency); $collector->setRange($budgetLimit->start_date, $budgetLimit->end_date)->setNormalCurrency($budgetLimit->transactionCurrency);
} }
$cache->addProperty($start); $cache->addProperty($start);
$cache->addProperty($end); $cache->addProperty($end);
@@ -296,7 +297,7 @@ class BudgetController extends Controller
if (null !== $budgetLimit) { if (null !== $budgetLimit) {
$start = $budgetLimit->start_date; $start = $budgetLimit->start_date;
$end = $budgetLimit->end_date; $end = $budgetLimit->end_date;
$collector->setCurrency($budgetLimit->transactionCurrency); $collector->setNormalCurrency($budgetLimit->transactionCurrency);
} }
$cache->addProperty($start); $cache->addProperty($start);
$cache->addProperty($end); $cache->addProperty($end);
@@ -378,7 +379,7 @@ class BudgetController extends Controller
if (null !== $budgetLimit) { if (null !== $budgetLimit) {
$start = $budgetLimit->start_date; $start = $budgetLimit->start_date;
$end = $budgetLimit->end_date; $end = $budgetLimit->end_date;
$collector->setRange($budgetLimit->start_date, $budgetLimit->end_date)->setCurrency($budgetLimit->transactionCurrency); $collector->setRange($budgetLimit->start_date, $budgetLimit->end_date)->setNormalCurrency($budgetLimit->transactionCurrency);
} }
$cache->addProperty($start); $cache->addProperty($start);
$cache->addProperty($end); $cache->addProperty($end);

View File

@@ -31,6 +31,7 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Report\Summarizer\TransactionSummarizer; use FireflyIII\Support\Report\Summarizer\TransactionSummarizer;
use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface; use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait; use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
@@ -201,9 +202,10 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
Carbon $end, Carbon $end,
?Collection $accounts = null, ?Collection $accounts = null,
?Collection $budgets = null, ?Collection $budgets = null,
?TransactionCurrency $currency = null ?TransactionCurrency $currency = null,
bool $convertToNative = false
): array { ): array {
Log::debug(sprintf('Start of %s.', __METHOD__)); Log::debug(sprintf('Start of %s(date, date, array, array, "%s", "%s").', __METHOD__, $currency?->code, var_export($convertToNative, true)));
// this collector excludes all transfers TO liabilities (which are also withdrawals) // this collector excludes all transfers TO liabilities (which are also withdrawals)
// because those expenses only become expenses once they move from the liability to the friend. // because those expenses only become expenses once they move from the liability to the friend.
// 2024-12-24 disable the exclusion for now. // 2024-12-24 disable the exclusion for now.
@@ -235,8 +237,8 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
$budgets = $this->getBudgets(); $budgets = $this->getBudgets();
} }
if (null !== $currency) { if (null !== $currency) {
Log::debug(sprintf('Limit to currency %s', $currency->code)); Log::debug(sprintf('Limit to normal currency %s', $currency->code));
$collector->setCurrency($currency); $collector->setNormalCurrency($currency);
} }
$collector->setBudgets($budgets); $collector->setBudgets($budgets);
$journals = $collector->getExtractedJournals(); $journals = $collector->getExtractedJournals();
@@ -246,6 +248,8 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
Log::debug('STOP looking for transactions in the foreign currency.'); Log::debug('STOP looking for transactions in the foreign currency.');
} }
$summarizer = new TransactionSummarizer($this->user); $summarizer = new TransactionSummarizer($this->user);
// 2025-04-21 overrule "convertToNative" because in this particular view, we never want to do this.
$summarizer->setConvertToNative($convertToNative);
return $summarizer->groupByCurrencyId($journals, 'negative', false); return $summarizer->groupByCurrencyId($journals, 'negative', false);
} }

View File

@@ -38,6 +38,7 @@ use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/** /**
* Trait AugumentData * Trait AugumentData
@@ -167,6 +168,7 @@ trait AugumentData
*/ */
protected function getLimits(Budget $budget, Carbon $start, Carbon $end): Collection // get data + augment with info protected function getLimits(Budget $budget, Carbon $start, Carbon $end): Collection // get data + augment with info
{ {
Log::debug('In getLimits');
/** @var OperationsRepositoryInterface $opsRepository */ /** @var OperationsRepositoryInterface $opsRepository */
$opsRepository = app(OperationsRepositoryInterface::class); $opsRepository = app(OperationsRepositoryInterface::class);
@@ -183,7 +185,7 @@ trait AugumentData
$cache->addProperty('get-limits'); $cache->addProperty('get-limits');
if ($cache->has()) { if ($cache->has()) {
return $cache->get(); return $cache->get();
} }
$set = $blRepository->getBudgetLimits($budget, $start, $end); $set = $blRepository->getBudgetLimits($budget, $start, $end);
@@ -192,13 +194,13 @@ trait AugumentData
// merge sets based on a key, in case of convert to native // merge sets based on a key, in case of convert to native
$limits = new Collection(); $limits = new Collection();
/** @var BudgetLimit $entry */ /** @var BudgetLimit $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
Log::debug(sprintf('Now at budget limit #%d', $entry->id));
$currency = $entry->transactionCurrency; $currency = $entry->transactionCurrency;
if ($this->convertToNative) { if ($this->convertToNative) {
// the sumExpenses method already handles this. // the sumExpenses method already handles this.
$currency = $this->defaultCurrency; $currency = $this->defaultCurrency;
} }
// clone because these objects change each other. // clone because these objects change each other.
@@ -209,9 +211,14 @@ trait AugumentData
$currentEnd = clone $currentStart; $currentEnd = clone $currentStart;
$currentEnd->addMonth(); $currentEnd->addMonth();
} }
// native amount.
$expenses = $opsRepository->sumExpenses($currentStart, $currentEnd, null, $budgetCollection, $currency); $expenses = $opsRepository->sumExpenses($currentStart, $currentEnd, null, $budgetCollection, $entry->transactionCurrency, $this->convertToNative);
$spent = $expenses[$currency->id]['sum'] ?? '0'; $spent = $expenses[$currency->id]['sum'] ?? '0';
$entry->native_spent = $spent;
// normal amount:
$expenses = $opsRepository->sumExpenses($currentStart, $currentEnd, null, $budgetCollection, $entry->transactionCurrency, false);
$spent = $expenses[$entry->transactionCurrency->id]['sum'] ?? '0';
$entry->spent = $spent; $entry->spent = $spent;
$limits->push($entry); $limits->push($entry);

View File

@@ -51,7 +51,7 @@ class TransactionSummarizer
public function groupByCurrencyId(array $journals, string $method = 'negative', bool $includeForeign = true): array public function groupByCurrencyId(array $journals, string $method = 'negative', bool $includeForeign = true): array
{ {
Log::debug(sprintf('Now in groupByCurrencyId(array, "%s")', $method)); Log::debug(sprintf('Now in groupByCurrencyId([%d journals], "%s")', count($journals), $method));
$array = []; $array = [];
foreach ($journals as $journal) { foreach ($journals as $journal) {
$field = 'amount'; $field = 'amount';
@@ -71,6 +71,7 @@ class TransactionSummarizer
$foreignCurrencyDecimalPlaces = null; $foreignCurrencyDecimalPlaces = null;
if ($this->convertToNative) { if ($this->convertToNative) {
Log::debug('convertToNative is true.');
// if convert to native, use the native amount yes or no? // if convert to native, use the native amount yes or no?
$useNative = $this->default->id !== (int) $journal['currency_id']; $useNative = $this->default->id !== (int) $journal['currency_id'];
$useForeign = $this->default->id === (int) $journal['foreign_currency_id']; $useForeign = $this->default->id === (int) $journal['foreign_currency_id'];
@@ -94,6 +95,7 @@ class TransactionSummarizer
} }
} }
if (!$this->convertToNative) { if (!$this->convertToNative) {
Log::debug('convertToNative is false.');
// use foreign amount? // use foreign amount?
$foreignCurrencyId = (int) $journal['foreign_currency_id']; $foreignCurrencyId = (int) $journal['foreign_currency_id'];
if (0 !== $foreignCurrencyId) { if (0 !== $foreignCurrencyId) {
@@ -224,4 +226,12 @@ class TransactionSummarizer
return $array; return $array;
} }
public function setConvertToNative(bool $convertToNative): void
{
Log::debug(sprintf('Overrule convertToNative to become %s', var_export($convertToNative, true)));
$this->convertToNative = $convertToNative;
}
} }

View File

@@ -314,6 +314,7 @@
{% endif %} {% endif %}
</td> </td>
<td class="hidden-sm hidden-xs spent" data-id="{{ budget.id }}" style="text-align:right;"> <td class="hidden-sm hidden-xs spent" data-id="{{ budget.id }}" style="text-align:right;">
{% for spentInfo in budget.spent %} {% for spentInfo in budget.spent %}
{{ formatAmountBySymbol(spentInfo.spent, spentInfo.currency_symbol, spentInfo.currency_decimal_places) }} {{ formatAmountBySymbol(spentInfo.spent, spentInfo.currency_symbol, spentInfo.currency_decimal_places) }}
{% if 0 == activeDaysPassed %} {% if 0 == activeDaysPassed %}

View File

@@ -167,7 +167,10 @@
<td style="width:33%;">{{ 'spent'|_ }}</td> <td style="width:33%;">{{ 'spent'|_ }}</td>
<td> <td>
{% if convertToNative %} {% if convertToNative %}
{{ formatAmountBySymbol(limit.spent, defaultCurrency.symbol, defaultCurrency.decimal_places) }} {{ formatAmountBySymbol(limit.spent, limit.transactionCurrency.symbol, limit.transactionCurrency.decimal_places) }}
{% if limit.native_spent %}
({{ formatAmountBySymbol(limit.native_spent, defaultCurrency.symbol, defaultCurrency.decimal_places) }})
{% endif %}
{% else %} {% else %}
{{ formatAmountBySymbol(limit.spent, limit.transactionCurrency.symbol, limit.transactionCurrency.decimal_places) }} {{ formatAmountBySymbol(limit.spent, limit.transactionCurrency.symbol, limit.transactionCurrency.decimal_places) }}
{% endif %} {% endif %}
@@ -215,7 +218,7 @@
{% if budgetLimit.id %} {% if budgetLimit.id %}
budgetLimitID = {{ budgetLimit.id }}; budgetLimitID = {{ budgetLimit.id }};
var budgetChartUrl = '{{ route('chart.budget.budget-limit', [budget.id, budgetLimit.id] ) }}'; var budgetChartUrl = '{{ route('chart.budget.budget-limit', [budget.id, budgetLimit.id] ) }}';
var currencySymbol = '{{ budgetLimit.transactionCurrency.symbol }}'; var currencySymbol = '{{ currencySymbol }}';
var expenseCategoryUrl = '{{ route('chart.budget.expense-category', [budget.id, budgetLimit.id]) }}'; var expenseCategoryUrl = '{{ route('chart.budget.expense-category', [budget.id, budgetLimit.id]) }}';
var expenseAssetUrl = '{{ route('chart.budget.expense-asset', [budget.id, budgetLimit.id]) }}'; var expenseAssetUrl = '{{ route('chart.budget.expense-asset', [budget.id, budgetLimit.id]) }}';
var expenseExpenseUrl = '{{ route('chart.budget.expense-expense', [budget.id, budgetLimit.id]) }}'; var expenseExpenseUrl = '{{ route('chart.budget.expense-expense', [budget.id, budgetLimit.id]) }}';