mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-25 13:10:35 +00:00
Auto commit for release 'develop' on 2024-09-28
This commit is contained in:
@@ -68,7 +68,7 @@ class AccountBalanceCalculator
|
||||
public static function recalculateForJournal(TransactionJournal $transactionJournal): void
|
||||
{
|
||||
Log::debug(__METHOD__);
|
||||
$object = new self();
|
||||
$object = new self();
|
||||
|
||||
// recalculate the involved accounts:
|
||||
$accounts = new Collection();
|
||||
@@ -82,34 +82,37 @@ class AccountBalanceCalculator
|
||||
{
|
||||
if (null === $notBefore) {
|
||||
Log::debug('getLatestBalance: no notBefore date, returning 0');
|
||||
|
||||
return '0';
|
||||
}
|
||||
Log::debug(sprintf('getLatestBalance: notBefore date is "%s", calculating', $notBefore->format('Y-m-d')));
|
||||
$query = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->where('transaction_journals.transaction_currency_id', $currencyId)
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
$query = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->where('transaction_journals.transaction_currency_id', $currencyId)
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
// this order is the same as GroupCollector
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->orderBy('transaction_journals.description', 'DESC')
|
||||
->orderBy('transactions.amount', 'DESC')
|
||||
->where('transactions.account_id', $accountId);
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->orderBy('transaction_journals.description', 'DESC')
|
||||
->orderBy('transactions.amount', 'DESC')
|
||||
->where('transactions.account_id', $accountId)
|
||||
;
|
||||
$notBefore->startOfDay();
|
||||
$query->where('transaction_journals.date', '<', $notBefore);
|
||||
|
||||
$first = $query->first(['transactions.id', 'transactions.balance_dirty', 'transactions.transaction_currency_id', 'transaction_journals.date', 'transactions.account_id', 'transactions.amount', 'transactions.balance_after']);
|
||||
$balance = $first->balance_after ?? '0';
|
||||
Log::debug(sprintf('getLatestBalance: found balance: %s in transaction #%d', $balance, $first->id ?? 0));
|
||||
|
||||
return $balance;
|
||||
}
|
||||
|
||||
private function getAccountBalanceByAccount(int $account, int $currency): AccountBalance
|
||||
{
|
||||
$query = AccountBalance::where('title', 'balance')->where('account_id', $account)->where('transaction_currency_id', $currency);
|
||||
$query = AccountBalance::where('title', 'balance')->where('account_id', $account)->where('transaction_currency_id', $currency);
|
||||
|
||||
$entry = $query->first();
|
||||
$entry = $query->first();
|
||||
if (null !== $entry) {
|
||||
// Log::debug(sprintf('Found account balance "balance" for account #%d and currency #%d: %s', $account, $currency, $entry->balance));
|
||||
|
||||
@@ -131,6 +134,7 @@ class AccountBalanceCalculator
|
||||
Log::debug('start of optimizedCalculation');
|
||||
if (false === config('firefly.feature_flags.running_balance_column')) {
|
||||
Log::debug('optimizedCalculation is disabled, return.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -141,14 +145,15 @@ class AccountBalanceCalculator
|
||||
$balances = [];
|
||||
$count = 0;
|
||||
$query = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
// this order is the same as GroupCollector, but in the exact reverse.
|
||||
->orderBy('transaction_journals.date', 'asc')
|
||||
->orderBy('transaction_journals.order', 'desc')
|
||||
->orderBy('transaction_journals.id', 'asc')
|
||||
->orderBy('transaction_journals.description', 'asc')
|
||||
->orderBy('transactions.amount', 'asc');
|
||||
->orderBy('transaction_journals.date', 'asc')
|
||||
->orderBy('transaction_journals.order', 'desc')
|
||||
->orderBy('transaction_journals.id', 'asc')
|
||||
->orderBy('transaction_journals.description', 'asc')
|
||||
->orderBy('transactions.amount', 'asc')
|
||||
;
|
||||
if ($accounts->count() > 0) {
|
||||
$query->whereIn('transactions.account_id', $accounts->pluck('id')->toArray());
|
||||
}
|
||||
@@ -157,7 +162,7 @@ class AccountBalanceCalculator
|
||||
$query->where('transaction_journals.date', '>=', $notBefore);
|
||||
}
|
||||
|
||||
$set = $query->get(['transactions.id', 'transactions.balance_dirty', 'transactions.transaction_currency_id', 'transaction_journals.date', 'transactions.account_id', 'transactions.amount']);
|
||||
$set = $query->get(['transactions.id', 'transactions.balance_dirty', 'transactions.transaction_currency_id', 'transaction_journals.date', 'transactions.account_id', 'transactions.amount']);
|
||||
|
||||
/** @var Transaction $entry */
|
||||
foreach ($set as $entry) {
|
||||
@@ -166,8 +171,8 @@ class AccountBalanceCalculator
|
||||
$balances[$entry->account_id][$entry->transaction_currency_id] ??= $this->getLatestBalance($entry->account_id, $entry->transaction_currency_id, $notBefore);
|
||||
|
||||
// before and after are easy:
|
||||
$before = $balances[$entry->account_id][$entry->transaction_currency_id];
|
||||
$after = bcadd($before, $entry->amount);
|
||||
$before = $balances[$entry->account_id][$entry->transaction_currency_id];
|
||||
$after = bcadd($before, $entry->amount);
|
||||
if (true === $entry->balance_dirty || $accounts->count() > 0) {
|
||||
// update the transaction:
|
||||
$entry->balance_before = $before;
|
||||
@@ -188,9 +193,9 @@ class AccountBalanceCalculator
|
||||
|
||||
private function getAccountBalanceByJournal(string $title, int $account, int $journal, int $currency): AccountBalance
|
||||
{
|
||||
$query = AccountBalance::where('title', $title)->where('account_id', $account)->where('transaction_journal_id', $journal)->where('transaction_currency_id', $currency);
|
||||
$query = AccountBalance::where('title', $title)->where('account_id', $account)->where('transaction_journal_id', $journal)->where('transaction_currency_id', $currency);
|
||||
|
||||
$entry = $query->first();
|
||||
$entry = $query->first();
|
||||
if (null !== $entry) {
|
||||
return $entry;
|
||||
}
|
||||
@@ -207,7 +212,7 @@ class AccountBalanceCalculator
|
||||
|
||||
private function recalculateLatest(?Account $account): void
|
||||
{
|
||||
$query = Transaction::groupBy(['transactions.account_id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id']);
|
||||
$query = Transaction::groupBy(['transactions.account_id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id']);
|
||||
|
||||
if (null !== $account) {
|
||||
$query->where('transactions.account_id', $account->id);
|
||||
@@ -228,11 +233,11 @@ class AccountBalanceCalculator
|
||||
$sumForeignAmount = '' === $sumForeignAmount ? '0' : $sumForeignAmount;
|
||||
|
||||
// at this point SQLite may return scientific notation because why not. Terrible.
|
||||
$sumAmount = app('steam')->floatalize($sumAmount);
|
||||
$sumForeignAmount = app('steam')->floatalize($sumForeignAmount);
|
||||
$sumAmount = app('steam')->floatalize($sumAmount);
|
||||
$sumForeignAmount = app('steam')->floatalize($sumForeignAmount);
|
||||
|
||||
// first create for normal currency:
|
||||
$entry = $this->getAccountBalanceByAccount($account, $transactionCurrency);
|
||||
$entry = $this->getAccountBalanceByAccount($account, $transactionCurrency);
|
||||
|
||||
try {
|
||||
$entry->balance = bcadd((string) $entry->balance, $sumAmount);
|
||||
@@ -287,7 +292,7 @@ class AccountBalanceCalculator
|
||||
*/
|
||||
private function recalculateJournals(?Account $account, ?TransactionJournal $transactionJournal): void
|
||||
{
|
||||
$query = Transaction::groupBy(['transactions.account_id', 'transaction_journals.id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id']);
|
||||
$query = Transaction::groupBy(['transactions.account_id', 'transaction_journals.id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id']);
|
||||
$query->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id');
|
||||
$query->orderBy('transaction_journals.date', 'asc');
|
||||
$amounts = [];
|
||||
@@ -298,28 +303,28 @@ class AccountBalanceCalculator
|
||||
$query->where('transaction_journals.date', '>=', $transactionJournal->date);
|
||||
$amounts = $this->getStartAmounts($account, $transactionJournal);
|
||||
}
|
||||
$result = $query->get(['transactions.account_id', 'transaction_journals.id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id', \DB::raw('SUM(transactions.amount) as sum_amount'), \DB::raw('SUM(transactions.foreign_amount) as sum_foreign_amount')]);
|
||||
$result = $query->get(['transactions.account_id', 'transaction_journals.id', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id', \DB::raw('SUM(transactions.amount) as sum_amount'), \DB::raw('SUM(transactions.foreign_amount) as sum_foreign_amount')]);
|
||||
|
||||
/** @var \stdClass $row */
|
||||
foreach ($result as $row) {
|
||||
$account = (int) $row->account_id;
|
||||
$transactionCurrency = (int) $row->transaction_currency_id;
|
||||
$foreignCurrency = (int) $row->foreign_currency_id;
|
||||
$sumAmount = (string) $row->sum_amount;
|
||||
$sumForeignAmount = (string) $row->sum_foreign_amount;
|
||||
$journalId = (int) $row->id;
|
||||
$account = (int) $row->account_id;
|
||||
$transactionCurrency = (int) $row->transaction_currency_id;
|
||||
$foreignCurrency = (int) $row->foreign_currency_id;
|
||||
$sumAmount = (string) $row->sum_amount;
|
||||
$sumForeignAmount = (string) $row->sum_foreign_amount;
|
||||
$journalId = (int) $row->id;
|
||||
|
||||
// check for empty strings
|
||||
$sumAmount = '' === $sumAmount ? '0' : $sumAmount;
|
||||
$sumForeignAmount = '' === $sumForeignAmount ? '0' : $sumForeignAmount;
|
||||
$sumAmount = '' === $sumAmount ? '0' : $sumAmount;
|
||||
$sumForeignAmount = '' === $sumForeignAmount ? '0' : $sumForeignAmount;
|
||||
|
||||
// new amounts:
|
||||
$amounts[$account][$transactionCurrency] = bcadd($amounts[$account][$transactionCurrency] ?? '0', $sumAmount);
|
||||
$amounts[$account][$foreignCurrency] = bcadd($amounts[$account][$foreignCurrency] ?? '0', $sumForeignAmount);
|
||||
|
||||
// first create for normal currency:
|
||||
$entry = self::getAccountBalanceByJournal('balance_after_journal', $account, $journalId, $transactionCurrency);
|
||||
$entry->balance = $amounts[$account][$transactionCurrency];
|
||||
$entry = self::getAccountBalanceByJournal('balance_after_journal', $account, $journalId, $transactionCurrency);
|
||||
$entry->balance = $amounts[$account][$transactionCurrency];
|
||||
$entry->save();
|
||||
|
||||
// then do foreign amount, if present:
|
||||
|
||||
@@ -72,16 +72,16 @@ class General extends AbstractExtension
|
||||
$info[] = app('steam')->balance($account, $date);
|
||||
}
|
||||
|
||||
$strings = [];
|
||||
$strings = [];
|
||||
foreach ($info as $currencyId => $balance) {
|
||||
if(0 === $currencyId) {
|
||||
if (0 === $currencyId) {
|
||||
// not good code but OK
|
||||
/** @var AccountRepositoryInterface $accountRepos */
|
||||
$accountRepos = app(AccountRepositoryInterface::class);
|
||||
$currency = $accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
|
||||
$strings[] = app('amount')->formatAnything($currency, $balance, false);
|
||||
$strings[] = app('amount')->formatAnything($currency, $balance, false);
|
||||
}
|
||||
if(0 !== $currencyId) {
|
||||
if (0 !== $currencyId) {
|
||||
$strings[] = app('amount')->formatByCurrencyId($currencyId, $balance, false);
|
||||
}
|
||||
}
|
||||
@@ -102,15 +102,15 @@ class General extends AbstractExtension
|
||||
static function (int $size): string {
|
||||
// less than one GB, more than one MB
|
||||
if ($size < (1024 * 1024 * 2014) && $size >= (1024 * 1024)) {
|
||||
return round($size / (1024 * 1024), 2) . ' MB';
|
||||
return round($size / (1024 * 1024), 2).' MB';
|
||||
}
|
||||
|
||||
// less than one MB
|
||||
if ($size < (1024 * 1024)) {
|
||||
return round($size / 1024, 2) . ' KB';
|
||||
return round($size / 1024, 2).' KB';
|
||||
}
|
||||
|
||||
return $size . ' bytes';
|
||||
return $size.' bytes';
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -132,7 +132,7 @@ class General extends AbstractExtension
|
||||
case 'application/pdf':
|
||||
return 'fa-file-pdf-o';
|
||||
|
||||
// image
|
||||
// image
|
||||
case 'image/png':
|
||||
case 'image/jpeg':
|
||||
case 'image/svg+xml':
|
||||
@@ -141,7 +141,7 @@ class General extends AbstractExtension
|
||||
case 'application/vnd.oasis.opendocument.image':
|
||||
return 'fa-file-image-o';
|
||||
|
||||
// MS word
|
||||
// MS word
|
||||
case 'application/msword':
|
||||
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
|
||||
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.template':
|
||||
@@ -157,7 +157,7 @@ class General extends AbstractExtension
|
||||
case 'application/vnd.oasis.opendocument.text-master':
|
||||
return 'fa-file-word-o';
|
||||
|
||||
// MS excel
|
||||
// MS excel
|
||||
case 'application/vnd.ms-excel':
|
||||
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
|
||||
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.template':
|
||||
@@ -168,7 +168,7 @@ class General extends AbstractExtension
|
||||
case 'application/vnd.oasis.opendocument.spreadsheet-template':
|
||||
return 'fa-file-excel-o';
|
||||
|
||||
// MS powerpoint
|
||||
// MS powerpoint
|
||||
case 'application/vnd.ms-powerpoint':
|
||||
case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
|
||||
case 'application/vnd.openxmlformats-officedocument.presentationml.template':
|
||||
@@ -180,7 +180,7 @@ class General extends AbstractExtension
|
||||
case 'application/vnd.oasis.opendocument.presentation-template':
|
||||
return 'fa-file-powerpoint-o';
|
||||
|
||||
// calc
|
||||
// calc
|
||||
case 'application/vnd.sun.xml.draw':
|
||||
case 'application/vnd.sun.xml.draw.template':
|
||||
case 'application/vnd.stardivision.draw':
|
||||
@@ -316,7 +316,7 @@ class General extends AbstractExtension
|
||||
'activeRoutePartialObjectType',
|
||||
static function ($context): string {
|
||||
[, $route, $objectType] = func_get_args();
|
||||
$activeObjectType = $context['objectType'] ?? false;
|
||||
$activeObjectType = $context['objectType'] ?? false;
|
||||
|
||||
if ($objectType === $activeObjectType
|
||||
&& false !== stripos(
|
||||
|
||||
Reference in New Issue
Block a user