Compare commits

..

11 Commits

Author SHA1 Message Date
github-actions
ee260a3df7 Auto commit for release 'develop' on 2025-02-11 2025-02-11 10:47:28 +01:00
Sander Dorigo
7cb41fb333 fix a null pointer 2025-02-11 10:41:32 +01:00
Sander Dorigo
d38adbfdc2 Fix #9808 2025-02-11 08:39:44 +01:00
Sander Dorigo
e6a6766ef1 update instructions 2025-02-11 08:36:24 +01:00
James Cole
a1e596491c Add debug logging. 2025-02-11 06:13:28 +01:00
James Cole
9c920908a6 Fix type errors 2025-02-11 06:06:30 +01:00
James Cole
0014bffeb8 Fix #9807 2025-02-11 06:06:09 +01:00
James Cole
63c17f99b2 Fix parse error 2025-02-11 06:05:47 +01:00
James Cole
ec1e0e2807 New notifications controller (not yet used) 2025-02-11 05:53:34 +01:00
Sander Dorigo
2f16419a7b Add debug logging to finalAccountBalance. 2025-02-10 16:47:59 +01:00
James Cole
02c13859e7 Update ValidatesUserGroupTrait.php
Signed-off-by: James Cole <james@firefly-iii.org>
2025-02-10 10:28:50 +01:00
29 changed files with 144 additions and 56 deletions

View File

@@ -189,7 +189,7 @@ SEND_REPORT_JOURNALS=true
ENABLE_EXTERNAL_MAP=false ENABLE_EXTERNAL_MAP=false
# #
# Enable or disable exchange rate conversion. This function isn't used yet by Firefly III # Enable or disable exchange rate conversion.
# #
ENABLE_EXCHANGE_RATES=false ENABLE_EXCHANGE_RATES=false

View File

