mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-29 18:20:01 +00:00
Auto commit for release 'branch-v6.2' on 2024-12-25
This commit is contained in:
@@ -32,7 +32,6 @@ use FireflyIII\Enums\TransactionTypeEnum;
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Helpers\Report\NetWorthInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
|
||||
@@ -104,10 +103,10 @@ class BasicController extends Controller
|
||||
$billData = $this->getBillInformation($start, $end);
|
||||
$spentData = $this->getLeftToSpendInfo($start, $end);
|
||||
$netWorthData = $this->getNetWorthInfo($start, $end);
|
||||
// $balanceData = [];
|
||||
// $billData = [];
|
||||
// $spentData = [];
|
||||
// $netWorthData = [];
|
||||
// $balanceData = [];
|
||||
// $billData = [];
|
||||
// $spentData = [];
|
||||
// $netWorthData = [];
|
||||
$total = array_merge($balanceData, $billData, $spentData, $netWorthData);
|
||||
|
||||
// give new keys
|
||||
@@ -186,8 +185,8 @@ class BasicController extends Controller
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'value_parsed' => app('amount')->formatAnything($currency, $sums[$currencyId] ?? '0', false),
|
||||
'local_icon' => 'balance-scale',
|
||||
'sub_title' => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false) .
|
||||
' + ' . app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false),
|
||||
'sub_title' => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false).
|
||||
' + '.app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false),
|
||||
];
|
||||
$return[] = [
|
||||
'key' => sprintf('spent-in-%s', $currency->code),
|
||||
@@ -323,6 +322,7 @@ class BasicController extends Controller
|
||||
private function getNetWorthInfo(Carbon $start, Carbon $end): array
|
||||
{
|
||||
Log::debug('getNetWorthInfo');
|
||||
|
||||
/** @var User $user */
|
||||
$user = auth()->user();
|
||||
$date = now(config('app.timezone'));
|
||||
|
@@ -212,10 +212,10 @@ class RecalculateNativeAmounts extends Command
|
||||
->join('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.user_group_id', $userGroup->id)
|
||||
|
||||
->where(function(DatabaseBuilder $q1) use ($currency) {
|
||||
$q1->where(function(DatabaseBuilder $q2) use ($currency) {
|
||||
->where(function (DatabaseBuilder $q1) use ($currency): void {
|
||||
$q1->where(function (DatabaseBuilder $q2) use ($currency): void {
|
||||
$q2->whereNot('transactions.transaction_currency_id', $currency->id)->whereNull('transactions.foreign_currency_id');
|
||||
})->orWhere(function(DatabaseBuilder $q3) use ($currency) {
|
||||
})->orWhere(function (DatabaseBuilder $q3) use ($currency): void {
|
||||
$q3->whereNot('transactions.transaction_currency_id', $currency->id)->whereNot('transactions.foreign_currency_id', $currency->id);
|
||||
});
|
||||
})
|
||||
|
@@ -117,7 +117,7 @@ class NetWorth implements NetWorthInterface
|
||||
return $netWorth;
|
||||
}
|
||||
|
||||
private function getRepository(): AccountRepositoryInterface | AdminAccountRepositoryInterface
|
||||
private function getRepository(): AccountRepositoryInterface|AdminAccountRepositoryInterface
|
||||
{
|
||||
if (null === $this->userGroup) {
|
||||
return $this->accountRepository;
|
||||
@@ -126,7 +126,7 @@ class NetWorth implements NetWorthInterface
|
||||
return $this->adminAccountRepository;
|
||||
}
|
||||
|
||||
public function setUser(null | Authenticatable | User $user): void
|
||||
public function setUser(null|Authenticatable|User $user): void
|
||||
{
|
||||
if (!$user instanceof User) {
|
||||
return;
|
||||
|
@@ -194,7 +194,7 @@ class IndexController extends Controller
|
||||
return view('accounts.index', compact('objectType', 'inactiveCount', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
|
||||
}
|
||||
|
||||
private function getBalance(Account $account, ?TransactionCurrency $currency = null, array $balances): array
|
||||
private function getBalance(Account $account, ?TransactionCurrency $currency, array $balances): array
|
||||
{
|
||||
if (!array_key_exists($account->id, $balances)) {
|
||||
return [];
|
||||
@@ -217,6 +217,7 @@ class IndexController extends Controller
|
||||
foreach ($endBalances as $key => $value) {
|
||||
$result[$key] = bcsub($value, $startBalances[$key] ?? '0');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@@ -84,6 +84,7 @@ class AccountController extends Controller
|
||||
public function expenseAccounts(): JsonResponse
|
||||
{
|
||||
Log::debug('RevenueAccounts');
|
||||
|
||||
/** @var Carbon $start */
|
||||
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
|
||||
|
||||
@@ -114,28 +115,32 @@ class AccountController extends Controller
|
||||
$endBalances = app('steam')->finalAccountsBalance($accounts, $end);
|
||||
|
||||
// loop the accounts, then check for balance and currency info.
|
||||
foreach($accounts as $account) {
|
||||
foreach ($accounts as $account) {
|
||||
Log::debug(sprintf('Now in account #%d ("%s")', $account->id, $account->name));
|
||||
$expenses = $endBalances[$account->id] ?? false;
|
||||
if(false === $expenses) {
|
||||
Log::error(sprintf('Found no end balance for account #%d',$account->id));
|
||||
if (false === $expenses) {
|
||||
Log::error(sprintf('Found no end balance for account #%d', $account->id));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var string $key
|
||||
* @var string $endBalance
|
||||
*/
|
||||
foreach ($expenses as $key => $endBalance) {
|
||||
if(!$this->convertToNative && 'native_balance' === $key) {
|
||||
if (!$this->convertToNative && 'native_balance' === $key) {
|
||||
Log::debug(sprintf('[a] Will skip expense array "%s"', $key));
|
||||
|
||||
continue;
|
||||
}
|
||||
if($this->convertToNative && 'native_balance' !== $key) {
|
||||
if ($this->convertToNative && 'native_balance' !== $key) {
|
||||
Log::debug(sprintf('[b] Will skip expense array "%s"', $key));
|
||||
|
||||
continue;
|
||||
}
|
||||
Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
|
||||
$searchCode = $this->convertToNative ? $default->code: $key;
|
||||
$searchCode = $this->convertToNative ? $default->code : $key;
|
||||
Log::debug(sprintf('Search code is %s', $searchCode));
|
||||
// see if there is an accompanying start amount.
|
||||
// grab the difference and find the currency.
|
||||
@@ -541,29 +546,33 @@ class AccountController extends Controller
|
||||
$endBalances = app('steam')->finalAccountsBalance($accounts, $end);
|
||||
|
||||
|
||||
// loop the accounts, then check for balance and currency info.
|
||||
foreach($accounts as $account) {
|
||||
// loop the accounts, then check for balance and currency info.
|
||||
foreach ($accounts as $account) {
|
||||
Log::debug(sprintf('Now in account #%d ("%s")', $account->id, $account->name));
|
||||
$expenses = $endBalances[$account->id] ?? false;
|
||||
if(false === $expenses) {
|
||||
Log::error(sprintf('Found no end balance for account #%d',$account->id));
|
||||
if (false === $expenses) {
|
||||
Log::error(sprintf('Found no end balance for account #%d', $account->id));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var string $key
|
||||
* @var string $endBalance
|
||||
*/
|
||||
foreach ($expenses as $key => $endBalance) {
|
||||
if(!$this->convertToNative && 'native_balance' === $key) {
|
||||
if (!$this->convertToNative && 'native_balance' === $key) {
|
||||
Log::debug(sprintf('[a] Will skip expense array "%s"', $key));
|
||||
|
||||
continue;
|
||||
}
|
||||
if($this->convertToNative && 'native_balance' !== $key) {
|
||||
if ($this->convertToNative && 'native_balance' !== $key) {
|
||||
Log::debug(sprintf('[b] Will skip expense array "%s"', $key));
|
||||
|
||||
continue;
|
||||
}
|
||||
Log::debug(sprintf('Will process expense array "%s" with amount %s', $key, $endBalance));
|
||||
$searchCode = $this->convertToNative ? $default->code: $key;
|
||||
$searchCode = $this->convertToNative ? $default->code : $key;
|
||||
Log::debug(sprintf('Search code is %s', $searchCode));
|
||||
// see if there is an accompanying start amount.
|
||||
// grab the difference and find the currency.
|
||||
|
@@ -387,7 +387,7 @@ class BudgetController extends Controller
|
||||
if ($cache->has()) {
|
||||
// return response()->json($cache->get());
|
||||
}
|
||||
Log::debug(sprintf('Regenerate frontpage chart from scratch.'));
|
||||
Log::debug('Regenerate frontpage chart from scratch.');
|
||||
$chartGenerator = app(FrontpageChartGenerator::class);
|
||||
$chartGenerator->setUser(auth()->user());
|
||||
$chartGenerator->setStart($start);
|
||||
|
@@ -33,7 +33,6 @@ use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Support\Http\Controllers\GetConfigurationData;
|
||||
use FireflyIII\Support\Models\AccountBalanceCalculator;
|
||||
use FireflyIII\User;
|
||||
use Http\Discovery\Exception\NotFoundException;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -63,35 +62,38 @@ class DebugController extends Controller
|
||||
|
||||
public function routes(): never
|
||||
{
|
||||
if(!auth()->user()->hasRole('owner')) {
|
||||
if (!auth()->user()->hasRole('owner')) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
$routes = Route::getRoutes();
|
||||
$return = [];
|
||||
|
||||
/** @var \Illuminate\Routing\Route $route */
|
||||
foreach ($routes as $route) {
|
||||
// skip API and other routes.
|
||||
if (
|
||||
str_starts_with($route->uri(), 'api') ||
|
||||
str_starts_with($route->uri(), '_debugbar') ||
|
||||
str_starts_with($route->uri(), '_ignition') ||
|
||||
str_starts_with($route->uri(), 'oauth') ||
|
||||
str_starts_with($route->uri(), 'sanctum')
|
||||
str_starts_with($route->uri(), 'api')
|
||||
|| str_starts_with($route->uri(), '_debugbar')
|
||||
|| str_starts_with($route->uri(), '_ignition')
|
||||
|| str_starts_with($route->uri(), 'oauth')
|
||||
|| str_starts_with($route->uri(), 'sanctum')
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
// skip non GET routes
|
||||
if (!in_array('GET', $route->methods())) {
|
||||
if (!in_array('GET', $route->methods(), true)) {
|
||||
continue;
|
||||
}
|
||||
// no name route:
|
||||
if (null === $route->getName()) {
|
||||
var_dump($route);
|
||||
|
||||
exit;
|
||||
}
|
||||
if (!str_contains($route->uri(), '{')) {
|
||||
|
||||
$return[$route->getName()] = route($route->getName());
|
||||
|
||||
continue;
|
||||
}
|
||||
$params = [];
|
||||
@@ -104,14 +106,15 @@ class DebugController extends Controller
|
||||
echo '<hr>';
|
||||
echo '<h1>Routes</h1>';
|
||||
echo sprintf('<h2>%s</h2>', $count);
|
||||
foreach($return as $name => $path) {
|
||||
echo sprintf('<a href="%1$s">%2$s</a><br>', $path, $name) . PHP_EOL;
|
||||
$count++;
|
||||
if(0 === $count % 10) {
|
||||
foreach ($return as $name => $path) {
|
||||
echo sprintf('<a href="%1$s">%2$s</a><br>', $path, $name).PHP_EOL;
|
||||
++$count;
|
||||
if (0 === $count % 10) {
|
||||
echo '<hr>';
|
||||
echo sprintf('<h2>%s</h2>', $count);
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
var_dump($return);
|
||||
}
|
||||
@@ -195,7 +198,7 @@ class DebugController extends Controller
|
||||
}
|
||||
if ('' !== $logContent) {
|
||||
// last few lines
|
||||
$logContent = 'Truncated from this point <----|' . substr((string) $logContent, -16384);
|
||||
$logContent = 'Truncated from this point <----|'.substr((string) $logContent, -16384);
|
||||
}
|
||||
|
||||
return view('debug', compact('table', 'now', 'logContent'));
|
||||
@@ -407,81 +410,118 @@ class DebugController extends Controller
|
||||
switch ($name) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Unknown parameter "%s"', $name));
|
||||
|
||||
case 'cliToken':
|
||||
case 'token':
|
||||
case 'code':
|
||||
case 'oldAddressHash':
|
||||
return 'fake-token';
|
||||
|
||||
case 'objectType':
|
||||
return 'asset';
|
||||
|
||||
case 'account':
|
||||
return '1';
|
||||
|
||||
case 'start_date':
|
||||
return '20241201';
|
||||
|
||||
case 'end_date':
|
||||
return '20241231';
|
||||
|
||||
case 'attachment':
|
||||
return '1';
|
||||
|
||||
case 'bill':
|
||||
return '1';
|
||||
|
||||
case 'budget':
|
||||
return '1';
|
||||
|
||||
case 'budgetLimit':
|
||||
return '1';
|
||||
|
||||
case 'category':
|
||||
return '1';
|
||||
|
||||
case 'currency':
|
||||
return '1';
|
||||
|
||||
case 'fromCurrencyCode':
|
||||
return 'EUR';
|
||||
|
||||
case 'toCurrencyCode':
|
||||
return 'USD';
|
||||
|
||||
case 'accountList':
|
||||
return '1,6';
|
||||
|
||||
case 'budgetList':
|
||||
return '1,2';
|
||||
|
||||
case 'categoryList':
|
||||
return '1,2';
|
||||
|
||||
case 'doubleList':
|
||||
return '1,2';
|
||||
|
||||
case 'tagList':
|
||||
return '1,2';
|
||||
|
||||
case 'tag':
|
||||
return '1';
|
||||
|
||||
case 'piggyBank':
|
||||
return '1';
|
||||
|
||||
case 'objectGroup':
|
||||
return '1';
|
||||
|
||||
case 'route':
|
||||
return 'accounts';
|
||||
|
||||
case 'specificPage':
|
||||
return 'show';
|
||||
|
||||
case 'recurrence':
|
||||
return '1';
|
||||
|
||||
case 'tj':
|
||||
return '1';
|
||||
|
||||
case 'reportType':
|
||||
return 'default';
|
||||
|
||||
case 'ruleGroup':
|
||||
return '1';
|
||||
|
||||
case 'rule':
|
||||
return '1';
|
||||
|
||||
case 'tagOrId':
|
||||
return '1';
|
||||
|
||||
case 'transactionGroup':
|
||||
return '1';
|
||||
|
||||
case 'journalList':
|
||||
return '1,2';
|
||||
|
||||
case 'transactionType':
|
||||
return 'withdrawal';
|
||||
|
||||
case 'journalLink':
|
||||
return '1';
|
||||
|
||||
case 'webhook':
|
||||
return '1';
|
||||
|
||||
case 'user':
|
||||
return '1';
|
||||
|
||||
case 'linkType':
|
||||
return '1';
|
||||
|
||||
case 'userGroup':
|
||||
return '1';
|
||||
|
||||
|
@@ -85,7 +85,8 @@ class BoxController extends Controller
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setRange($start, $end)
|
||||
->setTypes([TransactionType::DEPOSIT]);
|
||||
->setTypes([TransactionType::DEPOSIT])
|
||||
;
|
||||
$set = $collector->getExtractedJournals();
|
||||
|
||||
/** @var array $journal */
|
||||
@@ -102,7 +103,8 @@ class BoxController extends Controller
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setRange($start, $end)
|
||||
->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
->setTypes([TransactionTypeEnum::WITHDRAWAL->value])
|
||||
;
|
||||
$set = $collector->getExtractedJournals();
|
||||
|
||||
/** @var array $journal */
|
||||
|
@@ -61,7 +61,7 @@ class Account extends Model
|
||||
'virtual_balance' => 'string',
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'user_group_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban','native_virtual_balance'];
|
||||
protected $fillable = ['user_id', 'user_group_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban', 'native_virtual_balance'];
|
||||
|
||||
protected $hidden = ['encrypted'];
|
||||
private bool $joinedAccountTypes = false;
|
||||
|
@@ -57,7 +57,7 @@ class BudgetLimit extends Model
|
||||
'deleted' => Deleted::class,
|
||||
];
|
||||
|
||||
protected $fillable = ['budget_id', 'start_date', 'end_date', 'start_date_tz', 'end_date_tz', 'amount', 'transaction_currency_id','native_amount'];
|
||||
protected $fillable = ['budget_id', 'start_date', 'end_date', 'start_date_tz', 'end_date_tz', 'amount', 'transaction_currency_id', 'native_amount'];
|
||||
|
||||
/**
|
||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||
|
@@ -61,7 +61,8 @@ class BillRepository implements BillRepositoryInterface
|
||||
$search->whereLike('name', sprintf('%%%s', $query));
|
||||
}
|
||||
$search->orderBy('name', 'ASC')
|
||||
->where('active', true);
|
||||
->where('active', true)
|
||||
;
|
||||
|
||||
return $search->take($limit)->get();
|
||||
}
|
||||
@@ -73,7 +74,8 @@ class BillRepository implements BillRepositoryInterface
|
||||
$search->whereLike('name', sprintf('%s%%', $query));
|
||||
}
|
||||
$search->orderBy('name', 'ASC')
|
||||
->where('active', true);
|
||||
->where('active', true)
|
||||
;
|
||||
|
||||
return $search->take($limit)->get();
|
||||
}
|
||||
@@ -177,7 +179,8 @@ class BillRepository implements BillRepositoryInterface
|
||||
return $this->user->bills()
|
||||
->orderBy('order', 'ASC')
|
||||
->orderBy('active', 'DESC')
|
||||
->orderBy('name', 'ASC')->get();
|
||||
->orderBy('name', 'ASC')->get()
|
||||
;
|
||||
}
|
||||
|
||||
public function getBillsForAccounts(Collection $accounts): Collection
|
||||
@@ -218,7 +221,8 @@ class BillRepository implements BillRepositoryInterface
|
||||
->orderBy('bills.active', 'DESC')
|
||||
->orderBy('bills.name', 'ASC')
|
||||
->groupBy($fields)
|
||||
->get($fields);
|
||||
->get($fields)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,7 +285,7 @@ class BillRepository implements BillRepositoryInterface
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function setUser(null | Authenticatable | User $user): void
|
||||
public function setUser(null|Authenticatable|User $user): void
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
@@ -292,7 +296,8 @@ class BillRepository implements BillRepositoryInterface
|
||||
{
|
||||
return $this->user->bills()
|
||||
->orderBy('active', 'DESC')
|
||||
->orderBy('name', 'ASC')->paginate($size);
|
||||
->orderBy('name', 'ASC')->paginate($size)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,7 +316,8 @@ class BillRepository implements BillRepositoryInterface
|
||||
'transaction_journals.date',
|
||||
'transaction_journals.transaction_group_id',
|
||||
]
|
||||
);
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,7 +329,8 @@ class BillRepository implements BillRepositoryInterface
|
||||
->leftJoin('rule_actions', 'rule_actions.rule_id', '=', 'rules.id')
|
||||
->where('rule_actions.action_type', 'link_to_bill')
|
||||
->where('rule_actions.action_value', $bill->name)
|
||||
->get(['rules.*']);
|
||||
->get(['rules.*'])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,7 +344,8 @@ class BillRepository implements BillRepositoryInterface
|
||||
$rules = $this->user->rules()
|
||||
->leftJoin('rule_actions', 'rule_actions.rule_id', '=', 'rules.id')
|
||||
->where('rule_actions.action_type', 'link_to_bill')
|
||||
->get(['rules.id', 'rules.title', 'rule_actions.action_value', 'rules.active']);
|
||||
->get(['rules.id', 'rules.title', 'rule_actions.action_value', 'rules.active'])
|
||||
;
|
||||
$array = [];
|
||||
|
||||
/** @var Rule $rule */
|
||||
@@ -363,9 +371,10 @@ class BillRepository implements BillRepositoryInterface
|
||||
$result = [];
|
||||
|
||||
$journals = $bill->transactionJournals()
|
||||
->where('date', '>=', $date->year . '-01-01 00:00:00')
|
||||
->where('date', '<=', $date->year . '-12-31 23:59:59')
|
||||
->get();
|
||||
->where('date', '>=', $date->year.'-01-01 00:00:00')
|
||||
->where('date', '<=', $date->year.'-12-31 23:59:59')
|
||||
->get()
|
||||
;
|
||||
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
@@ -430,12 +439,12 @@ class BillRepository implements BillRepositoryInterface
|
||||
// find the most recent date for this bill NOT in the future. Cache this date:
|
||||
$start = clone $bill->date;
|
||||
$start->startOfDay();
|
||||
app('log')->debug('nextExpectedMatch: Start is ' . $start->format('Y-m-d'));
|
||||
app('log')->debug('nextExpectedMatch: Start is '.$start->format('Y-m-d'));
|
||||
|
||||
while ($start < $date) {
|
||||
app('log')->debug(sprintf('$start (%s) < $date (%s)', $start->format('Y-m-d H:i:s'), $date->format('Y-m-d H:i:s')));
|
||||
$start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
|
||||
app('log')->debug('Start is now ' . $start->format('Y-m-d H:i:s'));
|
||||
app('log')->debug('Start is now '.$start->format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
$end = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
|
||||
@@ -450,8 +459,8 @@ class BillRepository implements BillRepositoryInterface
|
||||
$start = clone $end;
|
||||
$end = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
|
||||
}
|
||||
app('log')->debug('nextExpectedMatch: Final start is ' . $start->format('Y-m-d'));
|
||||
app('log')->debug('nextExpectedMatch: Matching end is ' . $end->format('Y-m-d'));
|
||||
app('log')->debug('nextExpectedMatch: Final start is '.$start->format('Y-m-d'));
|
||||
app('log')->debug('nextExpectedMatch: Matching end is '.$end->format('Y-m-d'));
|
||||
|
||||
$cache->store($start);
|
||||
|
||||
@@ -523,6 +532,7 @@ class BillRepository implements BillRepositoryInterface
|
||||
'sum' => '0',
|
||||
];
|
||||
$setAmount = '0';
|
||||
|
||||
/** @var TransactionJournal $transactionJournal */
|
||||
foreach ($set as $transactionJournal) {
|
||||
$setAmount = bcadd($setAmount, Amount::getAmountFromJournalObject($transactionJournal));
|
||||
@@ -563,11 +573,11 @@ class BillRepository implements BillRepositoryInterface
|
||||
|
||||
$minField = $convertToNative && $bill->transactionCurrency->id !== $default->id ? 'native_amount_min' : 'amount_min';
|
||||
$maxField = $convertToNative && $bill->transactionCurrency->id !== $default->id ? 'native_amount_max' : 'amount_max';
|
||||
//Log::debug(sprintf('min field is %s, max field is %s', $minField, $maxField));
|
||||
// Log::debug(sprintf('min field is %s, max field is %s', $minField, $maxField));
|
||||
|
||||
if ($total > 0) {
|
||||
$currency = $convertToNative && $bill->transactionCurrency->id !== $default->id ? $default : $bill->transactionCurrency;
|
||||
$average = bcdiv(bcadd($bill->$maxField, $bill->$minField), '2');
|
||||
$average = bcdiv(bcadd($bill->{$maxField}, $bill->{$minField}), '2');
|
||||
Log::debug(sprintf('Amount to pay is %s %s (%d times)', $currency->code, $average, $total));
|
||||
$return[$currency->id] ??= [
|
||||
'id' => (string) $currency->id,
|
||||
|
@@ -104,7 +104,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
||||
->where('transaction_currency_id', $currency->id)
|
||||
->where('start_date', $start->format('Y-m-d'))
|
||||
->where('end_date', $end->format('Y-m-d'))
|
||||
->first();
|
||||
->first()
|
||||
;
|
||||
}
|
||||
|
||||
public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string
|
||||
@@ -115,7 +116,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
||||
$availableBudget = $this->user->availableBudgets()
|
||||
->where('transaction_currency_id', $currency->id)
|
||||
->where('start_date', $start->format('Y-m-d'))
|
||||
->where('end_date', $end->format('Y-m-d'))->first();
|
||||
->where('end_date', $end->format('Y-m-d'))->first()
|
||||
;
|
||||
if (null !== $availableBudget) {
|
||||
$amount = $availableBudget->amount;
|
||||
}
|
||||
@@ -128,7 +130,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
||||
$return = [];
|
||||
$availableBudgets = $this->user->availableBudgets()
|
||||
->where('start_date', $start->format('Y-m-d'))
|
||||
->where('end_date', $end->format('Y-m-d'))->get();
|
||||
->where('end_date', $end->format('Y-m-d'))->get()
|
||||
;
|
||||
|
||||
// use native amount if necessary?
|
||||
$convertToNative = app('preferences')->getForUser($this->user, 'convert_to_native', false)->data;
|
||||
@@ -138,9 +141,10 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
||||
foreach ($availableBudgets as $availableBudget) {
|
||||
$currencyId = $convertToNative && $availableBudget->transaction_currency_id !== $default->id ? $default->id : $availableBudget->transaction_currency_id;
|
||||
$field = $convertToNative && $availableBudget->transaction_currency_id !== $default->id ? 'native_amount' : 'amount';
|
||||
$return[$currencyId] = $return[$currencyId] ?? '0';
|
||||
$return[$currencyId] = bcadd($return[$currencyId], $availableBudget->$field);
|
||||
$return[$currencyId] ??= '0';
|
||||
$return[$currencyId] = bcadd($return[$currencyId], $availableBudget->{$field});
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -177,7 +181,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
||||
return $this->user->availableBudgets()
|
||||
->where('start_date', '=', $start->format('Y-m-d'))
|
||||
->where('end_date', '=', $end->format('Y-m-d'))
|
||||
->get();
|
||||
->get()
|
||||
;
|
||||
}
|
||||
|
||||
public function getByCurrencyDate(Carbon $start, Carbon $end, TransactionCurrency $currency): ?AvailableBudget
|
||||
@@ -186,7 +191,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
||||
->availableBudgets()
|
||||
->where('transaction_currency_id', $currency->id)
|
||||
->where('start_date', $start->format('Y-m-d'))
|
||||
->where('end_date', $end->format('Y-m-d'))->first();
|
||||
->where('end_date', $end->format('Y-m-d'))->first()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,7 +203,8 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
||||
$availableBudget = $this->user->availableBudgets()
|
||||
->where('transaction_currency_id', $currency->id)
|
||||
->where('start_date', $start->format('Y-m-d'))
|
||||
->where('end_date', $end->format('Y-m-d'))->first();
|
||||
->where('end_date', $end->format('Y-m-d'))->first()
|
||||
;
|
||||
if (null === $availableBudget) {
|
||||
$availableBudget = new AvailableBudget();
|
||||
$availableBudget->user()->associate($this->user);
|
||||
@@ -213,7 +220,7 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
|
||||
return $availableBudget;
|
||||
}
|
||||
|
||||
public function setUser(null | Authenticatable | User $user): void
|
||||
public function setUser(null|Authenticatable|User $user): void
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
|
@@ -186,7 +186,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function setUser(null | Authenticatable | User $user): void
|
||||
public function setUser(null|Authenticatable|User $user): void
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
@@ -210,8 +210,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
?Collection $accounts = null,
|
||||
?Collection $budgets = null,
|
||||
?TransactionCurrency $currency = null
|
||||
): array
|
||||
{
|
||||
): array {
|
||||
Log::debug('Start of sumExpenses.');
|
||||
// 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.
|
||||
@@ -240,7 +239,8 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
$collector->setUser($this->user)
|
||||
->setRange($start, $end)
|
||||
// ->excludeDestinationAccounts($selection)
|
||||
->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
->setTypes([TransactionTypeEnum::WITHDRAWAL->value])
|
||||
;
|
||||
|
||||
if (null !== $accounts) {
|
||||
$collector->setAccounts($accounts);
|
||||
@@ -259,29 +259,29 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
if (null !== $currency) {
|
||||
Log::debug('STOP looking for transactions in the foreign currency.');
|
||||
|
||||
// Log::debug(sprintf('Look for transactions with foreign currency %s', $currency->code));
|
||||
// // app('log')->debug(sprintf('Currency is "%s".', $currency->name));
|
||||
// /** @var GroupCollectorInterface $collector */
|
||||
// $collector = app(GroupCollectorInterface::class);
|
||||
// $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setForeignCurrency($currency)->setBudgets($budgets);
|
||||
//
|
||||
// if (null !== $accounts) {
|
||||
// $collector->setAccounts($accounts);
|
||||
// }
|
||||
// $result = $collector->getExtractedJournals();
|
||||
// // app('log')->debug(sprintf('Found %d journals with currency %s.', count($result), $currency->code));
|
||||
// // do not use array_merge because you want keys to overwrite (otherwise you get double results):
|
||||
// Log::debug(sprintf('Found %d extra journals in foreign currency.', count($result)));
|
||||
// $journals = $result + $journals;
|
||||
// Log::debug(sprintf('Look for transactions with foreign currency %s', $currency->code));
|
||||
// // app('log')->debug(sprintf('Currency is "%s".', $currency->name));
|
||||
// /** @var GroupCollectorInterface $collector */
|
||||
// $collector = app(GroupCollectorInterface::class);
|
||||
// $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setForeignCurrency($currency)->setBudgets($budgets);
|
||||
//
|
||||
// if (null !== $accounts) {
|
||||
// $collector->setAccounts($accounts);
|
||||
// }
|
||||
// $result = $collector->getExtractedJournals();
|
||||
// // app('log')->debug(sprintf('Found %d journals with currency %s.', count($result), $currency->code));
|
||||
// // do not use array_merge because you want keys to overwrite (otherwise you get double results):
|
||||
// Log::debug(sprintf('Found %d extra journals in foreign currency.', count($result)));
|
||||
// $journals = $result + $journals;
|
||||
}
|
||||
$array = [];
|
||||
|
||||
foreach ($journals as $journal) {
|
||||
// Log::debug(sprintf('Journal #%d.', $journal['transaction_journal_id']));
|
||||
// Log::debug(sprintf('Amounts: %1$s %2$s (amount), %3$s %4$s (foreign_amount), %5$s %6$s (native_amount) %5$s %7$s (foreign native amount)',
|
||||
// $journal['currency_code'], $journal['amount'], $journal['foreign_currency_code'], $journal['foreign_amount'],
|
||||
// $default->code, $journal['native_amount'], $journal['native_foreign_amount'])
|
||||
// );
|
||||
// Log::debug(sprintf('Journal #%d.', $journal['transaction_journal_id']));
|
||||
// Log::debug(sprintf('Amounts: %1$s %2$s (amount), %3$s %4$s (foreign_amount), %5$s %6$s (native_amount) %5$s %7$s (foreign native amount)',
|
||||
// $journal['currency_code'], $journal['amount'], $journal['foreign_currency_code'], $journal['foreign_amount'],
|
||||
// $default->code, $journal['native_amount'], $journal['native_foreign_amount'])
|
||||
// );
|
||||
// TODO same as in category::sumexpenses
|
||||
$amount = '0';
|
||||
$currencyId = (int) $journal['currency_id'];
|
||||
@@ -292,7 +292,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
if ($convertToNative) {
|
||||
$useNative = $default->id !== (int) $journal['currency_id'];
|
||||
$amount = Amount::getAmountFromJournal($journal);
|
||||
if($useNative) {
|
||||
if ($useNative) {
|
||||
Log::debug(sprintf('Journal #%d switches to native amount (original is %s)', $journal['transaction_journal_id'], $journal['currency_code']));
|
||||
$currencyId = $default->id;
|
||||
$currencyName = $default->name;
|
||||
@@ -327,6 +327,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
Log::debug(sprintf('Journal #%d adds amount %s %s', $journal['transaction_journal_id'], $currencyCode, $amount));
|
||||
}
|
||||
Log::debug('End of sumExpenses.', $array);
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
@@ -112,7 +112,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function setUser(null | Authenticatable | User $user): void
|
||||
public function setUser(null|Authenticatable|User $user): void
|
||||
{
|
||||
if ($user instanceof User) {
|
||||
$this->user = $user;
|
||||
@@ -200,7 +200,8 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::TRANSFER])
|
||||
->setDestinationAccounts($accounts)->excludeSourceAccounts($accounts);
|
||||
->setDestinationAccounts($accounts)->excludeSourceAccounts($accounts)
|
||||
;
|
||||
if (null !== $categories && $categories->count() > 0) {
|
||||
$collector->setCategories($categories);
|
||||
}
|
||||
@@ -262,7 +263,8 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::TRANSFER])
|
||||
->setSourceAccounts($accounts)->excludeDestinationAccounts($accounts);
|
||||
->setSourceAccounts($accounts)->excludeDestinationAccounts($accounts)
|
||||
;
|
||||
if (null !== $categories && $categories->count() > 0) {
|
||||
$collector->setCategories($categories);
|
||||
}
|
||||
@@ -393,7 +395,8 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)->setRange($start, $end)
|
||||
->setTypes([TransactionType::DEPOSIT]);
|
||||
->setTypes([TransactionType::DEPOSIT])
|
||||
;
|
||||
|
||||
if (null !== $accounts && $accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
@@ -429,7 +432,8 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setUser($this->user)->setRange($start, $end)
|
||||
->setTypes([TransactionType::TRANSFER]);
|
||||
->setTypes([TransactionType::TRANSFER])
|
||||
;
|
||||
|
||||
if (null !== $accounts && $accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
|
@@ -58,12 +58,13 @@ class Amount
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
$field = $convertToNative && $currency->id !== $journal['currency_id'] ? 'native_amount' : 'amount';
|
||||
$amount = $journal[$field] ?? '0';
|
||||
//Log::debug(sprintf('Field is %s, amount is %s', $field, $amount));
|
||||
// Log::debug(sprintf('Field is %s, amount is %s', $field, $amount));
|
||||
// fallback, the transaction has a foreign amount in $currency.
|
||||
if ($convertToNative && null !== $journal['foreign_amount'] && $currency->id === (int)$journal['foreign_currency_id']) {
|
||||
$amount = $journal['foreign_amount'];
|
||||
//Log::debug(sprintf('Overruled, amount is now %s', $amount));
|
||||
// Log::debug(sprintf('Overruled, amount is now %s', $amount));
|
||||
}
|
||||
|
||||
return $amount;
|
||||
}
|
||||
|
||||
@@ -76,20 +77,21 @@ class Amount
|
||||
$convertToNative = app('preferences')->get('convert_to_native', false)->data;
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
$field = $convertToNative && $currency->id !== $journal->transaction_currency_id ? 'native_amount' : 'amount';
|
||||
|
||||
/** @var null|Transaction $sourceTransaction */
|
||||
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
|
||||
if (null === $sourceTransaction) {
|
||||
return '0';
|
||||
}
|
||||
$amount = $sourceTransaction->$field;
|
||||
$amount = $sourceTransaction->{$field};
|
||||
if ((int) $sourceTransaction->foreign_currency_id === $currency->id) {
|
||||
// use foreign amount instead!
|
||||
$amount = (string) $sourceTransaction->foreign_amount; // hard coded to be foreign amount.
|
||||
}
|
||||
|
||||
return $amount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will properly format the given number, in color or "black and white",
|
||||
* as a currency, given two things: the currency required and the current locale.
|
||||
@@ -308,11 +310,11 @@ class Amount
|
||||
}
|
||||
|
||||
// default is amount before currency
|
||||
$format = $posA . $posD . '%v' . $space . $posB . '%s' . $posC . $posE;
|
||||
$format = $posA.$posD.'%v'.$space.$posB.'%s'.$posC.$posE;
|
||||
|
||||
if ($csPrecedes) {
|
||||
// alternative is currency before amount
|
||||
$format = $posA . $posB . '%s' . $posC . $space . $posD . '%v' . $posE;
|
||||
$format = $posA.$posB.'%s'.$posC.$space.$posD.'%v'.$posE;
|
||||
}
|
||||
|
||||
return $format;
|
||||
|
@@ -48,7 +48,6 @@ class FrontpageChartGenerator
|
||||
public bool $convertToNative = false;
|
||||
public TransactionCurrency $default;
|
||||
|
||||
|
||||
/**
|
||||
* FrontpageChartGenerator constructor.
|
||||
*/
|
||||
@@ -100,10 +99,12 @@ class FrontpageChartGenerator
|
||||
if (0 === $limits->count()) {
|
||||
$result = $this->noBudgetLimits($data, $budget);
|
||||
Log::debug(sprintf('Now DONE processing budget #%d ("%s")', $budget->id, $budget->name));
|
||||
|
||||
return $result;
|
||||
}
|
||||
$result = $this->budgetLimits($data, $budget, $limits);
|
||||
Log::debug(sprintf('Now DONE processing budget #%d ("%s")', $budget->id, $budget->name));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -132,6 +133,7 @@ class FrontpageChartGenerator
|
||||
private function budgetLimits(array $data, Budget $budget, Collection $limits): array
|
||||
{
|
||||
Log::debug('Start processing budget limits.');
|
||||
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($limits as $limit) {
|
||||
$data = $this->processLimit($data, $budget, $limit);
|
||||
@@ -158,6 +160,7 @@ class FrontpageChartGenerator
|
||||
|
||||
$spent = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection([$budget]), $currency);
|
||||
Log::debug(sprintf('Spent array has %d entries.', count($spent)));
|
||||
|
||||
/** @var array $entry */
|
||||
foreach ($spent as $entry) {
|
||||
// only spent the entry where the entry's currency matches the budget limit's currency
|
||||
@@ -195,7 +198,7 @@ class FrontpageChartGenerator
|
||||
}
|
||||
$useNative = $this->convertToNative && $this->default->id !== $limit->transaction_currency_id;
|
||||
$amount = $limit->amount;
|
||||
if($useNative) {
|
||||
if ($useNative) {
|
||||
$amount = $limit->native_amount;
|
||||
}
|
||||
|
||||
@@ -207,8 +210,8 @@ class FrontpageChartGenerator
|
||||
|
||||
|
||||
$data[0]['entries'][$title] = bcadd($data[0]['entries'][$title], 1 === bccomp($sumSpent, $amount) ? $amount : $sumSpent); // spent
|
||||
$data[1]['entries'][$title] = bcadd($data[1]['entries'][$title],1 === bccomp($amount, $sumSpent) ? bcadd($entry['sum'], $amount) : '0'); // left to spent
|
||||
$data[2]['entries'][$title] = bcadd($data[2]['entries'][$title],1 === bccomp($amount, $sumSpent) ? '0' : bcmul(bcadd($entry['sum'], $amount), '-1')); // overspent
|
||||
$data[1]['entries'][$title] = bcadd($data[1]['entries'][$title], 1 === bccomp($amount, $sumSpent) ? bcadd($entry['sum'], $amount) : '0'); // left to spent
|
||||
$data[2]['entries'][$title] = bcadd($data[2]['entries'][$title], 1 === bccomp($amount, $sumSpent) ? '0' : bcmul(bcadd($entry['sum'], $amount), '-1')); // overspent
|
||||
|
||||
Log::debug(sprintf('Amount [spent] is now %s.', $data[0]['entries'][$title]));
|
||||
Log::debug(sprintf('Amount [left] is now %s.', $data[1]['entries'][$title]));
|
||||
|
@@ -30,7 +30,6 @@ use FireflyIII\Models\CurrencyExchangeRate;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\UserGroup;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
@@ -187,7 +186,8 @@ class ExchangeRateConverter
|
||||
->where('to_currency_id', $to)
|
||||
->where('date', '<=', $date)
|
||||
->orderBy('date', 'DESC')
|
||||
->first();
|
||||
->first()
|
||||
;
|
||||
++$this->queryCount;
|
||||
$rate = (string) $result?->rate;
|
||||
|
||||
@@ -292,7 +292,8 @@ class ExchangeRateConverter
|
||||
->where('to_currency_id', $to->id)
|
||||
->where('date', '<=', $end->format('Y-m-d'))
|
||||
->where('date', '>=', $start->format('Y-m-d'))
|
||||
->orderBy('date', 'DESC')->get();
|
||||
->orderBy('date', 'DESC')->get()
|
||||
;
|
||||
++$this->queryCount;
|
||||
if (0 === $set->count()) {
|
||||
Log::debug('No prepared rates found in this period, use the fallback');
|
||||
|
@@ -39,6 +39,7 @@ trait BasicDataSupport
|
||||
protected function isInArray(array $array, int $entryId)
|
||||
{
|
||||
$key = $this->convertToNative ? 'native_balance' : 'balance';
|
||||
|
||||
return $array[$entryId][$key] ?? '0';
|
||||
}
|
||||
|
||||
|
@@ -54,7 +54,7 @@ trait ChartGeneration
|
||||
$cache->addProperty($accounts);
|
||||
$cache->addProperty($convertToNative);
|
||||
if ($cache->has()) {
|
||||
//return $cache->get();
|
||||
// return $cache->get();
|
||||
}
|
||||
app('log')->debug('Regenerate chart.account.account-balance-chart from scratch.');
|
||||
$locale = app('steam')->getLocale();
|
||||
@@ -72,7 +72,7 @@ trait ChartGeneration
|
||||
foreach ($accounts as $account) {
|
||||
$currency = $accountRepos->getAccountCurrency($account) ?? $default;
|
||||
$useNative = $convertToNative && $default->id !== $currency->id;
|
||||
$field =$useNative ? 'native_balance' : 'balance';
|
||||
$field = $useNative ? 'native_balance' : 'balance';
|
||||
$currency = $useNative ? $default : $currency;
|
||||
$currentSet = [
|
||||
'label' => $account->name,
|
||||
|
@@ -62,7 +62,7 @@ class Steam
|
||||
$value = (string) ($transaction[$key] ?? '0');
|
||||
$value = '' === $value ? '0' : $value;
|
||||
$sum = bcadd($sum, $value);
|
||||
//Log::debug(sprintf('Add value from "%s": %s', $key, $value));
|
||||
// Log::debug(sprintf('Add value from "%s": %s', $key, $value));
|
||||
}
|
||||
Log::debug(sprintf('Sum of "%s"-fields is %s', $key, $sum));
|
||||
|
||||
@@ -118,7 +118,8 @@ class Steam
|
||||
\DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'),
|
||||
\DB::raw('SUM(transactions.native_amount) AS modified_native'),
|
||||
]
|
||||
);
|
||||
)
|
||||
;
|
||||
|
||||
$currentBalance = $startBalance;
|
||||
|
||||
@@ -184,10 +185,10 @@ class Steam
|
||||
// Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision));
|
||||
if (str_contains($number, '.')) {
|
||||
if ('-' !== $number[0]) {
|
||||
return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision);
|
||||
return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision);
|
||||
}
|
||||
|
||||
return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
|
||||
return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision);
|
||||
}
|
||||
|
||||
return $number;
|
||||
@@ -272,7 +273,6 @@ class Steam
|
||||
* Wil je niks weten van native currencies, pak je:
|
||||
*
|
||||
* Eerst een som van alle transacties gegroepeerd op currency. Einde.
|
||||
*
|
||||
*/
|
||||
public function finalAccountBalance(Account $account, Carbon $date): array
|
||||
{
|
||||
@@ -291,9 +291,10 @@ class Steam
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
|
||||
->where('transactions.transaction_currency_id', $native->id)
|
||||
->sum('transactions.amount');
|
||||
->sum('transactions.amount')
|
||||
;
|
||||
// plus virtual balance, if the account has a virtual_balance in the native currency
|
||||
if($native->id === $accountCurrency?->id) {
|
||||
if ($native->id === $accountCurrency?->id) {
|
||||
$return['balance'] = bcadd('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance, $return['balance']);
|
||||
}
|
||||
Log::debug(sprintf('balance is (%s only) %s (with virtual balance)', $native->code, $return['balance']));
|
||||
@@ -303,7 +304,8 @@ class Steam
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
|
||||
->whereNot('transactions.transaction_currency_id', $native->id)
|
||||
->sum('transactions.native_amount');
|
||||
->sum('transactions.native_amount')
|
||||
;
|
||||
// plus native virtual balance.
|
||||
$return['native_balance'] = bcadd('' === (string) $account->native_virtual_balance ? '0' : $account->native_virtual_balance, $return['native_balance']);
|
||||
Log::debug(sprintf('native_balance is (all transactions to %s) %s (with virtual balance)', $native->code, $return['native_balance']));
|
||||
@@ -314,7 +316,8 @@ class Steam
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
|
||||
->whereNot('transactions.transaction_currency_id', $native->id)
|
||||
->where('transactions.foreign_currency_id', $native->id)
|
||||
->sum('transactions.foreign_amount');
|
||||
->sum('transactions.foreign_amount')
|
||||
;
|
||||
$return['native_balance'] = bcadd($return['native_balance'], $sum);
|
||||
|
||||
Log::debug(sprintf('Foreign amount transactions add (%s only) %s, total native_balance is now %s', $native->code, $sum, $return['native_balance']));
|
||||
@@ -325,7 +328,8 @@ class Steam
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
|
||||
->get(['transaction_currencies.code', 'transactions.amount'])->toArray();
|
||||
->get(['transaction_currencies.code', 'transactions.amount'])->toArray()
|
||||
;
|
||||
$others = $this->groupAndSumTransactions($array, 'code', 'amount');
|
||||
Log::debug('All balances are (joined)', $others);
|
||||
// if the account has no own currency preference, drop balance in favor of native balance
|
||||
@@ -336,9 +340,9 @@ class Steam
|
||||
}
|
||||
|
||||
// if the currency is the same as the native currency, set the native_balance to the balance for consistency.
|
||||
// if($currency->id === $native->id) {
|
||||
// $return['native_balance'] = $return['balance'];
|
||||
// }
|
||||
// if($currency->id === $native->id) {
|
||||
// $return['native_balance'] = $return['balance'];
|
||||
// }
|
||||
|
||||
if (!$hasCurrency && array_key_exists('balance', $return) && array_key_exists('native_balance', $return)) {
|
||||
Log::debug('Account has no currency preference, dropping balance in favor of native balance.');
|
||||
|
@@ -75,7 +75,7 @@ class AmountFormat extends AbstractExtension
|
||||
$this->formatAmountByAccount(),
|
||||
$this->formatAmountBySymbol(),
|
||||
$this->formatAmountByCurrency(),
|
||||
$this->formatAmountByCode()
|
||||
$this->formatAmountByCode(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ class AmountFormat extends AbstractExtension
|
||||
'formatAmountByCode',
|
||||
static function (string $amount, string $code, ?bool $coloured = null): string {
|
||||
$coloured ??= true;
|
||||
|
||||
/** @var TransactionCurrency $currency */
|
||||
$currency = TransactionCurrency::whereCode($code)->first();
|
||||
|
||||
|
@@ -79,6 +79,7 @@ class General extends AbstractExtension
|
||||
if (!$useNative) {
|
||||
$strings[] = app('amount')->formatAnything($currency, $balance, false);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
if ('native_balance' === $key) {
|
||||
|
12
composer.lock
generated
12
composer.lock
generated
@@ -10845,16 +10845,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "barryvdh/laravel-debugbar",
|
||||
"version": "v3.14.9",
|
||||
"version": "v3.14.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/barryvdh/laravel-debugbar.git",
|
||||
"reference": "2e805a6bd4e1aa83774316bb062703c65d0691ef"
|
||||
"reference": "56b9bd235e3fe62e250124804009ce5bab97cc63"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/2e805a6bd4e1aa83774316bb062703c65d0691ef",
|
||||
"reference": "2e805a6bd4e1aa83774316bb062703c65d0691ef",
|
||||
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/56b9bd235e3fe62e250124804009ce5bab97cc63",
|
||||
"reference": "56b9bd235e3fe62e250124804009ce5bab97cc63",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -10913,7 +10913,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/barryvdh/laravel-debugbar/issues",
|
||||
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.14.9"
|
||||
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.14.10"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -10925,7 +10925,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-25T14:51:20+00:00"
|
||||
"time": "2024-12-23T10:10:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/laravel-ide-helper",
|
||||
|
24
package-lock.json
generated
24
package-lock.json
generated
@@ -3621,9 +3621,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/admin-lte": {
|
||||
"version": "4.0.0-beta2",
|
||||
"resolved": "https://registry.npmjs.org/admin-lte/-/admin-lte-4.0.0-beta2.tgz",
|
||||
"integrity": "sha512-Ofav0BKnCnz+IeeXrHQZ6JWnHouwv+fDYyfagRpjfFaMBmYCljA2Qo1+fCGkJuJn/SfNPhFpJhbUt+l2tH0LwA==",
|
||||
"version": "4.0.0-beta3",
|
||||
"resolved": "https://registry.npmjs.org/admin-lte/-/admin-lte-4.0.0-beta3.tgz",
|
||||
"integrity": "sha512-q2VoAOu1DtZ7z41M2gQ05VMNYkFCAMxFU+j/HUMwCOlr/e3VhO+qww2SGJw4OxBw5nZQ7YV78+wK2RiB7ConzQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ag-charts-types": {
|
||||
@@ -3702,9 +3702,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/alpinejs": {
|
||||
"version": "3.14.7",
|
||||
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.14.7.tgz",
|
||||
"integrity": "sha512-ScnbydNBcWVnCiVupD3wWUvoMPm8244xkvDNMxVCspgmap9m4QuJ7pjc+77UtByU+1+Ejg0wzYkP4mQaOMcvng==",
|
||||
"version": "3.14.8",
|
||||
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.14.8.tgz",
|
||||
"integrity": "sha512-wT2fuP2DXpGk/jKaglwy7S/IJpm1FD+b7U6zUrhwErjoq5h27S4dxkJEXVvhbdwyPv9U+3OkUuNLkZT4h2Kfrg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "~3.1.1"
|
||||
@@ -5646,9 +5646,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.75",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz",
|
||||
"integrity": "sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==",
|
||||
"version": "1.5.76",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz",
|
||||
"integrity": "sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -6104,9 +6104,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
|
||||
"integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz",
|
||||
"integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
@@ -80,7 +80,7 @@ Route::group(
|
||||
Route::group(
|
||||
['middleware' => 'binders-only', 'namespace' => 'FireflyIII\Http\Controllers\System'],
|
||||
static function (): void {
|
||||
//Route::get('offline', static fn () => view('errors.offline'));
|
||||
// Route::get('offline', static fn () => view('errors.offline'));
|
||||
Route::get('health', ['uses' => 'HealthcheckController@check', 'as' => 'healthcheck']);
|
||||
}
|
||||
);
|
||||
|
Reference in New Issue
Block a user