@@ -34,6 +34,7 @@ use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Http\Api\AccountFilter; use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
/** /**
* Class AccountController * Class AccountController
@@ -83,8 +84,8 @@ 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. // set date to subday + end-of-day for account balance. so it is at $date 23:59:59
$date->endOfDay(); $date->subDay()->endOfDay();
/** @var Account $account */ /** @var Account $account */
foreach ($result as $account) { foreach ($result as $account) {
@@ -92,6 +93,7 @@ class AccountController extends Controller
$currency = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency; $currency = $this->repository->getAccountCurrency($account) ?? $this->nativeCurrency;
$useCurrency = $currency; $useCurrency = $currency;
if (in_array($account->accountType->type, $this->balanceTypes, true)) { if (in_array($account->accountType->type, $this->balanceTypes, true)) {
Log::debug(sprintf('accounts: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$balance = Steam::finalAccountBalance($account, $date); $balance = Steam::finalAccountBalance($account, $date);
$key = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? 'native_balance' : 'balance'; $key = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? 'native_balance' : 'balance';
$useCurrency = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? $this->nativeCurrency : $currency; $useCurrency = $this->convertToNative && $currency->id !== $this->nativeCurrency->id ? $this->nativeCurrency : $currency;

View File

@@ -33,6 +33,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/** /**
* Class MonthReportGenerator. * Class MonthReportGenerator.
@@ -52,10 +53,9 @@ class MonthReportGenerator implements ReportGeneratorInterface
{ {
$auditData = []; $auditData = [];
$dayBefore = clone $this->start; $dayBefore = clone $this->start;
$dayBefore->subDay();
// move to end of day // set date to subday + end-of-day for account balance. so it is at $date 23:59:59
$dayBefore->endOfDay(); $dayBefore->subDay()->endOfDay();
/** @var Account $account */ /** @var Account $account */
foreach ($this->accounts as $account) { foreach ($this->accounts as $account) {
@@ -136,6 +136,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
; ;
$journals = $collector->getExtractedJournals(); $journals = $collector->getExtractedJournals();
$journals = array_reverse($journals, true); $journals = array_reverse($journals, true);
Log::debug(sprintf('getAuditReport: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$dayBeforeBalance = Steam::finalAccountBalance($account, $date); $dayBeforeBalance = Steam::finalAccountBalance($account, $date);
$startBalance = $dayBeforeBalance['balance']; $startBalance = $dayBeforeBalance['balance'];
$defaultCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); $defaultCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup);
@@ -170,6 +171,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
$journals[$index]['invoice_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'invoice_date'); $journals[$index]['invoice_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'invoice_date');
} }
$locale = app('steam')->getLocale(); $locale = app('steam')->getLocale();
Log::debug(sprintf('getAuditReport end: Call finalAccountBalance with date/time "%s"', $this->end->toIso8601String()));
return [ return [
'journals' => $journals, 'journals' => $journals,

View File

@@ -258,7 +258,12 @@ trait AccountCollection
if (null === $account) { if (null === $account) {
continue; continue;
} }
$balance = Steam::finalAccountBalance($account, $transaction['date']); // the balance must be found BEFORE the transaction date.
// so sub one second. This is not perfect, but works well enough.
$date = clone $transaction['date'];
$date->subSecond();
Log::debug(sprintf('accountBalanceIs: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$balance = Steam::finalAccountBalance($account, $date);
$result = bccomp($balance['balance'], $value); $result = bccomp($balance['balance'], $value);
Log::debug(sprintf('"%s" vs "%s" is %d', $balance['balance'], $value, $result)); Log::debug(sprintf('"%s" vs "%s" is %d', $balance['balance'], $value, $result));

View File

@@ -79,6 +79,7 @@ class NetWorth implements NetWorthInterface
Log::debug(sprintf('Now in byAccounts("%s", "%s")', $ids, $date->format('Y-m-d H:i:s'))); Log::debug(sprintf('Now in byAccounts("%s", "%s")', $ids, $date->format('Y-m-d H:i:s')));
$default = Amount::getNativeCurrency(); $default = Amount::getNativeCurrency();
$netWorth = []; $netWorth = [];
Log::debug(sprintf('NetWorth: finalAccountsBalance("%s")', $date->format('Y-m-d H:i:s')));
$balances = Steam::finalAccountsBalance($accounts, $date); $balances = Steam::finalAccountsBalance($accounts, $date);
/** @var Account $account */ /** @var Account $account */
@@ -159,6 +160,7 @@ class NetWorth implements NetWorthInterface
*/ */
$accounts = $this->getAccounts(); $accounts = $this->getAccounts();
$return = []; $return = [];
Log::debug(sprintf('SumNetWorth: finalAccountsBalance("%s")', $date->format('Y-m-d H:i:s')));
$balances = Steam::finalAccountsBalance($accounts, $date); $balances = Steam::finalAccountsBalance($accounts, $date);
foreach ($accounts as $account) { foreach ($accounts as $account) {
$currency = $this->getRepository()->getAccountCurrency($account); $currency = $this->getRepository()->getAccountCurrency($account);

View File

@@ -33,6 +33,7 @@ use FireflyIII\Support\Http\Controllers\BasicDataSupport;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View; use Illuminate\View\View;
/** /**
@@ -90,9 +91,11 @@ class IndexController extends Controller
$start->subDay(); $start->subDay();
$ids = $accounts->pluck('id')->toArray(); $ids = $accounts->pluck('id')->toArray();
$startBalances = app('steam')->finalAccountsBalance($accounts, $start); Log::debug(sprintf('inactive start: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s')));
$endBalances = app('steam')->finalAccountsBalance($accounts, $end); Log::debug(sprintf('inactive end: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s')));
$activities = app('steam')->getLastActivities($ids); $startBalances = Steam::finalAccountsBalance($accounts, $start);
$endBalances = Steam::finalAccountsBalance($accounts, $end);
$activities = Steam::getLastActivities($ids);
$accounts->each( $accounts->each(
@@ -102,7 +105,7 @@ class IndexController extends Controller
$account->startBalances = Steam::filterAccountBalance($startBalances[$account->id] ?? [], $account, $this->convertToNative, $currency); $account->startBalances = Steam::filterAccountBalance($startBalances[$account->id] ?? [], $account, $this->convertToNative, $currency);
$account->endBalances = Steam::filterAccountBalance($endBalances[$account->id] ?? [], $account, $this->convertToNative, $currency); $account->endBalances = Steam::filterAccountBalance($endBalances[$account->id] ?? [], $account, $this->convertToNative, $currency);
$account->differences = $this->subtract($account->startBalances, $account->endBalances); $account->differences = $this->subtract($account->startBalances, $account->endBalances);
$account->interest = app('steam')->bcround($this->repository->getMetaValue($account, 'interest'), 4); $account->interest = Steam::bcround($this->repository->getMetaValue($account, 'interest'), 4);
$account->interestPeriod = (string) trans(sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period'))); $account->interestPeriod = (string) trans(sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period')));
$account->accountTypeString = (string) trans(sprintf('firefly.account_type_%s', $account->accountType->type)); $account->accountTypeString = (string) trans(sprintf('firefly.account_type_%s', $account->accountType->type));
$account->current_debt = '0'; $account->current_debt = '0';
@@ -153,9 +156,11 @@ class IndexController extends Controller
$start->subDay(); $start->subDay();
$ids = $accounts->pluck('id')->toArray(); $ids = $accounts->pluck('id')->toArray();
$startBalances = app('steam')->finalAccountsBalance($accounts, $start); Log::debug(sprintf('index start: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s')));
$endBalances = app('steam')->finalAccountsBalance($accounts, $end); Log::debug(sprintf('index end: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s')));
$activities = app('steam')->getLastActivities($ids); $startBalances = Steam::finalAccountsBalance($accounts, $start);
$endBalances = Steam::finalAccountsBalance($accounts, $end);
$activities = Steam::getLastActivities($ids);
$accounts->each( $accounts->each(
@@ -168,7 +173,7 @@ class IndexController extends Controller
$account->endBalances = Steam::filterAccountBalance($endBalances[$account->id] ?? [], $account, $this->convertToNative, $currency); $account->endBalances = Steam::filterAccountBalance($endBalances[$account->id] ?? [], $account, $this->convertToNative, $currency);
$account->differences = $this->subtract($account->startBalances, $account->endBalances); $account->differences = $this->subtract($account->startBalances, $account->endBalances);
$account->lastActivityDate = $this->isInArrayDate($activities, $account->id); $account->lastActivityDate = $this->isInArrayDate($activities, $account->id);
$account->interest = app('steam')->bcround($interest, 4); $account->interest = Steam::bcround($interest, 4);
$account->interestPeriod = (string) trans( $account->interestPeriod = (string) trans(
sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period')) sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period'))
); );

View File

@@ -39,6 +39,7 @@ use FireflyIII\User;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector; use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View; use Illuminate\View\View;
/** /**
@@ -113,7 +114,9 @@ class ReconcileController extends Controller
$end->endOfDay(); $end->endOfDay();
$startDate = clone $start; $startDate = clone $start;
$startDate->subDay()->endOfDay(); $startDate->subDay()->endOfDay(); // this is correct, subday endofday ends at 23:59:59
Log::debug(sprintf('reconcile: Call finalAccountBalance with date/time "%s"', $startDate->toIso8601String()));
Log::debug(sprintf('reconcile2: Call finalAccountBalance with date/time "%s"', $end->toIso8601String()));
$startBalance = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places); $startBalance = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places);
$endBalance = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places); $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));

View File

@@ -37,6 +37,7 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Routing\Redirector; use Illuminate\Routing\Redirector;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View; use Illuminate\View\View;
/** /**
@@ -135,6 +136,7 @@ class ShowController extends Controller
$groups->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')])); $groups->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]));
$showAll = false; $showAll = false;
Log::debug(sprintf('show: Call finalAccountBalance with date/time "%s"', $end->toIso8601String()));
$balances = Steam::filterAccountBalance(Steam::finalAccountBalance($account, $end), $account, $this->convertToNative, $accountCurrency); $balances = Steam::filterAccountBalance(Steam::finalAccountBalance($account, $end), $account, $this->convertToNative, $accountCurrency);
return view( return view(
@@ -200,6 +202,7 @@ class ShowController extends Controller
$groups->setPath(route('accounts.show.all', [$account->id])); $groups->setPath(route('accounts.show.all', [$account->id]));
$chartUrl = route('chart.account.period', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]); $chartUrl = route('chart.account.period', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
$showAll = true; $showAll = true;
Log::debug(sprintf('showAll: Call finalAccountBalance with date/time "%s"', $end->toIso8601String()));
$balances = Steam::filterAccountBalance(Steam::finalAccountBalance($account, $end), $account, $this->convertToNative, $accountCurrency); $balances = Steam::filterAccountBalance(Steam::finalAccountBalance($account, $end), $account, $this->convertToNative, $accountCurrency);
return view( return view(

View File

@@ -109,6 +109,8 @@ class AccountController extends Controller
$accountNames = $this->extractNames($accounts); $accountNames = $this->extractNames($accounts);
// grab all balances // grab all balances
Log::debug(sprintf('expenseAccounts: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s')));
Log::debug(sprintf('expenseAccounts: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s')));
$startBalances = Steam::finalAccountsBalance($accounts, $start); $startBalances = Steam::finalAccountsBalance($accounts, $start);
$endBalances = Steam::finalAccountsBalance($accounts, $end); $endBalances = Steam::finalAccountsBalance($accounts, $end);
@@ -453,6 +455,7 @@ class AccountController extends Controller
// temp, get end balance. // temp, get end balance.
Log::debug('temp get end balance'); Log::debug('temp get end balance');
Log::debug(sprintf('period: Call finalAccountBalance with date/time "%s"', $end->toIso8601String()));
Steam::finalAccountBalance($account, $end); Steam::finalAccountBalance($account, $end);
Log::debug('END temp get end balance done'); Log::debug('END temp get end balance done');
@@ -575,6 +578,8 @@ class AccountController extends Controller
$accountNames = $this->extractNames($accounts); $accountNames = $this->extractNames($accounts);
// grab all balances // grab all balances
Log::debug(sprintf('revAccounts: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s')));
Log::debug(sprintf('revAccounts: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s')));
$startBalances = Steam::finalAccountsBalance($accounts, $start); $startBalances = Steam::finalAccountsBalance($accounts, $start);
$endBalances = Steam::finalAccountsBalance($accounts, $end); $endBalances = Steam::finalAccountsBalance($accounts, $end);

View File

@@ -100,7 +100,10 @@ class ReportController extends Controller
while ($current < $end) { while ($current < $end) {
// get balances by date, grouped by currency. // get balances by date, grouped by currency.
$result = $helper->byAccounts($filtered, $current); $balanceCurrent = clone $current;
$balanceCurrent->subDay()->endOfDay(); // go to correct moment.
Log::debug(sprintf('Call byAccounts("%s")', $balanceCurrent->format('Y-m-d H:i:s')));
$result = $helper->byAccounts($filtered, $balanceCurrent);
// loop result, add to array. // loop result, add to array.
/** @var array $netWorthItem */ /** @var array $netWorthItem */

View File

@@ -195,15 +195,22 @@ class ReconcileController extends Controller
$startDate->subDay(); $startDate->subDay();
$currency = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency; $currency = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency;
Log::debug(sprintf('transactions: Call finalAccountBalance with date/time "%s"', $startDate->toIso8601String()));
Log::debug(sprintf('transactions2: Call finalAccountBalance with date/time "%s"', $end->toIso8601String()));
$startBalance = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places); $startBalance = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places);
$endBalance = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places); $endBalance = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places);
// get the transactions // get the transactions
$selectionStart = clone $start; $selectionStart = clone $start;
$selectionStart->startOfDay();
$selectionStart->subDays(3); $selectionStart->subDays(3);
$selectionEnd = clone $end; $selectionEnd = clone $end;
$selectionEnd->endOfDay();
$selectionEnd->addDays(3); $selectionEnd->addDays(3);
// to make sure the bar is in the right place:
$start->startOfDay();
// grab transactions: // grab transactions:
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);

View File

@@ -0,0 +1,29 @@
<?php
/*
* NotificationsController.php
* Copyright (c) 2025 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Preferences;
use FireflyIII\Http\Controllers\Controller;
class NotificationsController extends Controller {}

View File

@@ -43,6 +43,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Routing\Redirector; use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View; use Illuminate\View\View;
/** /**
@@ -223,7 +224,9 @@ class ConvertController extends Controller
// group accounts: // group accounts:
/** @var Account $account */ /** @var Account $account */
foreach ($accountList as $account) { foreach ($accountList as $account) {
$balance = Steam::finalAccountBalance($account, today()->endOfDay())['balance']; $date = today()->endOfDay();
Log::debug(sprintf('getLiabilities: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$balance = Steam::finalAccountBalance($account, $date)['balance'];
$currency = $this->accountRepository->getAccountCurrency($account) ?? $this->defaultCurrency; $currency = $this->accountRepository->getAccountCurrency($account) ?? $this->defaultCurrency;
$role = 'l_'.$account->accountType->type; $role = 'l_'.$account->accountType->type;
$key = (string) trans('firefly.opt_group_'.$role); $key = (string) trans('firefly.opt_group_'.$role);
@@ -245,7 +248,9 @@ class ConvertController extends Controller
// group accounts: // group accounts:
/** @var Account $account */ /** @var Account $account */
foreach ($accountList as $account) { foreach ($accountList as $account) {
$balance = Steam::finalAccountBalance($account, today()->endOfDay())['balance']; $date = today()->endOfDay();
Log::debug(sprintf('getAssetAccounts: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$balance = Steam::finalAccountBalance($account, $date)['balance'];
$currency = $this->accountRepository->getAccountCurrency($account) ?? $this->defaultCurrency; $currency = $this->accountRepository->getAccountCurrency($account) ?? $this->defaultCurrency;
$role = (string) $this->accountRepository->getMetaValue($account, 'account_role'); $role = (string) $this->accountRepository->getMetaValue($account, 'account_role');
if ('' === $role) { if ('' === $role) {

View File

@@ -29,9 +29,11 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
/** /**
* Class AccountTasker. * Class AccountTasker.
@@ -46,10 +48,13 @@ class AccountTasker implements AccountTaskerInterface
public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array
{ {
$yesterday = clone $start; $yesterday = clone $start;
$yesterday->subDay(); $yesterday->subDay()->endOfDay(); // exactly up until $start but NOT including.
$startSet = app('steam')->finalAccountsBalance($accounts, $yesterday); $end->endOfDay(); // needs to be end of day to be correct.
$endSet = app('steam')->finalAccountsBalance($accounts, $end); Log::debug(sprintf('getAccountReport: finalAccountsBalance("%s")', $yesterday->format('Y-m-d H:i:s')));
app('log')->debug('Start of accountreport'); Log::debug(sprintf('getAccountReport: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s')));
$startSet = Steam::finalAccountsBalance($accounts, $yesterday);
$endSet = Steam::finalAccountsBalance($accounts, $end);
Log::debug('Start of accountreport');
/** @var AccountRepositoryInterface $repository */ /** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class); $repository = app(AccountRepositoryInterface::class);
@@ -90,10 +95,10 @@ class AccountTasker implements AccountTaskerInterface
$entry['end_balance'] = $endSet[$account->id]['balance'] ?? '0'; $entry['end_balance'] = $endSet[$account->id]['balance'] ?? '0';
// first journal exists, and is on start, then this is the actual opening balance: // first journal exists, and is on start, then this is the actual opening balance:
if (null !== $first && $first->date->isSameDay($start) && TransactionTypeEnum::OPENING_BALANCE->value === $first->transactionType->type) { if (null !== $first && $first->date->isSameDay($yesterday) && TransactionTypeEnum::OPENING_BALANCE->value === $first->transactionType->type) {
app('log')->debug(sprintf('Date of first journal for %s is %s', $account->name, $first->date->format('Y-m-d'))); Log::debug(sprintf('Date of first journal for %s is %s', $account->name, $first->date->format('Y-m-d')));
$entry['start_balance'] = $first->transactions()->where('account_id', $account->id)->first()->amount; $entry['start_balance'] = $first->transactions()->where('account_id', $account->id)->first()->amount;
app('log')->debug(sprintf('Account %s was opened on %s, so opening balance is %f', $account->name, $start->format('Y-m-d'), $entry['start_balance'])); Log::debug(sprintf('Account %s was opened on %s, so opening balance is %f', $account->name, $yesterday->format('Y-m-d'), $entry['start_balance']));
} }
$return['sums'][$currency->id]['start'] = bcadd($return['sums'][$currency->id]['start'], $entry['start_balance']); $return['sums'][$currency->id]['start'] = bcadd($return['sums'][$currency->id]['start'], $entry['start_balance']);
$return['sums'][$currency->id]['end'] = bcadd($return['sums'][$currency->id]['end'], $entry['end_balance']); $return['sums'][$currency->id]['end'] = bcadd($return['sums'][$currency->id]['end'], $entry['end_balance']);
@@ -173,7 +178,7 @@ class AccountTasker implements AccountTaskerInterface
]; ];
$report['accounts'][$key]['sum'] = bcadd($report['accounts'][$key]['sum'], $journal['amount']); $report['accounts'][$key]['sum'] = bcadd($report['accounts'][$key]['sum'], $journal['amount']);
app('log')->debug(sprintf('Sum for %s is now %s', $journal['destination_account_name'], $report['accounts'][$key]['sum'])); Log::debug(sprintf('Sum for %s is now %s', $journal['destination_account_name'], $report['accounts'][$key]['sum']));
++$report['accounts'][$key]['count']; ++$report['accounts'][$key]['count'];
} }

View File

@@ -371,6 +371,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
public function leftOnAccount(PiggyBank $piggyBank, Account $account, Carbon $date): string public function leftOnAccount(PiggyBank $piggyBank, Account $account, Carbon $date): string
{ {
Log::debug(sprintf('leftOnAccount("%s","%s","%s")', $piggyBank->name, $account->name, $date->format('Y-m-d H:i:s'))); Log::debug(sprintf('leftOnAccount("%s","%s","%s")', $piggyBank->name, $account->name, $date->format('Y-m-d H:i:s')));
Log::debug(sprintf('leftOnAccount: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$balance = Steam::finalAccountBalance($account, $date)['balance']; $balance = Steam::finalAccountBalance($account, $date)['balance'];
Log::debug(sprintf('Balance is: %s', $balance)); Log::debug(sprintf('Balance is: %s', $balance));

View File

@@ -659,9 +659,10 @@ trait AccountServiceTrait
// submit to factory: // submit to factory:
$submission = [ $submission = [
'group_title' => null, 'group_title' => null,
'user' => $account->user_id, 'user' => $account->user,
'transactions' => [ 'user_group' => $account->user->userGroup,
'transactions' => [
[ [
'type' => 'Opening balance', 'type' => 'Opening balance',
'date' => $openingBalanceDate, 'date' => $openingBalanceDate,
@@ -669,7 +670,8 @@ trait AccountServiceTrait
'source_name' => $sourceName, 'source_name' => $sourceName,
'destination_id' => $destId, 'destination_id' => $destId,
'destination_name' => $destName, 'destination_name' => $destName,
'user' => $account->user_id, 'user' => $account->user,
'user_group' => $account->user->userGroup,
'currency_id' => $currency->id, 'currency_id' => $currency->id,
'order' => 0, 'order' => 0,
'amount' => $amount, 'amount' => $amount,

View File

@@ -203,8 +203,7 @@ class FrontpageChartGenerator
$amount = $limit->native_amount; $amount = $limit->native_amount;
Log::debug(sprintf('Amount is now "%s".', $amount)); Log::debug(sprintf('Amount is now "%s".', $amount));
} }
$amount = null === $amount ? '0' : $amount;
$sumSpent = bcmul($entry['sum'], '-1'); // spent $sumSpent = bcmul($entry['sum'], '-1'); // spent
$data[0]['entries'][$title] ??= '0'; $data[0]['entries'][$title] ??= '0';
$data[1]['entries'][$title] ??= '0'; $data[1]['entries'][$title] ??= '0';

View File

@@ -61,7 +61,7 @@ trait ValidatesUserGroupTrait
$user = auth()->user(); $user = auth()->user();
$groupId = 0; $groupId = 0;
if (!$request->has('user_group_id')) { if (!$request->has('user_group_id')) {
$groupId = $user->user_group_id; $groupId = (int) $user->user_group_id;
Log::debug(sprintf('validateUserGroup: no user group submitted, use default group #%d.', $groupId)); Log::debug(sprintf('validateUserGroup: no user group submitted, use default group #%d.', $groupId));
} }
if ($request->has('user_group_id')) { if ($request->has('user_group_id')) {

View File

@@ -76,6 +76,7 @@ class Steam
$balances = []; $balances = [];
$formatted = $start->format('Y-m-d'); $formatted = $start->format('Y-m-d');
Log::debug(sprintf('finalAccountBalanceInRange: Call finalAccountBalance with date/time "%s"', $start->toIso8601String()));
$startBalance = $this->finalAccountBalance($account, $start); $startBalance = $this->finalAccountBalance($account, $start);
$nativeCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); $nativeCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup);
$accountCurrency = $this->getAccountCurrency($account); $accountCurrency = $this->getAccountCurrency($account);
@@ -164,6 +165,7 @@ class Steam
public function finalAccountsBalance(Collection $accounts, Carbon $date): array public function finalAccountsBalance(Collection $accounts, Carbon $date): array
{ {
Log::debug(sprintf('finalAccountsBalance: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$balances = []; $balances = [];
foreach ($accounts as $account) { foreach ($accounts as $account) {
$balances[$account->id] = $this->finalAccountBalance($account, $date); $balances[$account->id] = $this->finalAccountBalance($account, $date);
@@ -260,6 +262,8 @@ class Steam
} }
/** /**
* Returns smaller than or equal to, so be careful with END OF DAY.
*
* 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: * Always returns:
* "balance": balance in the account's currency OR user's native currency if the account has no currency * "balance": balance in the account's currency OR user's native currency if the account has no currency
@@ -278,7 +282,7 @@ class Steam
$cache->addProperty($date); $cache->addProperty($date);
if ($cache->has()) { if ($cache->has()) {
// Log::debug(sprintf('CACHED finalAccountBalance(#%d, %s)', $account->id, $date->format('Y-m-d H:i:s'))); // Log::debug(sprintf('CACHED finalAccountBalance(#%d, %s)', $account->id, $date->format('Y-m-d H:i:s')));
// return $cache->get(); return $cache->get();
} }
Log::debug(sprintf('finalAccountBalance(#%d, %s)', $account->id, $date->format('Y-m-d H:i:s'))); Log::debug(sprintf('finalAccountBalance(#%d, %s)', $account->id, $date->format('Y-m-d H:i:s')));

View File

@@ -31,6 +31,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Search\OperatorQuerySearch; use FireflyIII\Support\Search\OperatorQuerySearch;
use Illuminate\Support\Facades\Log;
use League\CommonMark\GithubFlavoredMarkdownConverter; use League\CommonMark\GithubFlavoredMarkdownConverter;
use Route; use Route;
use Twig\Extension\AbstractExtension; use Twig\Extension\AbstractExtension;
@@ -67,6 +68,7 @@ class General extends AbstractExtension
/** @var Carbon $date */ /** @var Carbon $date */
$date = session('end', today(config('app.timezone'))->endOfMonth()); $date = session('end', today(config('app.timezone'))->endOfMonth());
Log::debug(sprintf('twig balance: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$info = Steam::finalAccountBalance($account, $date); $info = Steam::finalAccountBalance($account, $date);
$currency = Steam::getAccountCurrency($account); $currency = Steam::getAccountCurrency($account);
$default = Amount::getNativeCurrency(); $default = Amount::getNativeCurrency();

View File

@@ -31,6 +31,7 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Facades\Steam;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\ParameterBag;
/** /**
@@ -106,6 +107,7 @@ class AccountTransformer extends AbstractTransformer
$order = null; $order = null;
} }
// balance, native balance, virtual balance, native virtual balance? // balance, native balance, virtual balance, native virtual balance?
Log::debug(sprintf('transform: Call finalAccountBalance with date/time "%s"', $date->toIso8601String()));
$finalBalance = Steam::finalAccountBalance($account, $date); $finalBalance = Steam::finalAccountBalance($account, $date);
if ($convertToNative) { if ($convertToNative) {
$finalBalance['balance'] = $finalBalance[$currencyCode] ?? '0'; $finalBalance['balance'] = $finalBalance[$currencyCode] ?? '0';

View File

@@ -183,6 +183,8 @@ class AccountTransformer extends AbstractTransformer
$bEnd = []; $bEnd = [];
try { try {
Log::debug(sprintf('v2 transformer: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s')));
Log::debug(sprintf('v2 transformer: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s')));
$bStart = app('steam')->finalAccountsBalance($accounts, $start); $bStart = app('steam')->finalAccountsBalance($accounts, $start);
$bEnd = app('steam')->finalAccountsBalance($accounts, $end); $bEnd = app('steam')->finalAccountsBalance($accounts, $end);
} catch (FireflyException $e) { } catch (FireflyException $e) {

10
composer.lock generated
View File

@@ -11344,16 +11344,16 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "2.1.3", "version": "2.1.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "64ae44e48214f3deebdaeebf2694297a10a2bea9" "reference": "8f99e18eb775dbaf6460c95fa0b65312da9c746a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/64ae44e48214f3deebdaeebf2694297a10a2bea9", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8f99e18eb775dbaf6460c95fa0b65312da9c746a",
"reference": "64ae44e48214f3deebdaeebf2694297a10a2bea9", "reference": "8f99e18eb775dbaf6460c95fa0b65312da9c746a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -11398,7 +11398,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-02-07T15:05:24+00:00" "time": "2025-02-10T08:25:21+00:00"
}, },
{ {
"name": "phpstan/phpstan-deprecation-rules", "name": "phpstan/phpstan-deprecation-rules",

View File

@@ -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' => 'develop/2025-02-10', 'version' => 'develop/2025-02-11',
'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,

18
package-lock.json generated
View File

@@ -4757,9 +4757,9 @@
} }
}, },
"node_modules/compression": { "node_modules/compression": {
"version": "1.7.5", "version": "1.8.0",
"resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz",
"integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -5685,9 +5685,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.96", "version": "1.5.97",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.96.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.97.tgz",
"integrity": "sha512-8AJUW6dh75Fm/ny8+kZKJzI1pgoE8bKLZlzDU2W1ENd+DXKJrx7I7l9hb8UWR4ojlnb5OlixMt00QWiYJoVw1w==", "integrity": "sha512-HKLtaH02augM7ZOdYRuO19rWDeY+QSJ1VxnXFa/XDFLf07HvM90pALIJFgrO+UVaajI3+aJMMpojoUTLZyQ7JQ==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
@@ -8876,9 +8876,9 @@
} }
}, },
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.5.1", "version": "8.5.2",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz",
"integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {

View File

@@ -18,8 +18,8 @@
"is_reconciled": "Is reconciled", "is_reconciled": "Is reconciled",
"split": "Feloszt\u00e1s", "split": "Feloszt\u00e1s",
"single_split": "Feloszt\u00e1s", "single_split": "Feloszt\u00e1s",
"not_enough_currencies": "Not enough currencies", "not_enough_currencies": "Nincs el\u00e9g p\u00e9nznem",
"not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.", "not_enough_currencies_enabled": "Amennyiben csak egyetlen p\u00e9nznem enged\u00e9lyezett, akkor nincs sz\u00fcks\u00e9g \u00e1rfolyam be\u00e1ll\u00edt\u00e1sokra.",
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID} (\"{title}\")<\/a> mentve.", "transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transaction #{ID} (\"{title}\")<\/a> mentve.",
"webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID} (\"{title}\")<\/a> elt\u00e1rolva.", "webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID} (\"{title}\")<\/a> elt\u00e1rolva.",
"webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID}<\/a> (\"{title}\") friss\u00edtve.", "webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID}<\/a> (\"{title}\") friss\u00edtve.",

View File

@@ -182,6 +182,6 @@
}, },
"config": { "config": {
"html_language": "ru", "html_language": "ru",
"date_time_fns": "D MMMM yyyy, @ HH:mm:ss" "date_time_fns": "d MMMM yyyy, @ HH:mm:ss"
} }
} }

View File

@@ -18,8 +18,8 @@
"is_reconciled": "Je usklajena", "is_reconciled": "Je usklajena",
"split": "Razdeli", "split": "Razdeli",
"single_split": "Razdeli", "single_split": "Razdeli",
"not_enough_currencies": "Not enough currencies", "not_enough_currencies": "Ni dovolj valut",
"not_enough_currencies_enabled": "If you have just one currency enabled, there is no need to add exchange rates.", "not_enough_currencies_enabled": "\u010ce imate omogo\u010deno samo eno valuto, menjalnih te\u010dajev ni treba dodajati.",
"transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transakcija \u0161t. #{ID} (\"{title}\")<\/a> je bila shranjena.", "transaction_stored_link": "<a href=\"transactions\/show\/{ID}\">Transakcija \u0161t. #{ID} (\"{title}\")<\/a> je bila shranjena.",
"webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID} (\"{title}\")<\/a> je bil shranjen.", "webhook_stored_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID} (\"{title}\")<\/a> je bil shranjen.",
"webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID}<\/a> (\"{title}\") je bil posodobljen.", "webhook_updated_link": "<a href=\"webhooks\/show\/{ID}\">Webhook #{ID}<\/a> (\"{title}\") je bil posodobljen.",

View File

@@ -6,7 +6,7 @@
"administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.", "administration_currency_form_help": "It may take a long time for the page to load if you change the native currency because transaction may need to be converted to your (new) native currency.",
"administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"", "administrations_page_edit_sub_title_js": "Edit financial administration \"{title}\"",
"table": "\u8868\u683c", "table": "\u8868\u683c",
"welcome_back": "What's playing?", "welcome_back": "\u6b61\u8fce\u56de\u4f86\u7e7c\u7e8c\u7406\u8ca1\uff01",
"flash_error": "\u932f\u8aa4\uff01", "flash_error": "\u932f\u8aa4\uff01",
"flash_warning": "\u8b66\u544a\uff01", "flash_warning": "\u8b66\u544a\uff01",
"flash_success": "\u6210\u529f\uff01", "flash_success": "\u6210\u529f\uff01",