Merge branch 'v6.2' of github.com:firefly-iii/firefly-iii into v6.2

# Conflicts:
#	app/Support/Steam.php
This commit is contained in:
James Cole 2024-12-23 06:56:31 +01:00
commit 3c65b46aa5
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
91 changed files with 1146 additions and 1157 deletions

View File

@ -56,8 +56,8 @@ class AccountController extends Controller
function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUserGroup($this->validateUserGroup($request));
$this->chartData = new ChartData();
$this->default = app('amount')->getDefaultCurrency();
$this->chartData = new ChartData();
$this->default = app('amount')->getDefaultCurrency();
return $next($request);
}
@ -92,11 +92,11 @@ class AccountController extends Controller
*/
private function renderAccountData(array $params, Account $account): void
{
$currency = $this->repository->getAccountCurrency($account);
$currency = $this->repository->getAccountCurrency($account);
if (null === $currency) {
$currency = $this->default;
}
$currentSet = [
$currentSet = [
'label' => $account->name,
// the currency that belongs to the account.
@ -117,18 +117,18 @@ class AccountController extends Controller
'entries' => [],
'native_entries' => [],
];
$currentStart = clone $params['start'];
$range = app('steam')->finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $currency);
$currentStart = clone $params['start'];
$range = app('steam')->finalAccountBalanceInRange($account, $params['start'], clone $params['end'], $currency);
$previous = array_values($range)[0]['balance'];
$previousNative = array_values($range)[0]['native_balance'];
while ($currentStart <= $params['end']) {
$format = $currentStart->format('Y-m-d');
$label = $currentStart->toAtomString();
$balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
$balanceNative = array_key_exists($format, $range) ? $range[$format]['balance_native'] : $previousNative;
$previous = $balance;
$previousNative = $balanceNative;
$format = $currentStart->format('Y-m-d');
$label = $currentStart->toAtomString();
$balance = array_key_exists($format, $range) ? $range[$format]['balance'] : $previous;
$balanceNative = array_key_exists($format, $range) ? $range[$format]['balance_native'] : $previousNative;
$previous = $balance;
$previousNative = $balanceNative;
$currentStart->addDay();
$currentSet['entries'][$label] = $balance;

View File

@ -29,11 +29,9 @@ use FireflyIII\Events\RequestedVersionCheckStatus;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Http\Middleware\Installer;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

View File

@ -103,7 +103,7 @@ class PreferencesController extends Controller
$darkMode = app('preferences')->get('darkMode', 'browser')->data;
$customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data;
$fiscalYearStartStr = app('preferences')->get('fiscalYearStart', '01-01')->data;
$convertToNative =app('preferences')->get('convert_to_native', false)->data;
$convertToNative = app('preferences')->get('convert_to_native', false)->data;
if (is_array($fiscalYearStartStr)) {
$fiscalYearStartStr = '01-01';
}
@ -257,7 +257,7 @@ class PreferencesController extends Controller
}
// convert native
$convertToNative = 1 === (int) $request->get('convertToNative');
$convertToNative = 1 === (int) $request->get('convertToNative');
app('preferences')->set('convert_to_native', $convertToNative);
// custom fiscal year

View File

@ -28,7 +28,6 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\UserGroup;
use FireflyIII\User;
use Illuminate\Support\Collection;
use NumberFormatter;
/**
* Class Amount.
@ -56,15 +55,15 @@ class Amount
*/
public function formatFlat(string $symbol, int $decimalPlaces, string $amount, ?bool $coloured = null): string
{
$locale = app('steam')->getLocale();
$rounded = app('steam')->bcround($amount, $decimalPlaces);
$locale = app('steam')->getLocale();
$rounded = app('steam')->bcround($amount, $decimalPlaces);
$coloured ??= true;
$fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
$fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, $symbol);
$fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimalPlaces);
$fmt->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimalPlaces);
$result = (string) $fmt->format((float) $rounded); // intentional float
$fmt = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);
$fmt->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, $symbol);
$fmt->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, $decimalPlaces);
$fmt->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, $decimalPlaces);
$result = (string) $fmt->format((float) $rounded); // intentional float
if (true === $coloured) {
if (1 === bccomp($rounded, '0')) {
@ -110,7 +109,7 @@ class Amount
public function getDefaultCurrencyByUserGroup(UserGroup $userGroup): TransactionCurrency
{
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty('getDefaultCurrencyByGroup');
$cache->addProperty($userGroup->id);
if ($cache->has()) {
@ -173,23 +172,23 @@ class Amount
private function getLocaleInfo(): array
{
// get config from preference, not from translation:
$locale = app('steam')->getLocale();
$array = app('steam')->getLocaleArray($locale);
$locale = app('steam')->getLocale();
$array = app('steam')->getLocaleArray($locale);
setlocale(LC_MONETARY, $array);
$info = localeconv();
$info = localeconv();
// correct variables
$info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes');
$info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes');
$info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes');
$info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes');
$info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space');
$info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space');
$info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space');
$info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space');
$fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
$fmt = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);
$info['mon_decimal_point'] = $fmt->getSymbol(NumberFormatter::MONETARY_SEPARATOR_SYMBOL);
$info['mon_thousands_sep'] = $fmt->getSymbol(NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL);
$info['mon_decimal_point'] = $fmt->getSymbol(\NumberFormatter::MONETARY_SEPARATOR_SYMBOL);
$info['mon_thousands_sep'] = $fmt->getSymbol(\NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL);
return $info;
}
@ -209,7 +208,7 @@ class Amount
public static function getAmountJsConfig(bool $sepBySpace, int $signPosn, string $sign, bool $csPrecedes): string
{
// negative first:
$space = ' ';
$space = ' ';
// require space between symbol and amount?
if (false === $sepBySpace) {
@ -218,11 +217,11 @@ class Amount
// there are five possible positions for the "+" or "-" sign (if it is even used)
// pos_a and pos_e could be the ( and ) symbol.
$posA = ''; // before everything
$posB = ''; // before currency symbol
$posC = ''; // after currency symbol
$posD = ''; // before amount
$posE = ''; // after everything
$posA = ''; // before everything
$posB = ''; // before currency symbol
$posC = ''; // after currency symbol
$posD = ''; // before amount
$posE = ''; // after everything
// format would be (currency before amount)
// AB%sC_D%vE
@ -264,11 +263,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;

View File

@ -47,7 +47,7 @@ class RemoteUserGuard implements Guard
public function __construct(UserProvider $provider, Application $app)
{
/** @var null|Request $request */
$request = $app->get('request');
$request = $app->get('request');
app('log')->debug(sprintf('Created RemoteUserGuard for %s "%s"', $request?->getMethod(), $request?->getRequestUri()));
$this->application = $app;
$this->provider = $provider;
@ -63,8 +63,8 @@ class RemoteUserGuard implements Guard
return;
}
// Get the user identifier from $_SERVER or apache filtered headers
$header = config('auth.guard_header', 'REMOTE_USER');
$userID = request()->server($header) ?? null;
$header = config('auth.guard_header', 'REMOTE_USER');
$userID = request()->server($header) ?? null;
if (function_exists('apache_request_headers')) {
app('log')->debug('Use apache_request_headers to find user ID.');
@ -83,7 +83,7 @@ class RemoteUserGuard implements Guard
$retrievedUser = $this->provider->retrieveById($userID);
// store email address if present in header and not already set.
$header = config('auth.guard_email');
$header = config('auth.guard_email');
if (null !== $header) {
$emailAddress = (string) (request()->server($header) ?? apache_request_headers()[$header] ?? null);
@ -99,7 +99,7 @@ class RemoteUserGuard implements Guard
}
app('log')->debug(sprintf('Result of getting user from provider: %s', $retrievedUser->email));
$this->user = $retrievedUser;
$this->user = $retrievedUser;
}
public function guest(): bool
@ -139,14 +139,14 @@ class RemoteUserGuard implements Guard
/**
* @SuppressWarnings(PHPMD.ShortMethodName)
*/
public function id(): null | int | string
public function id(): null|int|string
{
app('log')->debug(sprintf('Now at %s', __METHOD__));
return $this->user?->id;
}
public function setUser(null | Authenticatable | User $user): void // @phpstan-ignore-line
public function setUser(null|Authenticatable|User $user): void // @phpstan-ignore-line
{
app('log')->debug(sprintf('Now at %s', __METHOD__));
if ($user instanceof User) {

View File

@ -30,15 +30,13 @@ use FireflyIII\Models\Role;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
use Override;
use Str;
/**
* Class RemoteUserProvider
*/
class RemoteUserProvider implements UserProvider
{
#[Override]
#[\Override]
public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false): void
{
app('log')->debug(sprintf('Now at %s', __METHOD__));
@ -74,7 +72,7 @@ class RemoteUserProvider implements UserProvider
'blocked' => false,
'blocked_code' => null,
'email' => $identifier,
'password' => bcrypt(Str::random(64)),
'password' => bcrypt(\Str::random(64)),
]
);
// if this is the first user, give them admin as well.

View File

@ -48,18 +48,19 @@ class Balance
return $cache->get();
}
$query = Transaction::whereIn('transactions.account_id', $accounts->pluck('id')->toArray())
->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->orderBy('transaction_journals.date', 'desc')
->orderBy('transaction_journals.order', 'asc')
->orderBy('transaction_journals.description', 'desc')
->orderBy('transactions.amount', 'desc')
->where('transaction_journals.date', '<=', $date);
$query = Transaction::whereIn('transactions.account_id', $accounts->pluck('id')->toArray())
->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->orderBy('transaction_journals.date', 'desc')
->orderBy('transaction_journals.order', 'asc')
->orderBy('transaction_journals.description', 'desc')
->orderBy('transactions.amount', 'desc')
->where('transaction_journals.date', '<=', $date)
;
$result = $query->get(['transactions.account_id', 'transactions.transaction_currency_id', 'transactions.balance_after']);
$result = $query->get(['transactions.account_id', 'transactions.transaction_currency_id', 'transactions.balance_after']);
foreach ($result as $entry) {
$accountId = (int) $entry->account_id;
$currencyId = (int) $entry->transaction_currency_id;
$accountId = (int) $entry->account_id;
$currencyId = (int) $entry->transaction_currency_id;
$currencies[$currencyId] ??= TransactionCurrency::find($currencyId);
$return[$accountId] ??= [];
if (array_key_exists($currencyId, $return[$accountId])) {

View File

@ -43,21 +43,23 @@ class AccountList implements BinderInterface
if ('allAssetAccounts' === $value) {
/** @var Collection $collection */
$collection = auth()->user()->accounts()
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('account_types.type', [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE])
->orderBy('accounts.name', 'ASC')
->get(['accounts.*']);
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('account_types.type', [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE])
->orderBy('accounts.name', 'ASC')
->get(['accounts.*'])
;
}
if ('allAssetAccounts' !== $value) {
$incoming = array_map('\intval', explode(',', $value));
$list = array_merge(array_unique($incoming), [0]);
$incoming = array_map('\intval', explode(',', $value));
$list = array_merge(array_unique($incoming), [0]);
/** @var Collection $collection */
$collection = auth()->user()->accounts()
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('accounts.id', $list)
->orderBy('accounts.name', 'ASC')
->get(['accounts.*']);
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('accounts.id', $list)
->orderBy('accounts.name', 'ASC')
->get(['accounts.*'])
;
}
if ($collection->count() > 0) {

View File

@ -41,12 +41,13 @@ class BudgetList implements BinderInterface
if (auth()->check()) {
if ('allBudgets' === $value) {
return auth()->user()->budgets()->where('active', true)
->orderBy('order', 'ASC')
->orderBy('name', 'ASC')
->get();
->orderBy('order', 'ASC')
->orderBy('name', 'ASC')
->get()
;
}
$list = array_unique(array_map('\intval', explode(',', $value)));
$list = array_unique(array_map('\intval', explode(',', $value)));
if (0 === count($list)) { // @phpstan-ignore-line
app('log')->warning('Budget list count is zero, return 404.');
@ -56,9 +57,10 @@ class BudgetList implements BinderInterface
/** @var Collection $collection */
$collection = auth()->user()->budgets()
->where('active', true)
->whereIn('id', $list)
->get();
->where('active', true)
->whereIn('id', $list)
->get()
;
// add empty budget if applicable.
if (in_array(0, $list, true)) {

View File

@ -41,19 +41,21 @@ class CategoryList implements BinderInterface
if (auth()->check()) {
if ('allCategories' === $value) {
return auth()->user()->categories()
->orderBy('name', 'ASC')
->get();
->orderBy('name', 'ASC')
->get()
;
}
$list = array_unique(array_map('\intval', explode(',', $value)));
$list = array_unique(array_map('\intval', explode(',', $value)));
if (0 === count($list)) { // @phpstan-ignore-line
throw new NotFoundHttpException();
}
/** @var Collection $collection */
$collection = auth()->user()->categories()
->whereIn('id', $list)
->get();
->whereIn('id', $list)
->get()
;
// add empty category if applicable.
if (in_array(0, $list, true)) {

View File

@ -43,16 +43,16 @@ class Date implements BinderInterface
/** @var FiscalHelperInterface $fiscalHelper */
$fiscalHelper = app(FiscalHelperInterface::class);
$magicWords = [
'currentMonthStart' => today(config('app.timezone'))->startOfMonth(),
'currentMonthEnd' => today(config('app.timezone'))->endOfMonth(),
'currentYearStart' => today(config('app.timezone'))->startOfYear(),
'currentYearEnd' => today(config('app.timezone'))->endOfYear(),
$magicWords = [
'currentMonthStart' => today(config('app.timezone'))->startOfMonth(),
'currentMonthEnd' => today(config('app.timezone'))->endOfMonth(),
'currentYearStart' => today(config('app.timezone'))->startOfYear(),
'currentYearEnd' => today(config('app.timezone'))->endOfYear(),
'previousMonthStart' => today(config('app.timezone'))->startOfMonth()->subDay()->startOfMonth(),
'previousMonthEnd' => today(config('app.timezone'))->startOfMonth()->subDay()->endOfMonth(),
'previousYearStart' => today(config('app.timezone'))->startOfYear()->subDay()->startOfYear(),
'previousYearEnd' => today(config('app.timezone'))->startOfYear()->subDay()->endOfYear(),
'previousMonthStart' => today(config('app.timezone'))->startOfMonth()->subDay()->startOfMonth(),
'previousMonthEnd' => today(config('app.timezone'))->startOfMonth()->subDay()->endOfMonth(),
'previousYearStart' => today(config('app.timezone'))->startOfYear()->subDay()->startOfYear(),
'previousYearEnd' => today(config('app.timezone'))->startOfYear()->subDay()->endOfYear(),
'currentFiscalYearStart' => $fiscalHelper->startOfFiscalYear(today(config('app.timezone'))),
'currentFiscalYearEnd' => $fiscalHelper->endOfFiscalYear(today(config('app.timezone'))),
@ -68,7 +68,7 @@ class Date implements BinderInterface
try {
$result = new Carbon($value);
} catch (InvalidDateException | InvalidFormatException $e) { // @phpstan-ignore-line
} catch (InvalidDateException|InvalidFormatException $e) { // @phpstan-ignore-line
$message = sprintf('Could not parse date "%s" for user #%d: %s', $value, auth()->user()->id, $e->getMessage());
app('log')->error($message);

View File

@ -39,7 +39,7 @@ class JournalList implements BinderInterface
public static function routeBinder(string $value, Route $route): array
{
if (auth()->check()) {
$list = self::parseList($value);
$list = self::parseList($value);
// get the journals by using the collector.
/** @var GroupCollectorInterface $collector */
@ -47,7 +47,7 @@ class JournalList implements BinderInterface
$collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::RECONCILIATION]);
$collector->withCategoryInformation()->withBudgetInformation()->withTagInformation()->withAccountInformation();
$collector->setJournalIds($list);
$result = $collector->getExtractedJournals();
$result = $collector->getExtractedJournals();
if (0 === count($result)) {
throw new NotFoundHttpException();
}

View File

@ -43,10 +43,11 @@ class TagList implements BinderInterface
if (auth()->check()) {
if ('allTags' === $value) {
return auth()->user()->tags()
->orderBy('tag', 'ASC')
->get();
->orderBy('tag', 'ASC')
->get()
;
}
$list = array_unique(array_map('\strtolower', explode(',', $value)));
$list = array_unique(array_map('\strtolower', explode(',', $value)));
app('log')->debug('List of tags is', $list);
if (0 === count($list)) { // @phpstan-ignore-line
@ -58,7 +59,7 @@ class TagList implements BinderInterface
/** @var TagRepositoryInterface $repository */
$repository = app(TagRepositoryInterface::class);
$repository->setUser(auth()->user());
$allTags = $repository->get();
$allTags = $repository->get();
$collection = $allTags->filter(
static function (Tag $tag) use ($list) {

View File

@ -40,7 +40,7 @@ class TagOrId implements BinderInterface
$repository = app(TagRepositoryInterface::class);
$repository->setUser(auth()->user());
$result = $repository->findByTag($value);
$result = $repository->findByTag($value);
if (null === $result) {
$result = $repository->find((int) $value);
}

View File

@ -42,8 +42,9 @@ class UserGroupAccount implements BinderInterface
/** @var User $user */
$user = auth()->user();
$account = Account::where('id', (int) $value)
->where('user_group_id', $user->user_group_id)
->first();
->where('user_group_id', $user->user_group_id)
->first()
;
if (null !== $account) {
return $account;
}

View File

@ -42,8 +42,9 @@ class UserGroupBill implements BinderInterface
/** @var User $user */
$user = auth()->user();
$currency = Bill::where('id', (int) $value)
->where('user_group_id', $user->user_group_id)
->first();
->where('user_group_id', $user->user_group_id)
->first()
;
if (null !== $currency) {
return $currency;
}

View File

@ -39,8 +39,9 @@ class UserGroupExchangeRate implements BinderInterface
/** @var User $user */
$user = auth()->user();
$rate = CurrencyExchangeRate::where('id', (int) $value)
->where('user_group_id', $user->user_group_id)
->first();
->where('user_group_id', $user->user_group_id)
->first()
;
if (null !== $rate) {
return $rate;
}

View File

@ -39,8 +39,9 @@ class UserGroupTransaction implements BinderInterface
/** @var User $user */
$user = auth()->user();
$group = TransactionGroup::where('id', (int) $value)
->where('user_group_id', $user->user_group_id)
->first();
->where('user_group_id', $user->user_group_id)
->first()
;
if (null !== $group) {
return $group;
}

View File

@ -23,9 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Support;
use Cache;
use Illuminate\Support\Collection;
use JsonException;
/**
* Class CacheProperties.
@ -57,7 +55,7 @@ class CacheProperties
*/
public function get()
{
return Cache::get($this->hash);
return \Cache::get($this->hash);
}
public function getHash(): string
@ -72,16 +70,16 @@ class CacheProperties
}
$this->hash();
return Cache::has($this->hash);
return \Cache::has($this->hash);
}
private function hash(): void
{
$content = '';
$content = '';
foreach ($this->properties as $property) {
try {
$content .= json_encode($property, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
} catch (\JsonException $e) {
// @ignoreException
$content .= hash('sha256', (string) time());
}
@ -94,6 +92,6 @@ class CacheProperties
*/
public function store($data): void
{
Cache::forever($this->hash, $data);
\Cache::forever($this->hash, $data);
}
}

View File

@ -26,16 +26,15 @@ namespace FireflyIII\Support\Calendar;
use Carbon\Carbon;
use FireflyIII\Exceptions\IntervalException;
use SplObjectStorage;
/**
* Class Calculator
*/
class Calculator
{
public const int DEFAULT_INTERVAL = 1;
private static ?SplObjectStorage $intervalMap = null;
private static array $intervals = [];
public const int DEFAULT_INTERVAL = 1;
private static ?\SplObjectStorage $intervalMap = null;
private static array $intervals = [];
/**
* @throws IntervalException
@ -66,14 +65,14 @@ class Calculator
/**
* @SuppressWarnings(PHPMD.MissingImport)
*/
private static function loadIntervalMap(): SplObjectStorage
private static function loadIntervalMap(): \SplObjectStorage
{
if (null !== self::$intervalMap) {
return self::$intervalMap;
}
self::$intervalMap = new SplObjectStorage();
self::$intervalMap = new \SplObjectStorage();
foreach (Periodicity::cases() as $interval) {
$periodicityClass = __NAMESPACE__ . "\\Periodicity\\{$interval->name}";
$periodicityClass = __NAMESPACE__."\\Periodicity\\{$interval->name}";
self::$intervals[] = $interval->name;
self::$intervalMap->attach($interval, new $periodicityClass());
}

View File

@ -155,7 +155,7 @@ class FrontpageChartGenerator
*/
private function processRow(array $data, Budget $budget, BudgetLimit $limit, array $entry): array
{
$title = sprintf('%s (%s)', $budget->name, $entry['currency_name']);
$title = sprintf('%s (%s)', $budget->name, $entry['currency_name']);
if ($limit->start_date->startOfDay()->ne($this->start->startOfDay()) || $limit->end_date->startOfDay()->ne($this->end->startOfDay())) {
$title = sprintf(
'%s (%s) (%s - %s)',
@ -165,7 +165,7 @@ class FrontpageChartGenerator
$limit->end_date->isoFormat($this->monthAndDayFormat)
);
}
$sumSpent = bcmul($entry['sum'], '-1'); // spent
$sumSpent = bcmul($entry['sum'], '-1'); // spent
$data[0]['entries'][$title] = 1 === bccomp($sumSpent, $limit->amount) ? $limit->amount : $sumSpent; // spent
$data[1]['entries'][$title] = 1 === bccomp($limit->amount, $sumSpent) ? bcadd($entry['sum'], $limit->amount) : '0'; // left to spent

View File

@ -65,13 +65,13 @@ class FrontpageChartGenerator
public function generate(): array
{
$categories = $this->repository->getCategories();
$accounts = $this->accountRepos->getAccountsByType(
$categories = $this->repository->getCategories();
$accounts = $this->accountRepos->getAccountsByType(
[AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::ASSET, AccountType::DEFAULT]
);
// get expenses + income per category:
$collection = [];
$collection = [];
/** @var Category $category */
foreach ($categories as $category) {
@ -82,10 +82,10 @@ class FrontpageChartGenerator
// collect for no-category:
$collection[] = $this->collectNoCatExpenses($accounts);
$tempData = array_merge(...$collection);
$tempData = array_merge(...$collection);
// sort temp array by amount.
$amounts = array_column($tempData, 'sum_float');
$amounts = array_column($tempData, 'sum_float');
array_multisort($amounts, SORT_ASC, $tempData);
$currencyData = $this->createCurrencyGroups($tempData);

View File

@ -38,22 +38,22 @@ class WholePeriodChartGenerator
{
public function generate(Category $category, Carbon $start, Carbon $end): array
{
$collection = new Collection([$category]);
$collection = new Collection([$category]);
/** @var OperationsRepositoryInterface $opsRepository */
$opsRepository = app(OperationsRepositoryInterface::class);
$opsRepository = app(OperationsRepositoryInterface::class);
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
$types = [AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
$accounts = $accountRepository->getAccountsByType($types);
$step = $this->calculateStep($start, $end);
$chartData = [];
$spent = [];
$earned = [];
$types = [AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
$accounts = $accountRepository->getAccountsByType($types);
$step = $this->calculateStep($start, $end);
$chartData = [];
$spent = [];
$earned = [];
$current = clone $start;
$current = clone $start;
while ($current <= $end) {
$key = $current->format('Y-m-d');
@ -63,14 +63,14 @@ class WholePeriodChartGenerator
$current = app('navigation')->addPeriod($current, $step, 0);
}
$currencies = $this->extractCurrencies($spent) + $this->extractCurrencies($earned);
$currencies = $this->extractCurrencies($spent) + $this->extractCurrencies($earned);
// generate chart data (for each currency)
/** @var array $currency */
foreach ($currencies as $currency) {
$code = $currency['currency_code'];
$name = $currency['currency_name'];
$chartData[sprintf('spent-in-%s', $code)] = [
$code = $currency['currency_code'];
$name = $currency['currency_name'];
$chartData[sprintf('spent-in-%s', $code)] = [
'label' => (string) trans('firefly.box_spent_in_currency', ['currency' => $name]),
'entries' => [],
'type' => 'bar',
@ -85,11 +85,11 @@ class WholePeriodChartGenerator
];
}
$current = clone $start;
$current = clone $start;
while ($current <= $end) {
$key = $current->format('Y-m-d');
$label = app('navigation')->periodShow($current, $step);
$key = $current->format('Y-m-d');
$label = app('navigation')->periodShow($current, $step);
/** @var array $currency */
foreach ($currencies as $currency) {

View File

@ -46,7 +46,7 @@ class ChartData
if (array_key_exists('native_currency_id', $data)) {
$data['native_currency_id'] = (string) $data['native_currency_id'];
}
$required = ['start', 'date', 'end', 'entries', 'native_entries'];
$required = ['start', 'date', 'end', 'entries', 'native_entries'];
foreach ($required as $field) {
if (!array_key_exists($field, $data)) {
throw new FireflyException(sprintf('Data-set is missing the "%s"-variable.', $field));

View File

@ -55,7 +55,7 @@ class ChartColour
public static function getColour(int $index): string
{
$index %= count(self::$colours);
$row = self::$colours[$index];
$row = self::$colours[$index];
return sprintf('rgba(%d, %d, %d, 0.7)', $row[0], $row[1], $row[2]);
}

View File

@ -68,7 +68,7 @@ class AutoBudgetCronjob extends AbstractCronjob
app('log')->info(sprintf('Will now fire auto budget cron job task for date "%s".', $this->date->format('Y-m-d')));
/** @var CreateAutoBudgetLimits $job */
$job = app(CreateAutoBudgetLimits::class, [$this->date]);
$job = app(CreateAutoBudgetLimits::class, [$this->date]);
$job->setDate($this->date);
$job->handle();

View File

@ -80,7 +80,7 @@ class BillWarningCronjob extends AbstractCronjob
app('log')->info(sprintf('Will now fire bill warning job task for date "%s".', $this->date->format('Y-m-d H:i:s')));
/** @var WarnAboutBills $job */
$job = app(WarnAboutBills::class);
$job = app(WarnAboutBills::class);
$job->setDate($this->date);
$job->setForce($this->force);
$job->handle();

View File

@ -69,7 +69,7 @@ class ExchangeRatesCronjob extends AbstractCronjob
app('log')->info(sprintf('Will now fire exchange rates cron job task for date "%s".', $this->date->format('Y-m-d')));
/** @var DownloadExchangeRates $job */
$job = app(DownloadExchangeRates::class);
$job = app(DownloadExchangeRates::class);
$job->setDate($this->date);
$job->handle();

View File

@ -78,7 +78,7 @@ class RecurringCronjob extends AbstractCronjob
{
app('log')->info(sprintf('Will now fire recurring cron job task for date "%s".', $this->date->format('Y-m-d H:i:s')));
$job = new CreateRecurringTransactions($this->date);
$job = new CreateRecurringTransactions($this->date);
$job->setForce($this->force);
$job->handle();

View File

@ -27,7 +27,6 @@ use Eloquent;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\Form\FormSupport;
use Illuminate\Support\Collection;
use Throwable;
/**
* Class ExpandedForm.
@ -43,7 +42,7 @@ class ExpandedForm
*/
public function amountNoCurrency(string $name, $value = null, ?array $options = null): string
{
$options ??= [];
$options ??= [];
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
@ -57,7 +56,7 @@ class ExpandedForm
// }
try {
$html = view('form.amount-no-currency', compact('classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Could not render amountNoCurrency(): %s', $e->getMessage()));
$html = 'Could not render amountNoCurrency.';
@ -74,8 +73,8 @@ class ExpandedForm
*/
public function checkbox(string $name, ?int $value = null, $checked = null, ?array $options = null): string
{
$options ??= [];
$value ??= 1;
$options ??= [];
$value ??= 1;
$options['checked'] = true === $checked;
if (app('session')->has('preFilled')) {
@ -83,16 +82,16 @@ class ExpandedForm
$options['checked'] = $preFilled[$name] ?? $options['checked'];
}
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
unset($options['placeholder'], $options['autocomplete'], $options['class']);
try {
$html = view('form.checkbox', compact('classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render checkbox(): %s', $e->getMessage()));
$html = 'Could not render checkbox.';
@ -117,7 +116,7 @@ class ExpandedForm
try {
$html = view('form.date', compact('classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render date(): %s', $e->getMessage()));
$html = 'Could not render date.';
@ -139,7 +138,7 @@ class ExpandedForm
try {
$html = view('form.file', compact('classes', 'name', 'label', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render file(): %s', $e->getMessage()));
$html = 'Could not render file.';
@ -157,15 +156,15 @@ class ExpandedForm
public function integer(string $name, $value = null, ?array $options = null): string
{
$options ??= [];
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
$options['step'] ??= '1';
try {
$html = view('form.integer', compact('classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render integer(): %s', $e->getMessage()));
$html = 'Could not render integer.';
@ -190,7 +189,7 @@ class ExpandedForm
try {
$html = view('form.location', compact('classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render location(): %s', $e->getMessage()));
$html = 'Could not render location.';
@ -206,12 +205,12 @@ class ExpandedForm
$selectList[0] = '(none)';
$fields = ['title', 'name', 'description'];
/** @var Eloquent $entry */
/** @var \Eloquent $entry */
foreach ($set as $entry) {
// All Eloquent models have an ID
$entryId = $entry->id; // @phpstan-ignore-line
$current = $entry->toArray();
$title = null;
$entryId = $entry->id; // @phpstan-ignore-line
$current = $entry->toArray();
$title = null;
foreach ($fields as $field) {
if (array_key_exists($field, $current) && null === $title) {
$title = $current[$field];
@ -243,7 +242,7 @@ class ExpandedForm
try {
$html = view('form.object_group', compact('classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render objectGroup(): %s', $e->getMessage()));
$html = 'Could not render objectGroup.';
@ -260,7 +259,7 @@ class ExpandedForm
{
try {
$html = view('form.options', compact('type', 'name'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render select(): %s', $e->getMessage()));
$html = 'Could not render optionsList.';
@ -281,7 +280,7 @@ class ExpandedForm
try {
$html = view('form.password', compact('classes', 'name', 'label', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render password(): %s', $e->getMessage()));
$html = 'Could not render password.';
@ -302,7 +301,7 @@ class ExpandedForm
try {
$html = view('form.password', compact('classes', 'value', 'name', 'label', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render passwordWithValue(): %s', $e->getMessage()));
$html = 'Could not render passwordWithValue.';
@ -330,7 +329,7 @@ class ExpandedForm
try {
$html = view('form.percentage', compact('classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render percentage(): %s', $e->getMessage()));
$html = 'Could not render percentage.';
@ -353,7 +352,7 @@ class ExpandedForm
try {
$html = view('form.static', compact('classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render staticText(): %s', $e->getMessage()));
$html = 'Could not render staticText.';
@ -377,7 +376,7 @@ class ExpandedForm
try {
$html = view('form.text', compact('classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render text(): %s', $e->getMessage()));
$html = 'Could not render text.';
@ -406,7 +405,7 @@ class ExpandedForm
try {
$html = view('form.textarea', compact('classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render textarea(): %s', $e->getMessage()));
$html = 'Could not render textarea.';

View File

@ -82,8 +82,8 @@ class ExportDataGenerator
public function __construct()
{
$this->accounts = new Collection();
$this->start = today(config('app.timezone'));
$this->accounts = new Collection();
$this->start = today(config('app.timezone'));
$this->start->subYear();
$this->end = today(config('app.timezone'));
$this->exportTransactions = false;
@ -141,7 +141,7 @@ class ExportDataGenerator
*/
private function exportAccounts(): string
{
$header = [
$header = [
'user_id',
'account_id',
'created_at',
@ -162,7 +162,7 @@ class ExportDataGenerator
];
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($this->user);
$allAccounts = $repository->getAccountsByType([]);
$records = [];
@ -192,7 +192,7 @@ class ExportDataGenerator
}
// load the CSV document from a string
$csv = Writer::createFromString();
$csv = Writer::createFromString();
// insert the header
try {
@ -230,8 +230,8 @@ class ExportDataGenerator
/** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class);
$repository->setUser($this->user);
$bills = $repository->getBills();
$header = [
$bills = $repository->getBills();
$header = [
'user_id',
'bill_id',
'created_at',
@ -245,7 +245,7 @@ class ExportDataGenerator
'skip',
'active',
];
$records = [];
$records = [];
/** @var Bill $bill */
foreach ($bills as $bill) {
@ -266,7 +266,7 @@ class ExportDataGenerator
}
// load the CSV document from a string
$csv = Writer::createFromString();
$csv = Writer::createFromString();
// insert the header
try {
@ -296,7 +296,7 @@ class ExportDataGenerator
*/
private function exportBudgets(): string
{
$header = [
$header = [
'user_id',
'budget_id',
'name',
@ -310,9 +310,9 @@ class ExportDataGenerator
$budgetRepos = app(BudgetRepositoryInterface::class);
$budgetRepos->setUser($this->user);
$limitRepos = app(BudgetLimitRepositoryInterface::class);
$budgets = $budgetRepos->getBudgets();
$records = [];
$limitRepos = app(BudgetLimitRepositoryInterface::class);
$budgets = $budgetRepos->getBudgets();
$records = [];
/** @var Budget $budget */
foreach ($budgets as $budget) {
@ -335,7 +335,7 @@ class ExportDataGenerator
}
// load the CSV document from a string
$csv = Writer::createFromString();
$csv = Writer::createFromString();
// insert the header
try {
@ -365,10 +365,10 @@ class ExportDataGenerator
*/
private function exportCategories(): string
{
$header = ['user_id', 'category_id', 'created_at', 'updated_at', 'name'];
$header = ['user_id', 'category_id', 'created_at', 'updated_at', 'name'];
/** @var CategoryRepositoryInterface $catRepos */
$catRepos = app(CategoryRepositoryInterface::class);
$catRepos = app(CategoryRepositoryInterface::class);
$catRepos->setUser($this->user);
$records = [];
@ -386,7 +386,7 @@ class ExportDataGenerator
}
// load the CSV document from a string
$csv = Writer::createFromString();
$csv = Writer::createFromString();
// insert the header
try {
@ -417,14 +417,14 @@ class ExportDataGenerator
private function exportPiggies(): string
{
/** @var PiggyBankRepositoryInterface $piggyRepos */
$piggyRepos = app(PiggyBankRepositoryInterface::class);
$piggyRepos = app(PiggyBankRepositoryInterface::class);
$piggyRepos->setUser($this->user);
/** @var AccountRepositoryInterface $accountRepos */
$accountRepos = app(AccountRepositoryInterface::class);
$accountRepos->setUser($this->user);
$header = [
$header = [
'user_id',
'piggy_bank_id',
'created_at',
@ -440,8 +440,8 @@ class ExportDataGenerator
'order',
'active',
];
$records = [];
$piggies = $piggyRepos->getPiggyBanks();
$records = [];
$piggies = $piggyRepos->getPiggyBanks();
/** @var PiggyBank $piggy */
foreach ($piggies as $piggy) {
@ -466,7 +466,7 @@ class ExportDataGenerator
}
// load the CSV document from a string
$csv = Writer::createFromString();
$csv = Writer::createFromString();
// insert the header
try {
@ -499,7 +499,7 @@ class ExportDataGenerator
/** @var RecurringRepositoryInterface $recurringRepos */
$recurringRepos = app(RecurringRepositoryInterface::class);
$recurringRepos->setUser($this->user);
$header = [
$header = [
// recurrence:
'user_id', 'recurrence_id', 'row_contains', 'created_at', 'updated_at', 'type', 'title', 'description', 'first_date', 'repeat_until', 'latest_date', 'repetitions', 'apply_rules', 'active',
@ -508,8 +508,8 @@ class ExportDataGenerator
// transactions + meta:
'currency_code', 'foreign_currency_code', 'source_name', 'source_type', 'destination_name', 'destination_type', 'amount', 'foreign_amount', 'category', 'budget', 'piggy_bank', 'tags',
];
$records = [];
$recurrences = $recurringRepos->getAll();
$records = [];
$recurrences = $recurringRepos->getAll();
/** @var Recurrence $recurrence */
foreach ($recurrences as $recurrence) {
@ -542,7 +542,7 @@ class ExportDataGenerator
$piggyBankId = $recurringRepos->getPiggyBank($transaction);
$tags = $recurringRepos->getTags($transaction);
$records[] = [
$records[] = [
// recurrence
$this->user->id,
$recurrence->id,
@ -558,7 +558,7 @@ class ExportDataGenerator
}
}
// load the CSV document from a string
$csv = Writer::createFromString();
$csv = Writer::createFromString();
// insert the header
try {
@ -595,8 +595,8 @@ class ExportDataGenerator
'action_type', 'action_value', 'action_order', 'action_active', 'action_stop_processing'];
$ruleRepos = app(RuleRepositoryInterface::class);
$ruleRepos->setUser($this->user);
$rules = $ruleRepos->getAll();
$records = [];
$rules = $ruleRepos->getAll();
$records = [];
/** @var Rule $rule */
foreach ($rules as $rule) {
@ -635,7 +635,7 @@ class ExportDataGenerator
}
// load the CSV document from a string
$csv = Writer::createFromString();
$csv = Writer::createFromString();
// insert the header
try {
@ -665,12 +665,12 @@ class ExportDataGenerator
*/
private function exportTags(): string
{
$header = ['user_id', 'tag_id', 'created_at', 'updated_at', 'tag', 'date', 'description', 'latitude', 'longitude', 'zoom_level'];
$header = ['user_id', 'tag_id', 'created_at', 'updated_at', 'tag', 'date', 'description', 'latitude', 'longitude', 'zoom_level'];
$tagRepos = app(TagRepositoryInterface::class);
$tagRepos->setUser($this->user);
$tags = $tagRepos->get();
$records = [];
$tags = $tagRepos->get();
$records = [];
/** @var Tag $tag */
foreach ($tags as $tag) {
@ -689,7 +689,7 @@ class ExportDataGenerator
}
// load the CSV document from a string
$csv = Writer::createFromString();
$csv = Writer::createFromString();
// insert the header
try {
@ -728,26 +728,27 @@ class ExportDataGenerator
private function exportTransactions(): string
{
// TODO better place for keys?
$header = ['user_id', 'group_id', 'journal_id', 'created_at', 'updated_at', 'group_title', 'type', 'amount', 'foreign_amount', 'currency_code', 'foreign_currency_code', 'description', 'date', 'source_name', 'source_iban', 'source_type', 'destination_name', 'destination_iban', 'destination_type', 'reconciled', 'category', 'budget', 'bill', 'tags', 'notes'];
$header = ['user_id', 'group_id', 'journal_id', 'created_at', 'updated_at', 'group_title', 'type', 'amount', 'foreign_amount', 'currency_code', 'foreign_currency_code', 'description', 'date', 'source_name', 'source_iban', 'source_type', 'destination_name', 'destination_iban', 'destination_type', 'reconciled', 'category', 'budget', 'bill', 'tags', 'notes'];
$metaFields = config('firefly.journal_meta_fields');
$header = array_merge($header, $metaFields);
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user);
$collector->setRange($this->start, $this->end)->withAccountInformation()->withCategoryInformation()->withBillInformation()
->withBudgetInformation()->withTagInformation()->withNotes();
->withBudgetInformation()->withTagInformation()->withNotes()
;
if (0 !== $this->accounts->count()) {
$collector->setAccounts($this->accounts);
}
$journals = $collector->getExtractedJournals();
$journals = $collector->getExtractedJournals();
// get repository for meta data:
$repository = app(TransactionGroupRepositoryInterface::class);
$repository->setUser($this->user);
$records = [];
$records = [];
/** @var array $journal */
foreach ($journals as $journal) {
@ -772,7 +773,7 @@ class ExportDataGenerator
}
// load the CSV document from a string
$csv = Writer::createFromString();
$csv = Writer::createFromString();
// insert the header
try {

View File

@ -23,8 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Support;
use Cache;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Configuration;
use Illuminate\Contracts\Encryption\DecryptException;
@ -39,9 +37,9 @@ class FireflyConfig
{
public function delete(string $name): void
{
$fullName = 'ff-config-' . $name;
if (Cache::has($fullName)) {
Cache::forget($fullName);
$fullName = 'ff-config-'.$name;
if (\Cache::has($fullName)) {
\Cache::forget($fullName);
}
Configuration::where('name', $name)->forceDelete();
}
@ -81,20 +79,20 @@ class FireflyConfig
*/
public function get(string $name, $default = null): ?Configuration
{
$fullName = 'ff-config-' . $name;
if (Cache::has($fullName)) {
return Cache::get($fullName);
$fullName = 'ff-config-'.$name;
if (\Cache::has($fullName)) {
return \Cache::get($fullName);
}
try {
/** @var null|Configuration $config */
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
} catch (Exception | QueryException $e) {
} catch (\Exception|QueryException $e) {
throw new FireflyException(sprintf('Could not poll the database: %s', $e->getMessage()), 0, $e);
}
if (null !== $config) {
Cache::forever($fullName, $config);
\Cache::forever($fullName, $config);
return $config;
}
@ -124,13 +122,13 @@ class FireflyConfig
$item->name = $name;
$item->data = $value;
$item->save();
Cache::forget('ff-config-' . $name);
\Cache::forget('ff-config-'.$name);
return $item;
}
$config->data = $value;
$config->save();
Cache::forget('ff-config-' . $name);
\Cache::forget('ff-config-'.$name);
return $config;
}

View File

@ -29,7 +29,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Throwable;
/**
* Class AccountForm
@ -69,7 +68,7 @@ class AccountForm
/** @var Account $account */
foreach ($accountList as $account) {
$role = (string) $repository->getMetaValue($account, 'account_role');
$role = (string) $repository->getMetaValue($account, 'account_role');
if (in_array($account->accountType->type, $liabilityTypes, true)) {
$role = sprintf('l_%s', $account->accountType->type);
}
@ -94,9 +93,9 @@ class AccountForm
*/
public function activeWithdrawalDestinations(string $name, mixed $value = null, ?array $options = null): string
{
$types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::EXPENSE];
$repository = $this->getAccountRepository();
$grouped = $this->getAccountsGrouped($types, $repository);
$types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::EXPENSE];
$repository = $this->getAccountRepository();
$grouped = $this->getAccountsGrouped($types, $repository);
$cash = $repository->getCashAccount();
$key = (string) trans('firefly.cash_account_type');
@ -112,21 +111,21 @@ class AccountForm
*/
public function assetAccountCheckList(string $name, ?array $options = null): string
{
$options ??= [];
$options ??= [];
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
$selected = request()->old($name) ?? [];
// get all asset accounts:
$types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT];
$grouped = $this->getAccountsGrouped($types);
$types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT];
$grouped = $this->getAccountsGrouped($types);
unset($options['class']);
try {
$html = view('form.assetAccountCheckList', compact('classes', 'selected', 'name', 'label', 'options', 'grouped'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render assetAccountCheckList(): %s', $e->getMessage()));
$html = 'Could not render assetAccountCheckList.';

View File

@ -28,7 +28,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use Illuminate\Support\Collection;
use Throwable;
/**
* Class CurrencyForm
@ -62,15 +61,15 @@ class CurrencyForm
$defaultCurrency = $options['currency'] ?? app('amount')->getDefaultCurrency();
/** @var Collection $currencies */
$currencies = app('amount')->getCurrencies();
$currencies = app('amount')->getCurrencies();
unset($options['currency'], $options['placeholder']);
// perhaps the currency has been sent to us in the field $amount_currency_id_$name (amount_currency_id_amount)
$preFilled = session('preFilled');
$preFilled = session('preFilled');
if (!is_array($preFilled)) {
$preFilled = [];
}
$key = 'amount_currency_id_' . $name;
$sentCurrencyId = array_key_exists($key, $preFilled) ? (int) $preFilled[$key] : $defaultCurrency->id;
$key = 'amount_currency_id_'.$name;
$sentCurrencyId = array_key_exists($key, $preFilled) ? (int) $preFilled[$key] : $defaultCurrency->id;
app('log')->debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
@ -90,8 +89,8 @@ class CurrencyForm
}
try {
$html = view('form.' . $view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
$html = view('form.'.$view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
$html = 'Could not render currencyField.';
@ -130,16 +129,16 @@ class CurrencyForm
$defaultCurrency = $options['currency'] ?? app('amount')->getDefaultCurrency();
/** @var Collection $currencies */
$currencies = app('amount')->getAllCurrencies();
$currencies = app('amount')->getAllCurrencies();
unset($options['currency'], $options['placeholder']);
// perhaps the currency has been sent to us in the field $amount_currency_id_$name (amount_currency_id_amount)
$preFilled = session('preFilled');
$preFilled = session('preFilled');
if (!is_array($preFilled)) {
$preFilled = [];
}
$key = 'amount_currency_id_' . $name;
$sentCurrencyId = array_key_exists($key, $preFilled) ? (int) $preFilled[$key] : $defaultCurrency->id;
$key = 'amount_currency_id_'.$name;
$sentCurrencyId = array_key_exists($key, $preFilled) ? (int) $preFilled[$key] : $defaultCurrency->id;
app('log')->debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
@ -159,8 +158,8 @@ class CurrencyForm
}
try {
$html = view('form.' . $view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
} catch (Throwable $e) {
$html = view('form.'.$view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
$html = 'Could not render currencyField.';
@ -181,12 +180,12 @@ class CurrencyForm
$currencyRepos = app(CurrencyRepositoryInterface::class);
// get all currencies:
$list = $currencyRepos->get();
$array = [];
$list = $currencyRepos->get();
$array = [];
/** @var TransactionCurrency $currency */
foreach ($list as $currency) {
$array[$currency->id] = $currency->name . ' (' . $currency->symbol . ')';
$array[$currency->id] = $currency->name.' ('.$currency->symbol.')';
}
return $this->select($name, $array, $value, $options);
@ -203,14 +202,14 @@ class CurrencyForm
$currencyRepos = app(CurrencyRepositoryInterface::class);
// get all currencies:
$list = $currencyRepos->get();
$array = [
$list = $currencyRepos->get();
$array = [
0 => (string) trans('firefly.no_currency'),
];
/** @var TransactionCurrency $currency */
foreach ($list as $currency) {
$array[$currency->id] = $currency->name . ' (' . $currency->symbol . ')';
$array[$currency->id] = $currency->name.' ('.$currency->symbol.')';
}
return $this->select($name, $array, $value, $options);

View File

@ -28,7 +28,6 @@ use Carbon\Carbon;
use Carbon\Exceptions\InvalidDateException;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Support\MessageBag;
use Throwable;
/**
* Trait FormSupport
@ -37,7 +36,7 @@ trait FormSupport
{
public function multiSelect(string $name, ?array $list = null, $selected = null, ?array $options = null): string
{
$list ??= [];
$list ??= [];
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
@ -47,7 +46,7 @@ trait FormSupport
try {
$html = view('form.multi-select', compact('classes', 'name', 'label', 'selected', 'options', 'list'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render multi-select(): %s', $e->getMessage()));
$html = 'Could not render multi-select.';
}
@ -63,7 +62,7 @@ trait FormSupport
}
$name = str_replace('[]', '', $name);
return (string) trans('form.' . $name);
return (string) trans('form.'.$name);
}
/**
@ -71,10 +70,10 @@ trait FormSupport
*/
protected function expandOptionArray(string $name, $label, ?array $options = null): array
{
$options ??= [];
$options ??= [];
$name = str_replace('[]', '', $name);
$options['class'] = 'form-control';
$options['id'] = 'ffInput_' . $name;
$options['id'] = 'ffInput_'.$name;
$options['autocomplete'] = 'off';
$options['placeholder'] = ucfirst($label);
@ -123,7 +122,7 @@ trait FormSupport
*/
public function select(string $name, ?array $list = null, $selected = null, ?array $options = null): string
{
$list ??= [];
$list ??= [];
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
@ -132,7 +131,7 @@ trait FormSupport
try {
$html = view('form.select', compact('classes', 'name', 'label', 'selected', 'options', 'list'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Could not render select(): %s', $e->getMessage()));
$html = 'Could not render select.';
}

View File

@ -62,14 +62,14 @@ class PiggyBankForm
/** @var PiggyBank $piggy */
foreach ($piggyBanks as $piggy) {
$group = $piggy->objectGroups->first();
$groupTitle = null;
$groupOrder = 0;
$group = $piggy->objectGroups->first();
$groupTitle = null;
$groupOrder = 0;
if (null !== $group) {
$groupTitle = $group->title;
$groupOrder = $group->order;
}
$subList[$groupOrder] ??= [
$subList[$groupOrder] ??= [
'group' => [
'title' => $groupTitle,
],

View File

@ -41,8 +41,8 @@ class RuleForm
$groupRepos = app(RuleGroupRepositoryInterface::class);
// get all currencies:
$list = $groupRepos->get();
$array = [];
$list = $groupRepos->get();
$array = [];
/** @var RuleGroup $group */
foreach ($list as $group) {
@ -57,15 +57,15 @@ class RuleForm
*/
public function ruleGroupListWithEmpty(string $name, $value = null, ?array $options = null): string
{
$options ??= [];
$options ??= [];
$options['class'] = 'form-control';
/** @var RuleGroupRepositoryInterface $groupRepos */
$groupRepos = app(RuleGroupRepositoryInterface::class);
$groupRepos = app(RuleGroupRepositoryInterface::class);
// get all currencies:
$list = $groupRepos->get();
$array = [
$list = $groupRepos->get();
$array = [
0 => (string) trans('firefly.none_in_select_list'),
];

View File

@ -64,7 +64,7 @@ class AccountBalanceGrouped
/** @var array $currency */
foreach ($this->data as $currency) {
// income and expense array prepped:
$income = [
$income = [
'label' => 'earned',
'currency_id' => (string) $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
@ -81,7 +81,7 @@ class AccountBalanceGrouped
'entries' => [],
'native_entries' => [],
];
$expense = [
$expense = [
'label' => 'spent',
'currency_id' => (string) $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
@ -101,22 +101,22 @@ class AccountBalanceGrouped
// loop all possible periods between $start and $end, and add them to the correct dataset.
$currentStart = clone $this->start;
while ($currentStart <= $this->end) {
$key = $currentStart->format($this->carbonFormat);
$label = $currentStart->toAtomString();
$key = $currentStart->format($this->carbonFormat);
$label = $currentStart->toAtomString();
// normal entries
$income['entries'][$label] = app('steam')->bcround($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']);
$expense['entries'][$label] = app('steam')->bcround($currency[$key]['spent'] ?? '0', $currency['currency_decimal_places']);
$income['entries'][$label] = app('steam')->bcround($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']);
$expense['entries'][$label] = app('steam')->bcround($currency[$key]['spent'] ?? '0', $currency['currency_decimal_places']);
// converted entries
$income['native_entries'][$label] = app('steam')->bcround($currency[$key]['native_earned'] ?? '0', $currency['native_currency_decimal_places']);
$expense['native_entries'][$label] = app('steam')->bcround($currency[$key]['native_spent'] ?? '0', $currency['native_currency_decimal_places']);
// next loop
$currentStart = app('navigation')->addPeriod($currentStart, $this->preferredRange, 0);
$currentStart = app('navigation')->addPeriod($currentStart, $this->preferredRange, 0);
}
$chartData[] = $income;
$chartData[] = $expense;
$chartData[] = $income;
$chartData[] = $expense;
}
return $chartData;
@ -142,9 +142,9 @@ class AccountBalanceGrouped
private function processJournal(array $journal): void
{
// format the date according to the period
$period = $journal['date']->format($this->carbonFormat);
$currencyId = (int) $journal['currency_id'];
$currency = $this->findCurrency($currencyId);
$period = $journal['date']->format($this->carbonFormat);
$currencyId = (int) $journal['currency_id'];
$currency = $this->findCurrency($currencyId);
// set the array with monetary info, if it does not exist.
$this->createDefaultDataEntry($journal);
@ -152,12 +152,12 @@ class AccountBalanceGrouped
$this->createDefaultPeriodEntry($journal);
// is this journal's amount in- our outgoing?
$key = $this->getDataKey($journal);
$amount = 'spent' === $key ? app('steam')->negative($journal['amount']) : app('steam')->positive($journal['amount']);
$key = $this->getDataKey($journal);
$amount = 'spent' === $key ? app('steam')->negative($journal['amount']) : app('steam')->positive($journal['amount']);
// get conversion rate
$rate = $this->getRate($currency, $journal['date']);
$amountConverted = bcmul($amount, $rate);
$rate = $this->getRate($currency, $journal['date']);
$amountConverted = bcmul($amount, $rate);
// perhaps transaction already has the foreign amount in the native currency.
if ((int) $journal['foreign_currency_id'] === $this->default->id) {
@ -166,7 +166,7 @@ class AccountBalanceGrouped
}
// add normal entry
$this->data[$currencyId][$period][$key] = bcadd($this->data[$currencyId][$period][$key], $amount);
$this->data[$currencyId][$period][$key] = bcadd($this->data[$currencyId][$period][$key], $amount);
// add converted entry
$convertedKey = sprintf('native_%s', $key);
@ -185,7 +185,7 @@ class AccountBalanceGrouped
private function createDefaultDataEntry(array $journal): void
{
$currencyId = (int) $journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$this->data[$currencyId] ??= [
'currency_id' => (string) $currencyId,
'currency_symbol' => $journal['currency_symbol'],
@ -202,8 +202,8 @@ class AccountBalanceGrouped
private function createDefaultPeriodEntry(array $journal): void
{
$currencyId = (int) $journal['currency_id'];
$period = $journal['date']->format($this->carbonFormat);
$currencyId = (int) $journal['currency_id'];
$period = $journal['date']->format($this->carbonFormat);
$this->data[$currencyId][$period] ??= [
'period' => $period,
'spent' => '0',

View File

@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Support\Http\Api;
use Carbon\Carbon;
use DateTimeInterface;
use FireflyIII\Models\TransactionCurrency;
/**
@ -46,7 +45,7 @@ trait ConvertsExchangeRates
// if not enabled, return the same array but without conversion:
return $set;
$this->enabled = false;
$this->enabled = false;
if (false === $this->enabled) {
$set['converted'] = false;
@ -56,8 +55,8 @@ trait ConvertsExchangeRates
$set['converted'] = true;
/** @var TransactionCurrency $native */
$native = app('amount')->getDefaultCurrency();
$currency = $this->getCurrency((int) $set['currency_id']);
$native = app('amount')->getDefaultCurrency();
$currency = $this->getCurrency((int) $set['currency_id']);
if ($native->id === $currency->id) {
$set['native_currency_id'] = (string) $currency->id;
$set['native_currency_code'] = $currency->code;
@ -67,9 +66,9 @@ trait ConvertsExchangeRates
return $set;
}
foreach ($set['entries'] as $date => $entry) {
$carbon = Carbon::createFromFormat(DateTimeInterface::ATOM, $date);
$rate = $this->getRate($currency, $native, $carbon);
$rate = '0' === $rate ? '1' : $rate;
$carbon = Carbon::createFromFormat(\DateTimeInterface::ATOM, $date);
$rate = $this->getRate($currency, $native, $carbon);
$rate = '0' === $rate ? '1' : $rate;
app('log')->debug(sprintf('bcmul("%s", "%s")', (string) $entry, $rate));
$set['entries'][$date] = (float) bcmul((string) $entry, $rate);
}

View File

@ -85,8 +85,8 @@ class ExchangeRateConverter
*/
private function getRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string
{
$key = $this->getCacheKey($from, $to, $date);
$res = Cache::get($key, null);
$key = $this->getCacheKey($from, $to, $date);
$res = Cache::get($key, null);
// find in cache
if (null !== $res) {
@ -96,7 +96,7 @@ class ExchangeRateConverter
}
// find in database
$rate = $this->getFromDB($from->id, $to->id, $date->format('Y-m-d'));
$rate = $this->getFromDB($from->id, $to->id, $date->format('Y-m-d'));
if (null !== $rate) {
Cache::forever($key, $rate);
Log::debug(sprintf('ExchangeRateConverter: Return DB rate from #%d to #%d on %s.', $from->id, $to->id, $date->format('Y-m-d')));
@ -105,7 +105,7 @@ class ExchangeRateConverter
}
// find reverse in database
$rate = $this->getFromDB($to->id, $from->id, $date->format('Y-m-d'));
$rate = $this->getFromDB($to->id, $from->id, $date->format('Y-m-d'));
if (null !== $rate) {
$rate = bcdiv('1', $rate);
Cache::forever($key, $rate);
@ -143,7 +143,7 @@ class ExchangeRateConverter
if ($from === $to) {
return '1';
}
$key = sprintf('cer-%d-%d-%s', $from, $to, $date);
$key = sprintf('cer-%d-%d-%s', $from, $to, $date);
// perhaps the rate has been cached during this particular run
$preparedRate = $this->prepared[$date][$from][$to] ?? null;
@ -153,7 +153,7 @@ class ExchangeRateConverter
return $preparedRate;
}
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty($key);
if ($cache->has()) {
$rate = $cache->get();
@ -166,15 +166,16 @@ class ExchangeRateConverter
}
/** @var null|CurrencyExchangeRate $result */
$result = auth()->user()
?->currencyExchangeRates()
->where('from_currency_id', $from)
->where('to_currency_id', $to)
->where('date', '<=', $date)
->orderBy('date', 'DESC')
->first();
$result = auth()->user()
?->currencyExchangeRates()
->where('from_currency_id', $from)
->where('to_currency_id', $to)
->where('date', '<=', $date)
->orderBy('date', 'DESC')
->first()
;
++$this->queryCount;
$rate = (string) $result?->rate;
$rate = (string) $result?->rate;
if ('' === $rate) {
app('log')->debug(sprintf('ExchangeRateConverter: Found no rate for #%d->#%d (%s) in the DB.', $from, $to, $date));
@ -214,13 +215,13 @@ class ExchangeRateConverter
if ($euroId === $currency->id) {
return '1';
}
$rate = $this->getFromDB($currency->id, $euroId, $date->format('Y-m-d'));
$rate = $this->getFromDB($currency->id, $euroId, $date->format('Y-m-d'));
if (null !== $rate) {
// app('log')->debug(sprintf('Rate for %s to EUR is %s.', $currency->code, $rate));
return $rate;
}
$rate = $this->getFromDB($euroId, $currency->id, $date->format('Y-m-d'));
$rate = $this->getFromDB($euroId, $currency->id, $date->format('Y-m-d'));
if (null !== $rate) {
return bcdiv('1', $rate);
// app('log')->debug(sprintf('Inverted rate for %s to EUR is %s.', $currency->code, $rate));
@ -249,7 +250,7 @@ class ExchangeRateConverter
if ($cache->has()) {
return (int) $cache->get();
}
$euro = TransactionCurrency::whereCode('EUR')->first();
$euro = TransactionCurrency::whereCode('EUR')->first();
++$this->queryCount;
if (null === $euro) {
throw new FireflyException('Cannot find EUR in system, cannot do currency conversion.');
@ -271,13 +272,14 @@ class ExchangeRateConverter
$start->startOfDay();
$end->endOfDay();
Log::debug(sprintf('Preparing for %s to %s between %s and %s', $from->code, $to->code, $start->format('Y-m-d'), $end->format('Y-m-d')));
$set = auth()->user()
->currencyExchangeRates()
->where('from_currency_id', $from->id)
->where('to_currency_id', $to->id)
->where('date', '<=', $end->format('Y-m-d'))
->where('date', '>=', $start->format('Y-m-d'))
->orderBy('date', 'DESC')->get();
$set = auth()->user()
->currencyExchangeRates()
->where('from_currency_id', $from->id)
->where('to_currency_id', $to->id)
->where('date', '<=', $end->format('Y-m-d'))
->where('date', '>=', $start->format('Y-m-d'))
->orderBy('date', 'DESC')->get()
;
++$this->queryCount;
if (0 === $set->count()) {
Log::debug('No prepared rates found in this period, use the fallback');
@ -291,10 +293,10 @@ class ExchangeRateConverter
$this->isPrepared = true;
// so there is a fallback just in case. Now loop the set of rates we DO have.
$temp = [];
$count = 0;
$temp = [];
$count = 0;
foreach ($set as $rate) {
$date = $rate->date->format('Y-m-d');
$date = $rate->date->format('Y-m-d');
$temp[$date] ??= [
$from->id => [
$to->id => $rate->rate,
@ -303,11 +305,11 @@ class ExchangeRateConverter
++$count;
}
Log::debug(sprintf('Found %d rates in this period.', $count));
$currentStart = clone $start;
$currentStart = clone $start;
while ($currentStart->lte($end)) {
$currentDate = $currentStart->format('Y-m-d');
$currentDate = $currentStart->format('Y-m-d');
$this->prepared[$currentDate] ??= [];
$fallback = $temp[$currentDate][$from->id][$to->id] ?? $this->fallback[$from->id][$to->id] ?? '0';
$fallback = $temp[$currentDate][$from->id][$to->id] ?? $this->fallback[$from->id][$to->id] ?? '0';
if (0 === count($this->prepared[$currentDate]) && 0 !== bccomp('0', $fallback)) {
// fill from temp or fallback or from temp (see before)
$this->prepared[$currentDate][$from->id][$to->id] = $fallback;

View File

@ -40,7 +40,7 @@ trait ParsesQueryFilters
private function dateOrToday(QueryParameters $parameters, string $field): Carbon
{
$date = today();
$date = today();
$value = $parameters->filter()?->value($field, date('Y-m-d'));

View File

@ -30,7 +30,7 @@ use Illuminate\Support\Facades\Log;
class SummaryBalanceGrouped
{
private const string SUM = 'sum';
private const string SUM = 'sum';
private array $amounts = [];
private array $currencies;
private CurrencyRepositoryInterface $currencyRepository;
@ -47,9 +47,9 @@ class SummaryBalanceGrouped
public function groupData(): array
{
Log::debug('Now going to group data.');
$return = [];
$return = [];
foreach ($this->keys as $key) {
$title = match ($key) {
$title = match ($key) {
'sum' => 'balance',
'expense' => 'spent',
'income' => 'earned',
@ -108,11 +108,11 @@ class SummaryBalanceGrouped
/** @var array $journal */
foreach ($journals as $journal) {
// transaction info:
$currencyId = (int) $journal['currency_id'];
$amount = bcmul($journal['amount'], $multiplier);
$currency = $this->currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
$this->currencies[$currencyId] = $currency;
$nativeAmount = $converter->convert($currency, $this->default, $journal['date'], $amount);
$currencyId = (int) $journal['currency_id'];
$amount = bcmul($journal['amount'], $multiplier);
$currency = $this->currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
$this->currencies[$currencyId] = $currency;
$nativeAmount = $converter->convert($currency, $this->default, $journal['date'], $amount);
if ((int) $journal['foreign_currency_id'] === $this->default->id) {
// use foreign amount instead
$nativeAmount = $journal['foreign_amount'];

View File

@ -56,8 +56,8 @@ trait ValidatesUserGroupTrait
}
/** @var User $user */
$user = auth()->user();
$groupId = 0;
$user = auth()->user();
$groupId = 0;
if (!$request->has('user_group_id')) {
$groupId = $user->user_group_id;
Log::debug(sprintf('validateUserGroup: no user group submitted, use default group #%d.', $groupId));
@ -68,7 +68,7 @@ trait ValidatesUserGroupTrait
}
/** @var UserGroupRepositoryInterface $repository */
$repository = app(UserGroupRepositoryInterface::class);
$repository = app(UserGroupRepositoryInterface::class);
$repository->setUser($user);
$memberships = $repository->getMembershipsFromGroupId($groupId);
@ -79,14 +79,14 @@ trait ValidatesUserGroupTrait
}
// need to get the group from the membership:
$group = $repository->getById($groupId);
$group = $repository->getById($groupId);
if (null === $group) {
Log::debug(sprintf('validateUserGroup: group #%d does not exist.', $groupId));
throw new AuthorizationException((string) trans('validation.belongs_user_or_user_group'));
}
Log::debug(sprintf('validateUserGroup: validate access of user to group #%d ("%s").', $groupId, $group->title));
$roles = property_exists($this, 'acceptedRoles') ? $this->acceptedRoles : []; // @phpstan-ignore-line
$roles = property_exists($this, 'acceptedRoles') ? $this->acceptedRoles : []; // @phpstan-ignore-line
if (0 === count($roles)) {
Log::debug('validateUserGroup: no roles defined, so no access.');

View File

@ -55,10 +55,10 @@ trait AugumentData
/** @var Account $expenseAccount */
foreach ($accounts as $expenseAccount) {
$collection = new Collection();
$collection = new Collection();
$collection->push($expenseAccount);
$revenue = $repository->findByName($expenseAccount->name, [AccountType::REVENUE]);
$revenue = $repository->findByName($expenseAccount->name, [AccountType::REVENUE]);
if (null !== $revenue) {
$collection->push($revenue);
}
@ -115,7 +115,7 @@ trait AugumentData
$return[$accountId] = $grouped[$accountId][0]['name'];
}
}
$return[0] = '(no name)';
$return[0] = '(no name)';
return $return;
}
@ -135,7 +135,7 @@ trait AugumentData
$return[$budgetId] = $grouped[$budgetId][0]['name'];
}
}
$return[0] = (string) trans('firefly.no_budget');
$return[0] = (string) trans('firefly.no_budget');
return $return;
}
@ -157,7 +157,7 @@ trait AugumentData
$return[$categoryId] = $grouped[$categoryId][0]['name'];
}
}
$return[0] = (string) trans('firefly.no_category');
$return[0] = (string) trans('firefly.no_category');
return $return;
}
@ -168,14 +168,14 @@ trait AugumentData
protected function getLimits(Budget $budget, Carbon $start, Carbon $end): Collection // get data + augment with info
{
/** @var OperationsRepositoryInterface $opsRepository */
$opsRepository = app(OperationsRepositoryInterface::class);
$opsRepository = app(OperationsRepositoryInterface::class);
/** @var BudgetLimitRepositoryInterface $blRepository */
$blRepository = app(BudgetLimitRepositoryInterface::class);
$blRepository = app(BudgetLimitRepositoryInterface::class);
$end->endOfMonth();
// properties for cache
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($budget->id);
@ -191,7 +191,7 @@ trait AugumentData
/** @var BudgetLimit $entry */
foreach ($set as $entry) {
$currency = $entry->transactionCurrency;
$currency = $entry->transactionCurrency;
if (null === $currency) {
$currency = app('amount')->getDefaultCurrency();
@ -227,7 +227,7 @@ trait AugumentData
/** @var array $journal */
foreach ($array as $journal) {
$name = '(no name)';
$name = '(no name)';
if (TransactionType::WITHDRAWAL === $journal['transaction_type_type']) {
$name = $journal['destination_account_name'];
}
@ -250,16 +250,16 @@ trait AugumentData
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$total = $assets->merge($opposing);
$total = $assets->merge($opposing);
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setAccounts($total);
$journals = $collector->getExtractedJournals();
$sum = [
$journals = $collector->getExtractedJournals();
$sum = [
'grand_sum' => '0',
'per_currency' => [],
];
// loop to support multi currency
foreach ($journals as $journal) {
$currencyId = (int) $journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
// if not set, set to zero:
if (!array_key_exists($currencyId, $sum['per_currency'])) {

View File

@ -46,7 +46,7 @@ trait ChartGeneration
protected function accountBalanceChart(Collection $accounts, Carbon $start, Carbon $end): array // chart helper method.
{
// chart properties for cache:
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.account.account-balance-chart');
@ -56,21 +56,21 @@ trait ChartGeneration
// return $cache->get();
}
app('log')->debug('Regenerate chart.account.account-balance-chart from scratch.');
$locale = app('steam')->getLocale();
$locale = app('steam')->getLocale();
/** @var GeneratorInterface $generator */
$generator = app(GeneratorInterface::class);
$generator = app(GeneratorInterface::class);
/** @var AccountRepositoryInterface $accountRepos */
$accountRepos = app(AccountRepositoryInterface::class);
$accountRepos = app(AccountRepositoryInterface::class);
$default = app('amount')->getDefaultCurrency();
$chartData = [];
$default = app('amount')->getDefaultCurrency();
$chartData = [];
/** @var Account $account */
foreach ($accounts as $account) {
// TODO we can use getAccountCurrency instead.
$currency = $accountRepos->getAccountCurrency($account);
$currency = $accountRepos->getAccountCurrency($account);
if (null === $currency) {
$currency = $default;
}
@ -79,7 +79,7 @@ trait ChartGeneration
$currency = $default;
}
$currentSet = [
$currentSet = [
'label' => $account->name,
'currency_symbol' => $currency->symbol,
'entries' => [],
@ -89,16 +89,16 @@ trait ChartGeneration
$range = Steam::finalAccountBalanceInRange($account, $start, clone $end);
$previous = array_values($range)[0];
while ($currentStart <= $end) {
$format = $currentStart->format('Y-m-d');
$label = trim($currentStart->isoFormat((string) trans('config.month_and_day_js', [], $locale)));
$balance = $range[$format] ?? $previous;
$previous = $balance;
$format = $currentStart->format('Y-m-d');
$label = trim($currentStart->isoFormat((string) trans('config.month_and_day_js', [], $locale)));
$balance = $range[$format] ?? $previous;
$previous = $balance;
$currentStart->addDay();
$currentSet['entries'][$label] = $balance['balance']; // TODO or native_balance
}
$chartData[] = $currentSet;
$chartData[] = $currentSet;
}
$data = $generator->multiSet($chartData);
$data = $generator->multiSet($chartData);
$cache->store($data);
return $data;

View File

@ -102,7 +102,7 @@ trait CreateStuff
return;
}
$key = RSA::createKey(4096);
$key = RSA::createKey(4096);
Log::alert('NO OAuth keys were found. They have been created.');

View File

@ -90,19 +90,19 @@ trait DateCalculation
protected function getNextPeriods(Carbon $date, string $range): array
{
// select thing for next 12 periods:
$loop = [];
$loop = [];
/** @var Carbon $current */
$current = app('navigation')->startOfPeriod($date, $range);
$current = app('navigation')->endOfPeriod($current, $range);
$current->addDay();
$count = 0;
$count = 0;
while ($count < 12) {
$current = app('navigation')->endOfPeriod($current, $range);
$currentStart = app('navigation')->startOfPeriod($current, $range);
$loop[] = [
$loop[] = [
'label' => $current->format('Y-m-d'),
'title' => app('navigation')->periodShow($current, $range),
'start' => clone $currentStart,
@ -122,7 +122,7 @@ trait DateCalculation
protected function getPreviousPeriods(Carbon $date, string $range): array
{
// select thing for last 12 periods:
$loop = [];
$loop = [];
/** @var Carbon $current */
$current = app('navigation')->startOfPeriod($date, $range);

View File

@ -61,13 +61,13 @@ trait GetConfigurationData
$steps = [];
if (is_array($elements) && count($elements) > 0) {
foreach ($elements as $key => $options) {
$currentStep = $options;
$currentStep = $options;
// get the text:
$currentStep['intro'] = (string) trans('intro.' . $route . '_' . $key);
$currentStep['intro'] = (string) trans('intro.'.$route.'_'.$key);
// save in array:
$steps[] = $currentStep;
$steps[] = $currentStep;
}
}
app('log')->debug(sprintf('Total basic steps for %s is %d', $routeKey, count($steps)));
@ -82,22 +82,22 @@ trait GetConfigurationData
*/
protected function getDateRangeConfig(): array // get configuration + get preferences.
{
$viewRange = app('navigation')->getViewRange(false);
$viewRange = app('navigation')->getViewRange(false);
Log::debug(sprintf('dateRange: the view range is "%s"', $viewRange));
/** @var Carbon $start */
$start = session('start');
$start = session('start');
/** @var Carbon $end */
$end = session('end');
$end = session('end');
/** @var Carbon $first */
$first = session('first');
$title = sprintf('%s - %s', $start->isoFormat($this->monthAndDayFormat), $end->isoFormat($this->monthAndDayFormat));
$isCustom = true === session('is_custom_range', false);
$today = today(config('app.timezone'));
$ranges = [
$first = session('first');
$title = sprintf('%s - %s', $start->isoFormat($this->monthAndDayFormat), $end->isoFormat($this->monthAndDayFormat));
$isCustom = true === session('is_custom_range', false);
$today = today(config('app.timezone'));
$ranges = [
// first range is the current range:
$title => [$start, $end],
];
@ -127,10 +127,10 @@ trait GetConfigurationData
// today:
/** @var Carbon $todayStart */
$todayStart = app('navigation')->startOfPeriod($today, $viewRange);
$todayStart = app('navigation')->startOfPeriod($today, $viewRange);
/** @var Carbon $todayEnd */
$todayEnd = app('navigation')->endOfPeriod($todayStart, $viewRange);
$todayEnd = app('navigation')->endOfPeriod($todayStart, $viewRange);
if ($todayStart->ne($start) || $todayEnd->ne($end)) {
$ranges[ucfirst((string) trans('firefly.today'))] = [$todayStart, $todayEnd];
@ -186,16 +186,16 @@ trait GetConfigurationData
// user is on page with specific instructions:
if ('' !== $specificPage) {
$routeKey = str_replace('.', '_', $route);
$elements = config(sprintf('intro.%s', $routeKey . '_' . $specificPage));
$elements = config(sprintf('intro.%s', $routeKey.'_'.$specificPage));
if (is_array($elements) && count($elements) > 0) {
foreach ($elements as $key => $options) {
$currentStep = $options;
$currentStep = $options;
// get the text:
$currentStep['intro'] = (string) trans('intro.' . $route . '_' . $specificPage . '_' . $key);
$currentStep['intro'] = (string) trans('intro.'.$route.'_'.$specificPage.'_'.$key);
// save in array:
$steps[] = $currentStep;
$steps[] = $currentStep;
}
}
}

View File

@ -32,7 +32,6 @@ use FireflyIII\Models\Tag;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Throwable;
/**
* Trait ModelInformation
@ -56,7 +55,7 @@ trait ModelInformation
'count' => 1,
]
)->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Throwable was thrown in getActionsForBill(): %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
$result = 'Could not render view. See log files.';
@ -75,14 +74,14 @@ trait ModelInformation
protected function getLiabilityTypes(): array
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository = app(AccountRepositoryInterface::class);
// types of liability:
/** @var AccountType $debt */
$debt = $repository->getAccountTypeByType(AccountType::DEBT);
$debt = $repository->getAccountTypeByType(AccountType::DEBT);
/** @var AccountType $loan */
$loan = $repository->getAccountTypeByType(AccountType::LOAN);
$loan = $repository->getAccountTypeByType(AccountType::LOAN);
/** @var AccountType $mortgage */
$mortgage = $repository->getAccountTypeByType(AccountType::MORTGAGE);
@ -114,8 +113,8 @@ trait ModelInformation
protected function getTriggersForBill(Bill $bill): array // get info and argument
{
// TODO duplicate code
$operators = config('search.operators');
$triggers = [];
$operators = config('search.operators');
$triggers = [];
foreach ($operators as $key => $operator) {
if ('user_action' !== $key && false === $operator['alias']) {
$triggers[$key] = (string) trans(sprintf('firefly.rule_trigger_%s_choice', $key));
@ -143,7 +142,7 @@ trait ModelInformation
'triggers' => $triggers,
]
)->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Throwable was thrown in getTriggersForBill(): %s', $e->getMessage()));
app('log')->debug($e->getTraceAsString());
@ -165,8 +164,8 @@ trait ModelInformation
private function getTriggersForJournal(TransactionJournal $journal): array
{
// TODO duplicated code.
$operators = config('search.operators');
$triggers = [];
$operators = config('search.operators');
$triggers = [];
foreach ($operators as $key => $operator) {
if ('user_action' !== $key && false === $operator['alias']) {
$triggers[$key] = (string) trans(sprintf('firefly.rule_trigger_%s_choice', $key));
@ -174,18 +173,18 @@ trait ModelInformation
}
asort($triggers);
$result = [];
$journalTriggers = [];
$values = [];
$index = 0;
$result = [];
$journalTriggers = [];
$values = [];
$index = 0;
// amount, description, category, budget, tags, source, destination, notes, currency type
// ,type
/** @var null|Transaction $source */
$source = $journal->transactions()->where('amount', '<', 0)->first();
$source = $journal->transactions()->where('amount', '<', 0)->first();
/** @var null|Transaction $destination */
$destination = $journal->transactions()->where('amount', '>', 0)->first();
$destination = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $destination || null === $source) {
return $result;
}
@ -220,21 +219,21 @@ trait ModelInformation
++$index;
// category (if)
$category = $journal->categories()->first();
$category = $journal->categories()->first();
if (null !== $category) {
$journalTriggers[$index] = 'category_is';
$values[$index] = $category->name;
++$index;
}
// budget (if)
$budget = $journal->budgets()->first();
$budget = $journal->budgets()->first();
if (null !== $budget) {
$journalTriggers[$index] = 'budget_is';
$values[$index] = $budget->name;
++$index;
}
// tags (if)
$tags = $journal->tags()->get();
$tags = $journal->tags()->get();
/** @var Tag $tag */
foreach ($tags as $tag) {
@ -243,7 +242,7 @@ trait ModelInformation
++$index;
}
// notes (if)
$notes = $journal->notes()->first();
$notes = $journal->notes()->first();
if (null !== $notes) {
$journalTriggers[$index] = 'notes_are';
$values[$index] = $notes->text;
@ -259,7 +258,7 @@ trait ModelInformation
'triggers' => $triggers,
];
$string = view('rules.partials.trigger', $renderInfo)->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Throwable was thrown in getTriggersForJournal(): %s', $e->getMessage()));
app('log')->debug($e->getTraceAsString());

View File

@ -75,11 +75,11 @@ trait PeriodOverview
*/
protected function getAccountPeriodOverview(Account $account, Carbon $start, Carbon $end): array
{
$range = app('navigation')->getViewRange(true);
$range = app('navigation')->getViewRange(true);
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
// properties for cache
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('account-show-period-entries');
@ -89,32 +89,32 @@ trait PeriodOverview
}
/** @var array $dates */
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
// collect all expenses in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]));
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::DEPOSIT]);
$earnedSet = $collector->getExtractedJournals();
$earnedSet = $collector->getExtractedJournals();
// collect all income in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]));
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::WITHDRAWAL]);
$spentSet = $collector->getExtractedJournals();
$spentSet = $collector->getExtractedJournals();
// collect all transfers in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]));
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::TRANSFER]);
$transferSet = $collector->getExtractedJournals();
$transferSet = $collector->getExtractedJournals();
// loop dates
foreach ($dates as $currentDate) {
@ -125,15 +125,15 @@ trait PeriodOverview
$transferredIn = $this->filterTransferredIn($account, $this->filterJournalsByDate($transferSet, $currentDate['start'], $currentDate['end']));
$entries[]
= [
'title' => $title,
'route' => route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
'title' => $title,
'route' => route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
'total_transactions' => count($spent) + count($earned) + count($transferredAway) + count($transferredIn),
'spent' => $this->groupByCurrency($spent),
'earned' => $this->groupByCurrency($earned),
'transferred_away' => $this->groupByCurrency($transferredAway),
'transferred_in' => $this->groupByCurrency($transferredIn),
];
'total_transactions' => count($spent) + count($earned) + count($transferredAway) + count($transferredIn),
'spent' => $this->groupByCurrency($spent),
'earned' => $this->groupByCurrency($earned),
'transferred_away' => $this->groupByCurrency($transferredAway),
'transferred_in' => $this->groupByCurrency($transferredIn),
];
}
$cache->store($entries);
@ -197,8 +197,8 @@ trait PeriodOverview
/** @var array $journal */
foreach ($journals as $journal) {
$currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = $journal['foreign_currency_id'];
$currencyId = (int) $journal['currency_id'];
$foreignCurrencyId = $journal['foreign_currency_id'];
if (!array_key_exists($currencyId, $return)) {
$return[$currencyId] = [
'amount' => '0',
@ -240,11 +240,11 @@ trait PeriodOverview
*/
protected function getCategoryPeriodOverview(Category $category, Carbon $start, Carbon $end): array
{
$range = app('navigation')->getViewRange(true);
$range = app('navigation')->getViewRange(true);
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
// properties for entries with their amounts.
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($range);
@ -256,32 +256,32 @@ trait PeriodOverview
}
/** @var array $dates */
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
// collect all expenses in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setCategory($category);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::DEPOSIT]);
$earnedSet = $collector->getExtractedJournals();
$earnedSet = $collector->getExtractedJournals();
// collect all income in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setCategory($category);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::WITHDRAWAL]);
$spentSet = $collector->getExtractedJournals();
$spentSet = $collector->getExtractedJournals();
// collect all transfers in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setCategory($category);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::TRANSFER]);
$transferSet = $collector->getExtractedJournals();
$transferSet = $collector->getExtractedJournals();
foreach ($dates as $currentDate) {
$spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']);
$earned = $this->filterJournalsByDate($earnedSet, $currentDate['start'], $currentDate['end']);
@ -289,17 +289,17 @@ trait PeriodOverview
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
$entries[]
= [
'transactions' => 0,
'title' => $title,
'route' => route(
'categories.show',
[$category->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
),
'total_transactions' => count($spent) + count($earned) + count($transferred),
'spent' => $this->groupByCurrency($spent),
'earned' => $this->groupByCurrency($earned),
'transferred' => $this->groupByCurrency($transferred),
];
'transactions' => 0,
'title' => $title,
'route' => route(
'categories.show',
[$category->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
),
'total_transactions' => count($spent) + count($earned) + count($transferred),
'spent' => $this->groupByCurrency($spent),
'earned' => $this->groupByCurrency($earned),
'transferred' => $this->groupByCurrency($transferred),
];
}
$cache->store($entries);
@ -315,11 +315,11 @@ trait PeriodOverview
*/
protected function getNoBudgetPeriodOverview(Carbon $start, Carbon $end): array
{
$range = app('navigation')->getViewRange(true);
$range = app('navigation')->getViewRange(true);
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('no-budget-period-entries');
@ -329,28 +329,28 @@ trait PeriodOverview
}
/** @var array $dates */
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
// get all expenses without a budget.
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->withoutBudget()->withAccountInformation()->setTypes([TransactionType::WITHDRAWAL]);
$journals = $collector->getExtractedJournals();
$journals = $collector->getExtractedJournals();
foreach ($dates as $currentDate) {
$set = $this->filterJournalsByDate($journals, $currentDate['start'], $currentDate['end']);
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
$entries[]
= [
'title' => $title,
'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
'total_transactions' => count($set),
'spent' => $this->groupByCurrency($set),
'earned' => [],
'transferred_away' => [],
'transferred_in' => [],
];
'title' => $title,
'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
'total_transactions' => count($set),
'spent' => $this->groupByCurrency($set),
'earned' => [],
'transferred_away' => [],
'transferred_in' => [],
];
}
$cache->store($entries);
@ -367,38 +367,38 @@ trait PeriodOverview
protected function getNoCategoryPeriodOverview(Carbon $theDate): array
{
app('log')->debug(sprintf('Now in getNoCategoryPeriodOverview(%s)', $theDate->format('Y-m-d')));
$range = app('navigation')->getViewRange(true);
$first = $this->journalRepos->firstNull();
$start = null === $first ? new Carbon() : $first->date;
$end = clone $theDate;
$end = app('navigation')->endOfPeriod($end, $range);
$range = app('navigation')->getViewRange(true);
$first = $this->journalRepos->firstNull();
$start = null === $first ? new Carbon() : $first->date;
$end = clone $theDate;
$end = app('navigation')->endOfPeriod($end, $range);
app('log')->debug(sprintf('Start for getNoCategoryPeriodOverview() is %s', $start->format('Y-m-d')));
app('log')->debug(sprintf('End for getNoCategoryPeriodOverview() is %s', $end->format('Y-m-d')));
// properties for cache
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
// collect all expenses in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->withoutCategory();
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::DEPOSIT]);
$earnedSet = $collector->getExtractedJournals();
$earnedSet = $collector->getExtractedJournals();
// collect all income in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->withoutCategory();
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::WITHDRAWAL]);
$spentSet = $collector->getExtractedJournals();
$spentSet = $collector->getExtractedJournals();
// collect all transfers in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->withoutCategory();
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::TRANSFER]);
@ -412,13 +412,13 @@ trait PeriodOverview
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
$entries[]
= [
'title' => $title,
'route' => route('categories.no-category', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
'total_transactions' => count($spent) + count($earned) + count($transferred),
'spent' => $this->groupByCurrency($spent),
'earned' => $this->groupByCurrency($earned),
'transferred' => $this->groupByCurrency($transferred),
];
'title' => $title,
'route' => route('categories.no-category', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
'total_transactions' => count($spent) + count($earned) + count($transferred),
'spent' => $this->groupByCurrency($spent),
'earned' => $this->groupByCurrency($earned),
'transferred' => $this->groupByCurrency($transferred),
];
}
app('log')->debug('End of loops');
@ -432,11 +432,11 @@ trait PeriodOverview
*/
protected function getTagPeriodOverview(Tag $tag, Carbon $start, Carbon $end): array // period overview for tags.
{
$range = app('navigation')->getViewRange(true);
$range = app('navigation')->getViewRange(true);
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
// properties for cache
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('tag-period-entries');
@ -446,37 +446,37 @@ trait PeriodOverview
}
/** @var array $dates */
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
// collect all expenses in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setTag($tag);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::DEPOSIT]);
$earnedSet = $collector->getExtractedJournals();
$earnedSet = $collector->getExtractedJournals();
// collect all income in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setTag($tag);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::WITHDRAWAL]);
$spentSet = $collector->getExtractedJournals();
$spentSet = $collector->getExtractedJournals();
// collect all transfers in this period:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setTag($tag);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::TRANSFER]);
$transferSet = $collector->getExtractedJournals();
$transferSet = $collector->getExtractedJournals();
// filer all of them:
$earnedSet = $this->filterJournalsByTag($earnedSet, $tag);
$spentSet = $this->filterJournalsByTag($spentSet, $tag);
$transferSet = $this->filterJournalsByTag($transferSet, $tag);
$earnedSet = $this->filterJournalsByTag($earnedSet, $tag);
$spentSet = $this->filterJournalsByTag($spentSet, $tag);
$transferSet = $this->filterJournalsByTag($transferSet, $tag);
foreach ($dates as $currentDate) {
$spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']);
@ -485,17 +485,17 @@ trait PeriodOverview
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
$entries[]
= [
'transactions' => 0,
'title' => $title,
'route' => route(
'tags.show',
[$tag->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
),
'total_transactions' => count($spent) + count($earned) + count($transferred),
'spent' => $this->groupByCurrency($spent),
'earned' => $this->groupByCurrency($earned),
'transferred' => $this->groupByCurrency($transferred),
];
'transactions' => 0,
'title' => $title,
'route' => route(
'tags.show',
[$tag->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
),
'total_transactions' => count($spent) + count($earned) + count($transferred),
'spent' => $this->groupByCurrency($spent),
'earned' => $this->groupByCurrency($earned),
'transferred' => $this->groupByCurrency($transferred),
];
}
return $entries;
@ -505,7 +505,7 @@ trait PeriodOverview
{
$return = [];
foreach ($set as $entry) {
$found = false;
$found = false;
/** @var array $localTag */
foreach ($entry['tags'] as $localTag) {
@ -527,12 +527,12 @@ trait PeriodOverview
*/
protected function getTransactionPeriodOverview(string $transactionType, Carbon $start, Carbon $end): array
{
$range = app('navigation')->getViewRange(true);
$types = config(sprintf('firefly.transactionTypesByType.%s', $transactionType));
$range = app('navigation')->getViewRange(true);
$types = config(sprintf('firefly.transactionTypesByType.%s', $transactionType));
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
// properties for cache
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('transactions-period-entries');
@ -542,13 +542,13 @@ trait PeriodOverview
}
/** @var array $dates */
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = [];
// collect all journals in this period (regardless of type)
$collector = app(GroupCollectorInterface::class);
$collector = app(GroupCollectorInterface::class);
$collector->setTypes($types)->setRange($start, $end);
$genericSet = $collector->getExtractedJournals();
$genericSet = $collector->getExtractedJournals();
foreach ($dates as $currentDate) {
$spent = [];
@ -567,14 +567,14 @@ trait PeriodOverview
$transferred = $this->filterJournalsByDate($genericSet, $currentDate['start'], $currentDate['end']);
}
$entries[]
= [
'title' => $title,
'route' => route('transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
'total_transactions' => count($spent) + count($earned) + count($transferred),
'spent' => $this->groupByCurrency($spent),
'earned' => $this->groupByCurrency($earned),
'transferred' => $this->groupByCurrency($transferred),
];
= [
'title' => $title,
'route' => route('transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
'total_transactions' => count($spent) + count($earned) + count($transferred),
'spent' => $this->groupByCurrency($spent),
'earned' => $this->groupByCurrency($earned),
'transferred' => $this->groupByCurrency($transferred),
];
}
return $entries;

View File

@ -37,7 +37,6 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\Search\OperatorQuerySearch;
use Throwable;
/**
* Trait RenderPartialViews
@ -52,24 +51,24 @@ trait RenderPartialViews
protected function budgetEntry(array $attributes): string // generate view for report.
{
/** @var PopupReportInterface $popupHelper */
$popupHelper = app(PopupReportInterface::class);
$popupHelper = app(PopupReportInterface::class);
/** @var BudgetRepositoryInterface $budgetRepository */
$budgetRepository = app(BudgetRepositoryInterface::class);
$budget = $budgetRepository->find((int) $attributes['budgetId']);
$accountRepos = app(AccountRepositoryInterface::class);
$account = $accountRepos->find((int) $attributes['accountId']);
$accountRepos = app(AccountRepositoryInterface::class);
$account = $accountRepos->find((int) $attributes['accountId']);
if (null === $budget || null === $account) {
throw new FireflyException('Could not render popup.report.balance-amount because budget or account is null.');
}
$journals = $popupHelper->balanceForBudget($budget, $account, $attributes);
$journals = $popupHelper->balanceForBudget($budget, $account, $attributes);
try {
$view = view('popup.report.balance-amount', compact('journals', 'budget', 'account'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Could not render: %s', $e->getMessage()));
$view = 'Firefly III could not render the view. Please see the log files.';
@ -92,7 +91,7 @@ trait RenderPartialViews
try {
$result = view('reports.options.budget', compact('budgets'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Cannot render reports.options.tag: %s', $e->getMessage()));
$result = 'Could not render view.';
@ -113,18 +112,18 @@ trait RenderPartialViews
$budgetRepository = app(BudgetRepositoryInterface::class);
/** @var PopupReportInterface $popupHelper */
$popupHelper = app(PopupReportInterface::class);
$popupHelper = app(PopupReportInterface::class);
$budget = $budgetRepository->find((int) $attributes['budgetId']);
$budget = $budgetRepository->find((int) $attributes['budgetId']);
if (null === $budget) {
// transactions without a budget.
$budget = new Budget();
}
$journals = $popupHelper->byBudget($budget, $attributes);
$journals = $popupHelper->byBudget($budget, $attributes);
try {
$view = view('popup.report.budget-spent-amount', compact('journals', 'budget'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Could not render: %s', $e->getMessage()));
$view = 'Firefly III could not render the view. Please see the log files.';
@ -142,7 +141,7 @@ trait RenderPartialViews
protected function categoryEntry(array $attributes): string // generate view for report.
{
/** @var PopupReportInterface $popupHelper */
$popupHelper = app(PopupReportInterface::class);
$popupHelper = app(PopupReportInterface::class);
/** @var CategoryRepositoryInterface $categoryRepository */
$categoryRepository = app(CategoryRepositoryInterface::class);
@ -151,7 +150,7 @@ trait RenderPartialViews
try {
$view = view('popup.report.category-entry', compact('journals', 'category'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Could not render: %s', $e->getMessage()));
$view = 'Firefly III could not render the view. Please see the log files.';
@ -174,7 +173,7 @@ trait RenderPartialViews
try {
$result = view('reports.options.category', compact('categories'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Cannot render reports.options.category: %s', $e->getMessage()));
$result = 'Could not render view.';
@ -216,7 +215,7 @@ trait RenderPartialViews
try {
$result = view('reports.options.double', compact('set'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Cannot render reports.options.tag: %s', $e->getMessage()));
$result = 'Could not render view.';
@ -237,19 +236,19 @@ trait RenderPartialViews
$accountRepository = app(AccountRepositoryInterface::class);
/** @var PopupReportInterface $popupHelper */
$popupHelper = app(PopupReportInterface::class);
$popupHelper = app(PopupReportInterface::class);
$account = $accountRepository->find((int) $attributes['accountId']);
$account = $accountRepository->find((int) $attributes['accountId']);
if (null === $account) {
return 'This is an unknown account. Apologies.';
}
$journals = $popupHelper->byExpenses($account, $attributes);
$journals = $popupHelper->byExpenses($account, $attributes);
try {
$view = view('popup.report.expense-entry', compact('journals', 'account'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Could not render: %s', $e->getMessage()));
$view = 'Firefly III could not render the view. Please see the log files.';
@ -266,8 +265,8 @@ trait RenderPartialViews
*/
protected function getCurrentActions(Rule $rule): array // get info from object and present.
{
$index = 0;
$actions = [];
$index = 0;
$actions = [];
// must be repos
$currentActions = $rule->ruleActions()->orderBy('order', 'ASC')->get();
@ -285,7 +284,7 @@ trait RenderPartialViews
'count' => $count,
]
)->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Throwable was thrown in getCurrentActions(): %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
@ -306,8 +305,8 @@ trait RenderPartialViews
protected function getCurrentTriggers(Rule $rule): array // get info from object and present.
{
// TODO duplicated code.
$operators = config('search.operators');
$triggers = [];
$operators = config('search.operators');
$triggers = [];
foreach ($operators as $key => $operator) {
if ('user_action' !== $key && false === $operator['alias']) {
$triggers[$key] = (string) trans(sprintf('firefly.rule_trigger_%s_choice', $key));
@ -325,7 +324,7 @@ trait RenderPartialViews
$count = ($index + 1);
try {
$rootOperator = OperatorQuerySearch::getRootOperator((string) $entry->trigger_type);
$rootOperator = OperatorQuerySearch::getRootOperator((string) $entry->trigger_type);
if (str_starts_with($rootOperator, '-')) {
$rootOperator = substr($rootOperator, 1);
}
@ -340,7 +339,7 @@ trait RenderPartialViews
'triggers' => $triggers,
]
)->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Throwable was thrown in getCurrentTriggers(): %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
@ -365,18 +364,18 @@ trait RenderPartialViews
$accountRepository = app(AccountRepositoryInterface::class);
/** @var PopupReportInterface $popupHelper */
$popupHelper = app(PopupReportInterface::class);
$account = $accountRepository->find((int) $attributes['accountId']);
$popupHelper = app(PopupReportInterface::class);
$account = $accountRepository->find((int) $attributes['accountId']);
if (null === $account) {
return 'This is an unknown category. Apologies.';
}
$journals = $popupHelper->byIncome($account, $attributes);
$journals = $popupHelper->byIncome($account, $attributes);
try {
$view = view('popup.report.income-entry', compact('journals', 'account'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Could not render: %s', $e->getMessage()));
$view = 'Firefly III could not render the view. Please see the log files.';
@ -395,7 +394,7 @@ trait RenderPartialViews
{
try {
$result = view('reports.options.no-options')->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Cannot render reports.options.no-options: %s', $e->getMessage()));
$result = 'Could not render view.';
@ -418,7 +417,7 @@ trait RenderPartialViews
try {
$result = view('reports.options.tag', compact('tags'))->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Cannot render reports.options.tag: %s', $e->getMessage()));
$result = 'Could not render view.';

View File

@ -30,7 +30,6 @@ use FireflyIII\Http\Requests\RuleFormRequest;
use FireflyIII\Http\Requests\TestRuleFormRequest;
use FireflyIII\Support\Binder\AccountList;
use FireflyIII\User;
use Hash;
use Illuminate\Contracts\Validation\Validator as ValidatorContract;
use Illuminate\Routing\Route;
use Illuminate\Support\Facades\Validator;
@ -83,13 +82,13 @@ trait RequestInformation
$page = $this->getPageName();
$specificPage = $this->getSpecificPageName();
// indicator if user has seen the help for this page ( + special page):
$key = sprintf('shown_demo_%s%s', $page, $specificPage);
$key = sprintf('shown_demo_%s%s', $page, $specificPage);
// is there an intro for this route?
$intro = config(sprintf('intro.%s', $page)) ?? [];
$specialIntro = config(sprintf('intro.%s%s', $page, $specificPage)) ?? [];
// some routes have a "what" parameter, which indicates a special page:
$shownDemo = true;
$shownDemo = true;
// both must be array and either must be > 0
if (count($intro) > 0 || count($specialIntro) > 0) {
$shownDemo = app('preferences')->get($key, false)->data;
@ -123,7 +122,7 @@ trait RequestInformation
final protected function notInSessionRange(Carbon $date): bool // Validate a preference
{
/** @var Carbon $start */
$start = session('start', today(config('app.timezone'))->startOfMonth());
$start = session('start', today(config('app.timezone'))->startOfMonth());
/** @var Carbon $end */
$end = session('end', today(config('app.timezone'))->endOfMonth());
@ -145,20 +144,20 @@ trait RequestInformation
final protected function parseAttributes(array $attributes): array // parse input + return result
{
$attributes['location'] ??= '';
$attributes['accounts'] = AccountList::routeBinder($attributes['accounts'] ?? '', new Route('get', '', []));
$date = Carbon::createFromFormat('Ymd', $attributes['startDate']);
$attributes['accounts'] = AccountList::routeBinder($attributes['accounts'] ?? '', new Route('get', '', []));
$date = Carbon::createFromFormat('Ymd', $attributes['startDate']);
if (null === $date) {
$date = today(config('app.timezone'));
}
$date->startOfMonth();
$attributes['startDate'] = $date;
$date2 = Carbon::createFromFormat('Ymd', $attributes['endDate']);
$date2 = Carbon::createFromFormat('Ymd', $attributes['endDate']);
if (null === $date2) {
$date2 = today(config('app.timezone'));
}
$date2->endOfDay();
$attributes['endDate'] = $date2;
$attributes['endDate'] = $date2;
return $attributes;
}
@ -170,7 +169,7 @@ trait RequestInformation
*/
final protected function validatePassword(User $user, string $current, string $new): bool // get request info
{
if (!Hash::check($current, $user->password)) {
if (!\Hash::check($current, $user->password)) {
throw new ValidationException((string) trans('firefly.invalid_current_password'));
}

View File

@ -28,7 +28,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\Support\Search\OperatorQuerySearch;
use Illuminate\Http\Request;
use Throwable;
/**
* Trait RuleManagement
@ -55,7 +54,7 @@ trait RuleManagement
'count' => $index + 1,
]
)->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->error(sprintf('Throwable was thrown in getPreviousActions(): %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
@ -74,8 +73,8 @@ trait RuleManagement
protected function getPreviousTriggers(Request $request): array
{
// TODO duplicated code.
$operators = config('search.operators');
$triggers = [];
$operators = config('search.operators');
$triggers = [];
foreach ($operators as $key => $operator) {
if ('user_action' !== $key && false === $operator['alias']) {
$triggers[$key] = (string) trans(sprintf('firefly.rule_trigger_%s_choice', $key));
@ -100,7 +99,7 @@ trait RuleManagement
'triggers' => $triggers,
]
)->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
@ -129,7 +128,7 @@ trait RuleManagement
}
asort($triggers);
$index = 0;
$index = 0;
foreach ($submittedOperators as $operator) {
$rootOperator = OperatorQuerySearch::getRootOperator($operator['type']);
$needsContext = (bool) config(sprintf('search.operators.%s.needs_context', $rootOperator));
@ -146,7 +145,7 @@ trait RuleManagement
'triggers' => $triggers,
]
)->render();
} catch (Throwable $e) {
} catch (\Throwable $e) {
app('log')->debug(sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());

View File

@ -39,14 +39,15 @@ trait TransactionCalculation
*/
protected function getExpensesForOpposing(Collection $accounts, Collection $opposing, Carbon $start, Carbon $end): array
{
$total = $accounts->merge($opposing);
$total = $accounts->merge($opposing);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($total)
->setRange($start, $end)
->withAccountInformation()
->setTypes([TransactionType::WITHDRAWAL]);
->setRange($start, $end)
->withAccountInformation()
->setTypes([TransactionType::WITHDRAWAL])
;
return $collector->getExtractedJournals();
}
@ -60,7 +61,8 @@ trait TransactionCalculation
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
->setTags($tags)->withAccountInformation();
->setTags($tags)->withAccountInformation()
;
return $collector->getExtractedJournals();
}
@ -73,7 +75,8 @@ trait TransactionCalculation
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
->setBudgets($budgets)->withAccountInformation();
->setBudgets($budgets)->withAccountInformation()
;
return $collector->getExtractedJournals();
}
@ -90,7 +93,8 @@ trait TransactionCalculation
->setRange($start, $end)
->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
->setCategories($categories)
->withAccountInformation();
->withAccountInformation()
;
return $collector->getExtractedJournals();
}
@ -103,7 +107,8 @@ trait TransactionCalculation
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
->setCategories($categories)->withAccountInformation();
->setCategories($categories)->withAccountInformation()
;
return $collector->getExtractedJournals();
}
@ -113,7 +118,7 @@ trait TransactionCalculation
*/
protected function getIncomeForOpposing(Collection $accounts, Collection $opposing, Carbon $start, Carbon $end): array
{
$total = $accounts->merge($opposing);
$total = $accounts->merge($opposing);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
@ -130,7 +135,8 @@ trait TransactionCalculation
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
->setTags($tags)->withAccountInformation();
->setTags($tags)->withAccountInformation()
;
return $collector->getExtractedJournals();
}

View File

@ -69,7 +69,7 @@ trait UserNavigation
final protected function isEditableGroup(TransactionGroup $group): bool
{
/** @var null|TransactionJournal $journal */
$journal = $group->transactionJournals()->first();
$journal = $group->transactionJournals()->first();
if (null === $journal) {
return false;
}
@ -96,10 +96,10 @@ trait UserNavigation
return redirect(route('index'));
}
$journal = $transaction->transactionJournal;
$journal = $transaction->transactionJournal;
/** @var null|Transaction $other */
$other = $journal->transactions()->where('id', '!=', $transaction->id)->first();
$other = $journal->transactions()->where('id', '!=', $transaction->id)->first();
if (null === $other) {
app('log')->error(sprintf('Account #%d has no valid journals. Dont know where it belongs.', $account->id));
session()->flash('error', trans('firefly.cant_find_redirect_account'));
@ -119,7 +119,7 @@ trait UserNavigation
final protected function redirectGroupToAccount(TransactionGroup $group)
{
/** @var null|TransactionJournal $journal */
$journal = $group->transactionJournals()->first();
$journal = $group->transactionJournals()->first();
if (null === $journal) {
app('log')->error(sprintf('No journals in group #%d', $group->id));

View File

@ -37,7 +37,7 @@ trait UserGroupDetectable
public function detectUserGroup(): ?UserGroup
{
/** @var User $user */
$user = auth()->user();
$user = auth()->user();
app('log')->debug('Now in detectUserGroup()');
/** @var null|UserGroup $userGroup */
@ -49,7 +49,7 @@ trait UserGroupDetectable
app('log')->debug(sprintf('Request class has no user_group_id parameter, grab default from user (group #%d).', $user->user_group_id));
$userGroupId = (int) $user->user_group_id;
}
$userGroup = UserGroup::find($userGroupId);
$userGroup = UserGroup::find($userGroupId);
if (null === $userGroup) {
app('log')->error(sprintf('Request class has user_group_id (#%d), but group does not exist.', $userGroupId));

View File

@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Support\JsonApi\Enrichments;
use Carbon\Carbon;
use DB;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\ObjectGroup;
@ -37,8 +36,6 @@ use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Override;
use stdClass;
/**
* Class AccountEnrichment
@ -66,7 +63,7 @@ class AccountEnrichment implements EnrichmentInterface
$this->end = null;
}
#[Override]
#[\Override]
public function enrichSingle(Model $model): Account
{
Log::debug(__METHOD__);
@ -76,7 +73,7 @@ class AccountEnrichment implements EnrichmentInterface
return $collection->first();
}
#[Override]
#[\Override]
/**
* Do the actual enrichment.
*/
@ -147,7 +144,7 @@ class AccountEnrichment implements EnrichmentInterface
$metaFields = $this->repository->getMetaValues($this->collection, ['is_multi_currency', 'currency_id', 'account_role', 'account_number', 'liability_direction', 'interest', 'interest_period', 'current_debt']);
$currencyIds = $metaFields->where('name', 'currency_id')->pluck('data')->toArray();
$currencies = [];
$currencies = [];
foreach ($this->currencyRepository->getByIds($currencyIds) as $currency) {
$id = $currency->id;
$currencies[$id] = $currency;
@ -177,8 +174,8 @@ class AccountEnrichment implements EnrichmentInterface
$default = $this->default;
// get start and end, so the balance difference can be generated.
$start = null;
$end = null;
$start = null;
$end = null;
if (null !== $this->start) {
$start = Balance::getAccountBalances($this->collection, $this->start);
}
@ -200,7 +197,7 @@ class AccountEnrichment implements EnrichmentInterface
'balance_difference' => null,
];
if (array_key_exists($account->id, $balances)) {
$set = [];
$set = [];
foreach ($balances[$account->id] as $currencyId => $entry) {
$left = $start[$account->id][$currencyId]['balance'] ?? null;
$right = $end[$account->id][$currencyId]['balance'] ?? null;
@ -242,11 +239,12 @@ class AccountEnrichment implements EnrichmentInterface
private function getObjectGroups(): void
{
$set = DB::table('object_groupables')
->where('object_groupable_type', Account::class)
->whereIn('object_groupable_id', $this->collection->pluck('id')->toArray())
->distinct()
->get(['object_groupables.object_groupable_id', 'object_groupables.object_group_id']);
$set = \DB::table('object_groupables')
->where('object_groupable_type', Account::class)
->whereIn('object_groupable_id', $this->collection->pluck('id')->toArray())
->distinct()
->get(['object_groupables.object_groupable_id', 'object_groupables.object_group_id'])
;
// get the groups:
$groupIds = $set->pluck('object_group_id')->toArray();
$groups = ObjectGroup::whereIn('id', $groupIds)->get();
@ -256,7 +254,7 @@ class AccountEnrichment implements EnrichmentInterface
$this->objectGroups[$group->id] = $group;
}
/** @var stdClass $entry */
/** @var \stdClass $entry */
foreach ($set as $entry) {
$this->grouped[(int) $entry->object_groupable_id] = (int) $entry->object_group_id;
}

View File

@ -77,7 +77,7 @@ trait ExpandsQuery
$config = config('api.valid_api_filters')[$class];
$parsed = [];
foreach ($filters->all() as $filter) {
$key = $filter->key();
$key = $filter->key();
if (!in_array($key, $config, true)) {
continue;
}

View File

@ -39,8 +39,8 @@ trait FiltersPagination
$pagination['number'] = min(65536, max($pagination['number'], 1));
// clean up page size
$pagination['size'] = (int) ($pagination['size'] ?? $this->getPageSize());
$pagination['size'] = min(1337, max($pagination['size'], 1));
$pagination['size'] = (int) ($pagination['size'] ?? $this->getPageSize());
$pagination['size'] = min(1337, max($pagination['size'], 1));
return $pagination;
}

View File

@ -71,14 +71,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());
}
@ -87,7 +88,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']);
// the balance value is an array.
// first entry is the balance, second is the date.
@ -99,8 +100,8 @@ class AccountBalanceCalculator
$balances[$entry->account_id][$entry->transaction_currency_id] ??= [$this->getLatestBalance($entry->account_id, $entry->transaction_currency_id, $notBefore), null];
// before and after are easy:
$before = $balances[$entry->account_id][$entry->transaction_currency_id][0];
$after = bcadd($before, $entry->amount);
$before = $balances[$entry->account_id][$entry->transaction_currency_id][0];
$after = bcadd($before, $entry->amount);
if (true === $entry->balance_dirty || $accounts->count() > 0) {
// update the transaction:
$entry->balance_before = $before;
@ -126,17 +127,18 @@ class AccountBalanceCalculator
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);
@ -168,7 +170,7 @@ class AccountBalanceCalculator
*/
foreach ($currencies as $currencyId => $balance) {
/** @var TransactionCurrency $currency */
$currency = TransactionCurrency::find($currencyId);
$currency = TransactionCurrency::find($currencyId);
if (null === $currency) {
Log::error(sprintf('Could not find currency #%d, will not save account balance.', $currencyId));
@ -196,7 +198,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();
@ -208,9 +210,9 @@ class AccountBalanceCalculator
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));
@ -229,9 +231,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;
}

View File

@ -49,15 +49,15 @@ class BillDateCalculator
Log::debug(sprintf('Dates must be between %s and %s.', $earliest->format('Y-m-d'), $latest->format('Y-m-d')));
Log::debug(sprintf('Bill started on %s, period is "%s", skip is %d, last paid = "%s".', $billStart->format('Y-m-d'), $period, $skip, $lastPaid?->format('Y-m-d')));
$daysUntilEOM = app('navigation')->daysUntilEndOfMonth($billStart);
$daysUntilEOM = app('navigation')->daysUntilEndOfMonth($billStart);
Log::debug(sprintf('For bill start, days until end of month is %d', $daysUntilEOM));
$set = new Collection();
$currentStart = clone $earliest;
$set = new Collection();
$currentStart = clone $earliest;
// 2023-06-23 subDay to fix 7655
$currentStart->subDay();
$loop = 0;
$loop = 0;
Log::debug('Start of loop');
while ($currentStart <= $latest) {
@ -107,7 +107,7 @@ class BillDateCalculator
// for the next loop, go to end of period, THEN add day.
Log::debug('Add one day to nextExpectedMatch/currentStart.');
$nextExpectedMatch->addDay();
$currentStart = clone $nextExpectedMatch;
$currentStart = clone $nextExpectedMatch;
++$loop;
if ($loop > 12) {
@ -117,7 +117,7 @@ class BillDateCalculator
}
}
Log::debug('end of loop');
$simple = $set->map(
$simple = $set->map(
static function (Carbon $date) {
return $date->format('Y-m-d');
}
@ -142,7 +142,7 @@ class BillDateCalculator
return $billStartDate;
}
$steps = app('navigation')->diffInPeriods($period, $skip, $earliest, $billStartDate);
$steps = app('navigation')->diffInPeriods($period, $skip, $earliest, $billStartDate);
if ($steps === $this->diffInMonths) {
Log::debug(sprintf('Steps is %d, which is the same as diffInMonths (%d), so we add another 1.', $steps, $this->diffInMonths));
++$steps;

View File

@ -39,7 +39,7 @@ trait ReturnsIntegerIdTrait
protected function id(): Attribute
{
return Attribute::make(
get: static fn($value) => (int) $value,
get: static fn ($value) => (int) $value,
);
}
}

View File

@ -37,14 +37,14 @@ trait ReturnsIntegerUserIdTrait
protected function userGroupId(): Attribute
{
return Attribute::make(
get: static fn($value) => (int) $value,
get: static fn ($value) => (int) $value,
);
}
protected function userId(): Attribute
{
return Attribute::make(
get: static fn($value) => (int) $value,
get: static fn ($value) => (int) $value,
);
}
}

View File

@ -30,7 +30,6 @@ use FireflyIII\Helpers\Fiscal\FiscalHelperInterface;
use FireflyIII\Support\Calendar\Calculator;
use FireflyIII\Support\Calendar\Periodicity;
use Illuminate\Support\Facades\Log;
use Throwable;
/**
* Class Navigation.
@ -77,10 +76,10 @@ class Navigation
if (!array_key_exists($repeatFreq, $functionMap)) {
Log::error(sprintf(
'The periodicity %s is unknown. Choose one of available periodicity: %s',
$repeatFreq,
implode(', ', array_keys($functionMap))
));
'The periodicity %s is unknown. Choose one of available periodicity: %s',
$repeatFreq,
implode(', ', array_keys($functionMap))
));
return $theDate;
}
@ -94,7 +93,7 @@ class Navigation
return $this->calculator->nextDateByInterval($epoch, $periodicity, $skipInterval);
} catch (IntervalException $exception) {
Log::warning($exception->getMessage(), ['exception' => $exception]);
} catch (Throwable $exception) { // @phpstan-ignore-line
} catch (\Throwable $exception) { // @phpstan-ignore-line
Log::error($exception->getMessage(), ['exception' => $exception]);
}
@ -111,7 +110,7 @@ class Navigation
if ($end < $start) {
[$start, $end] = [$end, $start];
}
$periods = [];
$periods = [];
// first, 13 periods of [range]
$loopCount = 0;
$loopDate = clone $end;
@ -161,9 +160,9 @@ class Navigation
public function startOfPeriod(Carbon $theDate, string $repeatFreq): Carbon
{
$date = clone $theDate;
$date = clone $theDate;
// Log::debug(sprintf('Now in startOfPeriod("%s", "%s")', $date->toIso8601String(), $repeatFreq));
$functionMap = [
$functionMap = [
'1D' => 'startOfDay',
'daily' => 'startOfDay',
'1W' => 'startOfWeek',
@ -210,7 +209,7 @@ class Navigation
return $date;
}
$result = match ($repeatFreq) {
$result = match ($repeatFreq) {
'last7' => $date->subDays(7)->startOfDay(),
'last30' => $date->subDays(30)->startOfDay(),
'last90' => $date->subDays(90)->startOfDay(),
@ -238,7 +237,7 @@ class Navigation
public function endOfPeriod(Carbon $end, string $repeatFreq): Carbon
{
$currentEnd = clone $end;
$currentEnd = clone $end;
// Log::debug(sprintf('Now in endOfPeriod("%s", "%s").', $currentEnd->toIso8601String(), $repeatFreq));
$functionMap = [
@ -272,7 +271,7 @@ class Navigation
Log::debug('Session data available.');
/** @var Carbon $tStart */
$tStart = session('start', today(config('app.timezone'))->startOfMonth());
$tStart = session('start', today(config('app.timezone'))->startOfMonth());
/** @var Carbon $tEnd */
$tEnd = session('end', today(config('app.timezone'))->endOfMonth());
@ -292,7 +291,7 @@ class Navigation
return $end->endOfMonth();
}
$result = match ($repeatFreq) {
$result = match ($repeatFreq) {
'last7' => $currentEnd->addDays(7)->startOfDay(),
'last30' => $currentEnd->addDays(30)->startOfDay(),
'last90' => $currentEnd->addDays(90)->startOfDay(),
@ -312,7 +311,7 @@ class Navigation
return $end;
}
$function = $functionMap[$repeatFreq];
$function = $functionMap[$repeatFreq];
if (array_key_exists($repeatFreq, $modifierMap)) {
$currentEnd->{$function}($modifierMap[$repeatFreq]); // @phpstan-ignore-line
@ -343,13 +342,13 @@ class Navigation
public function diffInPeriods(string $period, int $skip, Carbon $beginning, Carbon $end): int
{
Log::debug(sprintf(
'diffInPeriods: %s (skip: %d), between %s and %s.',
$period,
$skip,
$beginning->format('Y-m-d'),
$end->format('Y-m-d')
));
$map = [
'diffInPeriods: %s (skip: %d), between %s and %s.',
$period,
$skip,
$beginning->format('Y-m-d'),
$end->format('Y-m-d')
));
$map = [
'daily' => 'diffInDays',
'weekly' => 'diffInWeeks',
'monthly' => 'diffInMonths',
@ -362,7 +361,7 @@ class Navigation
return 1;
}
$func = $map[$period];
$func = $map[$period];
// first do the diff
$floatDiff = $beginning->{$func}($end, true); // @phpstan-ignore-line
@ -377,7 +376,7 @@ class Navigation
}
// then do ceil()
$diff = ceil($floatDiff);
$diff = ceil($floatDiff);
Log::debug(sprintf('Diff is %f periods (%d rounded up)', $floatDiff, $diff));
@ -385,11 +384,11 @@ class Navigation
$parameter = $skip + 1;
$diff = ceil($diff / $parameter) * $parameter;
Log::debug(sprintf(
'diffInPeriods: skip is %d, so param is %d, and diff becomes %d',
$skip,
$parameter,
$diff
));
'diffInPeriods: skip is %d, so param is %d, and diff becomes %d',
$skip,
$parameter,
$diff
));
}
return (int) $diff;
@ -414,7 +413,7 @@ class Navigation
'yearly' => 'endOfYear',
];
$currentEnd = clone $theCurrentEnd;
$currentEnd = clone $theCurrentEnd;
if (array_key_exists($repeatFreq, $functionMap)) {
$function = $functionMap[$repeatFreq];
@ -469,7 +468,7 @@ class Navigation
*/
public function listOfPeriods(Carbon $start, Carbon $end): array
{
$locale = app('steam')->getLocale();
$locale = app('steam')->getLocale();
// define period to increment
$increment = 'addDay';
$format = $this->preferredCarbonFormat($start, $end);
@ -486,8 +485,8 @@ class Navigation
$increment = 'addYear';
$displayFormat = (string) trans('config.year_js');
}
$begin = clone $start;
$entries = [];
$begin = clone $start;
$entries = [];
while ($begin < $end) {
$formatted = $begin->format($format);
$displayed = $begin->isoFormat($displayFormat);
@ -649,7 +648,7 @@ class Navigation
public function subtractPeriod(Carbon $theDate, string $repeatFreq, ?int $subtract = null): Carbon
{
$subtract ??= 1;
$date = clone $theDate;
$date = clone $theDate;
// 1D 1W 1M 3M 6M 1Y
$functionMap = [
'1D' => 'subDays',
@ -688,7 +687,7 @@ class Navigation
// this is then subtracted from $theDate (* $subtract).
if ('custom' === $repeatFreq) {
/** @var Carbon $tStart */
$tStart = session('start', today(config('app.timezone'))->startOfMonth());
$tStart = session('start', today(config('app.timezone'))->startOfMonth());
/** @var Carbon $tEnd */
$tEnd = session('end', today(config('app.timezone'))->endOfMonth());
@ -782,7 +781,7 @@ class Navigation
return $fiscalHelper->endOfFiscalYear($end);
}
$list = [
$list = [
'last7',
'last30',
'last90',

View File

@ -24,12 +24,10 @@ declare(strict_types=1);
namespace FireflyIII\Support;
use ArrayObject;
/**
* Class NullArrayObject
*/
class NullArrayObject extends ArrayObject
class NullArrayObject extends \ArrayObject
{
/** @var null|mixed */
public $default;

View File

@ -77,15 +77,15 @@ class ParseDateString
public function parseDate(string $date): Carbon
{
app('log')->debug(sprintf('parseDate("%s")', $date));
$date = strtolower($date);
$date = strtolower($date);
// parse keywords:
if (in_array($date, $this->keywords, true)) {
return $this->parseKeyword($date);
}
// if regex for YYYY-MM-DD:
$pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/';
$result = preg_match($pattern, $date);
$pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/';
$result = preg_match($pattern, $date);
if (false !== $result && 0 !== $result) {
return $this->parseDefaultDate($date);
}
@ -178,11 +178,11 @@ class ParseDateString
foreach ($parts as $part) {
app('log')->debug(sprintf('Now parsing part "%s"', $part));
$part = trim($part);
$part = trim($part);
// verify if correct
$pattern = '/[+-]\d+[wqmdy]/';
$result = preg_match($pattern, $part);
$pattern = '/[+-]\d+[wqmdy]/';
$result = preg_match($pattern, $part);
if (0 === $result || false === $result) {
app('log')->error(sprintf('Part "%s" does not match regular expression. Will be skipped.', $part));
@ -196,7 +196,7 @@ class ParseDateString
continue;
}
$func = $functions[$direction][$period];
$func = $functions[$direction][$period];
app('log')->debug(sprintf('Will now do %s(%d) on %s', $func, $number, $today->format('Y-m-d')));
$today->{$func}($number); // @phpstan-ignore-line
app('log')->debug(sprintf('Resulting date is %s', $today->format('Y-m-d')));

View File

@ -47,15 +47,16 @@ class Preferences
}
return Preference::where('user_id', $user->id)
->where('name', '!=', 'currencyPreference')
->where(function (Builder $q) use ($user): void {
$q->whereNull('user_group_id');
$q->orWhere('user_group_id', $user->user_group_id);
})
->get();
->where('name', '!=', 'currencyPreference')
->where(function (Builder $q) use ($user): void {
$q->whereNull('user_group_id');
$q->orWhere('user_group_id', $user->user_group_id);
})
->get()
;
}
public function get(string $name, null | array | bool | int | string $default = null): ?Preference
public function get(string $name, null|array|bool|int|string $default = null): ?Preference
{
/** @var null|User $user */
$user = auth()->user();
@ -69,7 +70,7 @@ class Preferences
return $this->getForUser($user, $name, $default);
}
public function getForUser(User $user, string $name, null | array | bool | int | string $default = null): ?Preference
public function getForUser(User $user, string $name, null|array|bool|int|string $default = null): ?Preference
{
// don't care about user group ID, except for some specific preferences.
$userGroupId = $this->getUserGroupId($user, $name);
@ -121,16 +122,16 @@ class Preferences
Cache::put($key, '', 5);
}
public function setForUser(User $user, string $name, null | array | bool | int | string $value): Preference
public function setForUser(User $user, string $name, null|array|bool|int|string $value): Preference
{
$fullName = sprintf('preference%s%s', $user->id, $name);
$groupId = $this->getUserGroupId($user, $name);
$groupId = 0 === (int) $groupId ? null : (int) $groupId;
$fullName = sprintf('preference%s%s', $user->id, $name);
$groupId = $this->getUserGroupId($user, $name);
$groupId = 0 === (int) $groupId ? null : (int) $groupId;
Cache::forget($fullName);
/** @var null|Preference $pref */
$pref = Preference::where('user_group_id', $groupId)->where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']);
$pref = Preference::where('user_group_id', $groupId)->where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']);
if (null !== $pref && null === $value) {
$pref->delete();
@ -173,12 +174,13 @@ class Preferences
{
$result = [];
$preferences = Preference::where('user_id', $user->id)
->where(function (Builder $q) use ($user): void {
$q->whereNull('user_group_id');
$q->orWhere('user_group_id', $user->user_group_id);
})
->whereIn('name', $list)
->get(['id', 'name', 'data']);
->where(function (Builder $q) use ($user): void {
$q->whereNull('user_group_id');
$q->orWhere('user_group_id', $user->user_group_id);
})
->whereIn('name', $list)
->get(['id', 'name', 'data'])
;
/** @var Preference $preference */
foreach ($preferences as $preference) {
@ -216,7 +218,7 @@ class Preferences
return $result;
}
public function getEncryptedForUser(User $user, string $name, null | array | bool | int | string $default = null): ?Preference
public function getEncryptedForUser(User $user, string $name, null|array|bool|int|string $default = null): ?Preference
{
$result = $this->getForUser($user, $name, $default);
if ('' === $result->data) {
@ -237,7 +239,7 @@ class Preferences
return $result;
}
public function getFresh(string $name, null | array | bool | int | string $default = null): ?Preference
public function getFresh(string $name, null|array|bool|int|string $default = null): ?Preference
{
/** @var null|User $user */
$user = auth()->user();
@ -275,7 +277,7 @@ class Preferences
Session::forget('first');
}
public function set(string $name, null | array | bool | int | string $value): Preference
public function set(string $name, null|array|bool|int|string $value): Preference
{
/** @var null|User $user */
$user = auth()->user();

View File

@ -76,7 +76,7 @@ class BudgetReportGenerator
/** @var Account $account */
foreach ($this->accounts as $account) {
$accountId = $account->id;
$accountId = $account->id;
$this->report[$accountId] ??= [
'name' => $account->name,
'id' => $account->id,
@ -113,18 +113,18 @@ class BudgetReportGenerator
$this->report[$sourceAccountId]['currencies'][$currencyId]
??= [
'currency_id' => $expenses['currency_id'],
'currency_symbol' => $expenses['currency_symbol'],
'currency_name' => $expenses['currency_name'],
'currency_decimal_places' => $expenses['currency_decimal_places'],
'budgets' => [],
];
'currency_id' => $expenses['currency_id'],
'currency_symbol' => $expenses['currency_symbol'],
'currency_name' => $expenses['currency_name'],
'currency_decimal_places' => $expenses['currency_decimal_places'],
'budgets' => [],
];
$this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId]
??= '0';
$this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId]
= bcadd($this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId], $journal['amount']);
= bcadd($this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId], $journal['amount']);
}
}
@ -162,7 +162,7 @@ class BudgetReportGenerator
*/
private function processBudget(Budget $budget): void
{
$budgetId = $budget->id;
$budgetId = $budget->id;
$this->report['budgets'][$budgetId] ??= [
'budget_id' => $budgetId,
'budget_name' => $budget->name,
@ -171,7 +171,7 @@ class BudgetReportGenerator
];
// get all budget limits for budget in period:
$limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end);
$limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end);
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
@ -184,14 +184,14 @@ class BudgetReportGenerator
*/
private function processLimit(Budget $budget, BudgetLimit $limit): void
{
$budgetId = $budget->id;
$limitId = $limit->id;
$limitCurrency = $limit->transactionCurrency ?? $this->currency;
$currencyId = $limitCurrency->id;
$expenses = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, $this->accounts, new Collection([$budget]));
$spent = $expenses[$currencyId]['sum'] ?? '0';
$left = -1 === bccomp(bcadd($limit->amount, $spent), '0') ? '0' : bcadd($limit->amount, $spent);
$overspent = 1 === bccomp(bcmul($spent, '-1'), $limit->amount) ? bcadd($spent, $limit->amount) : '0';
$budgetId = $budget->id;
$limitId = $limit->id;
$limitCurrency = $limit->transactionCurrency ?? $this->currency;
$currencyId = $limitCurrency->id;
$expenses = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, $this->accounts, new Collection([$budget]));
$spent = $expenses[$currencyId]['sum'] ?? '0';
$left = -1 === bccomp(bcadd($limit->amount, $spent), '0') ? '0' : bcadd($limit->amount, $spent);
$overspent = 1 === bccomp(bcmul($spent, '-1'), $limit->amount) ? bcadd($spent, $limit->amount) : '0';
$this->report['budgets'][$budgetId]['budget_limits'][$limitId] ??= [
'budget_limit_id' => $limitId,
@ -212,17 +212,17 @@ class BudgetReportGenerator
// make sum information:
$this->report['sums'][$currencyId]
??= [
'budgeted' => '0',
'spent' => '0',
'left' => '0',
'overspent' => '0',
'currency_id' => $currencyId,
'currency_code' => $limitCurrency->code,
'currency_name' => $limitCurrency->name,
'currency_symbol' => $limitCurrency->symbol,
'currency_decimal_places' => $limitCurrency->decimal_places,
];
??= [
'budgeted' => '0',
'spent' => '0',
'left' => '0',
'overspent' => '0',
'currency_id' => $currencyId,
'currency_code' => $limitCurrency->code,
'currency_name' => $limitCurrency->name,
'currency_symbol' => $limitCurrency->symbol,
'currency_decimal_places' => $limitCurrency->decimal_places,
];
$this->report['sums'][$currencyId]['budgeted'] = bcadd($this->report['sums'][$currencyId]['budgeted'], $limit->amount);
$this->report['sums'][$currencyId]['spent'] = bcadd($this->report['sums'][$currencyId]['spent'], $spent);
$this->report['sums'][$currencyId]['left'] = bcadd($this->report['sums'][$currencyId]['left'], bcadd($limit->amount, $spent));
@ -242,16 +242,16 @@ class BudgetReportGenerator
'budget_limits' => [],
];
$noBudget = $this->nbRepository->sumExpenses($this->start, $this->end, $this->accounts);
$noBudget = $this->nbRepository->sumExpenses($this->start, $this->end, $this->accounts);
foreach ($noBudget as $noBudgetEntry) {
// currency information:
$nbCurrencyId = (int) ($noBudgetEntry['currency_id'] ?? $this->currency->id);
$nbCurrencyCode = $noBudgetEntry['currency_code'] ?? $this->currency->code;
$nbCurrencyName = $noBudgetEntry['currency_name'] ?? $this->currency->name;
$nbCurrencySymbol = $noBudgetEntry['currency_symbol'] ?? $this->currency->symbol;
$nbCurrencyDp = $noBudgetEntry['currency_decimal_places'] ?? $this->currency->decimal_places;
$nbCurrencyId = (int) ($noBudgetEntry['currency_id'] ?? $this->currency->id);
$nbCurrencyCode = $noBudgetEntry['currency_code'] ?? $this->currency->code;
$nbCurrencyName = $noBudgetEntry['currency_name'] ?? $this->currency->name;
$nbCurrencySymbol = $noBudgetEntry['currency_symbol'] ?? $this->currency->symbol;
$nbCurrencyDp = $noBudgetEntry['currency_decimal_places'] ?? $this->currency->decimal_places;
$this->report['budgets'][0]['budget_limits'][] = [
$this->report['budgets'][0]['budget_limits'][] = [
'budget_limit_id' => null,
'start_date' => $this->start,
'end_date' => $this->end,
@ -267,7 +267,7 @@ class BudgetReportGenerator
'currency_symbol' => $nbCurrencySymbol,
'currency_decimal_places' => $nbCurrencyDp,
];
$this->report['sums'][$nbCurrencyId]['spent'] = bcadd($this->report['sums'][$nbCurrencyId]['spent'] ?? '0', $noBudgetEntry['sum']);
$this->report['sums'][$nbCurrencyId]['spent'] = bcadd($this->report['sums'][$nbCurrencyId]['spent'] ?? '0', $noBudgetEntry['sum']);
// append currency info because it may be missing:
$this->report['sums'][$nbCurrencyId]['currency_id'] = $nbCurrencyId;
$this->report['sums'][$nbCurrencyId]['currency_code'] = $nbCurrencyCode;
@ -290,15 +290,15 @@ class BudgetReportGenerator
// make percentages based on total amount.
foreach ($this->report['budgets'] as $budgetId => $data) {
foreach ($data['budget_limits'] as $limitId => $entry) {
$budgetId = (int) $budgetId;
$limitId = (int) $limitId;
$currencyId = (int) $entry['currency_id'];
$spent = $entry['spent'];
$totalSpent = $this->report['sums'][$currencyId]['spent'] ?? '0';
$spentPct = '0';
$budgeted = $entry['budgeted'];
$totalBudgeted = $this->report['sums'][$currencyId]['budgeted'] ?? '0';
$budgetedPct = '0';
$budgetId = (int) $budgetId;
$limitId = (int) $limitId;
$currencyId = (int) $entry['currency_id'];
$spent = $entry['spent'];
$totalSpent = $this->report['sums'][$currencyId]['spent'] ?? '0';
$spentPct = '0';
$budgeted = $entry['budgeted'];
$totalBudgeted = $this->report['sums'][$currencyId]['budgeted'] ?? '0';
$budgetedPct = '0';
if (0 !== bccomp($spent, '0') && 0 !== bccomp($totalSpent, '0')) {
$spentPct = round((float) bcmul(bcdiv($spent, $totalSpent), '100'));
@ -306,7 +306,7 @@ class BudgetReportGenerator
if (0 !== bccomp($budgeted, '0') && 0 !== bccomp($totalBudgeted, '0')) {
$budgetedPct = round((float) bcmul(bcdiv($budgeted, $totalBudgeted), '100'));
}
$this->report['sums'][$currencyId]['budgeted'] ??= '0';
$this->report['sums'][$currencyId]['budgeted'] ??= '0';
$this->report['budgets'][$budgetId]['budget_limits'][$limitId]['spent_pct'] = $spentPct;
$this->report['budgets'][$budgetId]['budget_limits'][$limitId]['budgeted_pct'] = $budgetedPct;
}

View File

@ -62,17 +62,17 @@ class CategoryReportGenerator
*/
public function operations(): void
{
$earnedWith = $this->opsRepository->listIncome($this->start, $this->end, $this->accounts);
$spentWith = $this->opsRepository->listExpenses($this->start, $this->end, $this->accounts);
$earnedWith = $this->opsRepository->listIncome($this->start, $this->end, $this->accounts);
$spentWith = $this->opsRepository->listExpenses($this->start, $this->end, $this->accounts);
// also transferred out and transferred into these accounts in this category:
$transferredIn = $this->opsRepository->listTransferredIn($this->start, $this->end, $this->accounts);
$transferredOut = $this->opsRepository->listTransferredOut($this->start, $this->end, $this->accounts);
$earnedWithout = $this->noCatRepository->listIncome($this->start, $this->end, $this->accounts);
$spentWithout = $this->noCatRepository->listExpenses($this->start, $this->end, $this->accounts);
$earnedWithout = $this->noCatRepository->listIncome($this->start, $this->end, $this->accounts);
$spentWithout = $this->noCatRepository->listExpenses($this->start, $this->end, $this->accounts);
$this->report = [
$this->report = [
'categories' => [],
'sums' => [],
];
@ -121,7 +121,7 @@ class CategoryReportGenerator
private function processCategoryRow(int $currencyId, array $currencyRow, int $categoryId, array $categoryRow): void
{
$key = sprintf('%s-%s', $currencyId, $categoryId);
$key = sprintf('%s-%s', $currencyId, $categoryId);
$this->report['categories'][$key] ??= [
'id' => $categoryId,
'title' => $categoryRow['name'],
@ -137,9 +137,9 @@ class CategoryReportGenerator
// loop journals:
foreach ($categoryRow['transaction_journals'] as $journal) {
// sum of sums
$this->report['sums'][$currencyId]['sum'] = bcadd($this->report['sums'][$currencyId]['sum'], $journal['amount']);
$this->report['sums'][$currencyId]['sum'] = bcadd($this->report['sums'][$currencyId]['sum'], $journal['amount']);
// sum of spent:
$this->report['sums'][$currencyId]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd(
$this->report['sums'][$currencyId]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd(
$this->report['sums'][$currencyId]['spent'],
$journal['amount']
) : $this->report['sums'][$currencyId]['spent'];
@ -150,14 +150,14 @@ class CategoryReportGenerator
) : $this->report['sums'][$currencyId]['earned'];
// sum of category
$this->report['categories'][$key]['sum'] = bcadd($this->report['categories'][$key]['sum'], $journal['amount']);
$this->report['categories'][$key]['sum'] = bcadd($this->report['categories'][$key]['sum'], $journal['amount']);
// total spent in category
$this->report['categories'][$key]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd(
$this->report['categories'][$key]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd(
$this->report['categories'][$key]['spent'],
$journal['amount']
) : $this->report['categories'][$key]['spent'];
// total earned in category
$this->report['categories'][$key]['earned'] = 1 === bccomp($journal['amount'], '0') ? bcadd(
$this->report['categories'][$key]['earned'] = 1 === bccomp($journal['amount'], '0') ? bcadd(
$this->report['categories'][$key]['earned'],
$journal['amount']
) : $this->report['categories'][$key]['earned'];

View File

@ -82,8 +82,8 @@ trait CalculateRangeOccurrences
*/
protected function getNdomInRange(Carbon $start, Carbon $end, int $skipMod, string $moment): array
{
$return = [];
$attempts = 0;
$return = [];
$attempts = 0;
$start->startOfMonth();
// this feels a bit like a cop out but why reinvent the wheel?
$counters = [1 => 'first', 2 => 'second', 3 => 'third', 4 => 'fourth', 5 => 'fifth'];
@ -108,12 +108,12 @@ trait CalculateRangeOccurrences
*/
protected function getWeeklyInRange(Carbon $start, Carbon $end, int $skipMod, string $moment): array
{
$return = [];
$attempts = 0;
$return = [];
$attempts = 0;
app('log')->debug('Rep is weekly.');
// monday = 1
// sunday = 7
$dayOfWeek = (int) $moment;
$dayOfWeek = (int) $moment;
app('log')->debug(sprintf('DoW in repetition is %d, in mutator is %d', $dayOfWeek, $start->dayOfWeekIso));
if ($start->dayOfWeekIso > $dayOfWeek) {
// day has already passed this week, add one week:
@ -154,8 +154,8 @@ trait CalculateRangeOccurrences
}
// is $date between $start and $end?
$obj = clone $date;
$count = 0;
$obj = clone $date;
$count = 0;
while ($obj <= $end && $obj >= $start && $count < 10) {
if (0 === $attempts % $skipMod) {
$return[] = clone $obj;

View File

@ -89,10 +89,10 @@ trait CalculateXOccurrences
*/
protected function getXNDomOccurrences(Carbon $date, int $count, int $skipMod, string $moment): array
{
$return = [];
$total = 0;
$attempts = 0;
$mutator = clone $date;
$return = [];
$total = 0;
$attempts = 0;
$mutator = clone $date;
$mutator->addDay(); // always assume today has passed.
$mutator->startOfMonth();
// this feels a bit like a cop out but why reinvent the wheel?
@ -120,14 +120,14 @@ trait CalculateXOccurrences
*/
protected function getXWeeklyOccurrences(Carbon $date, int $count, int $skipMod, string $moment): array
{
$return = [];
$total = 0;
$attempts = 0;
$mutator = clone $date;
$return = [];
$total = 0;
$attempts = 0;
$mutator = clone $date;
// monday = 1
// sunday = 7
$mutator->addDay(); // always assume today has passed.
$dayOfWeek = (int) $moment;
$dayOfWeek = (int) $moment;
if ($mutator->dayOfWeekIso > $dayOfWeek) {
// day has already passed this week, add one week:
$mutator->addWeek();
@ -164,7 +164,7 @@ trait CalculateXOccurrences
if ($mutator > $date) {
$date->addYear();
}
$obj = clone $date;
$obj = clone $date;
while ($total < $count) {
if (0 === $attempts % $skipMod) {
$return[] = clone $obj;

View File

@ -86,7 +86,7 @@ trait CalculateXOccurrencesSince
++$total;
}
++$attempts;
$mutator = $mutator->endOfMonth()->addDay();
$mutator = $mutator->endOfMonth()->addDay();
}
return $return;
@ -101,10 +101,10 @@ trait CalculateXOccurrencesSince
protected function getXNDomOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$return = [];
$total = 0;
$attempts = 0;
$mutator = clone $date;
$return = [];
$total = 0;
$attempts = 0;
$mutator = clone $date;
$mutator->addDay(); // always assume today has passed.
$mutator->startOfMonth();
// this feels a bit like a cop out but why reinvent the wheel?
@ -135,15 +135,15 @@ trait CalculateXOccurrencesSince
protected function getXWeeklyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$return = [];
$total = 0;
$attempts = 0;
$mutator = clone $date;
$return = [];
$total = 0;
$attempts = 0;
$mutator = clone $date;
// monday = 1
// sunday = 7
// Removed assumption today has passed, see issue https://github.com/firefly-iii/firefly-iii/issues/4798
// $mutator->addDay(); // always assume today has passed.
$dayOfWeek = (int) $moment;
$dayOfWeek = (int) $moment;
if ($mutator->dayOfWeekIso > $dayOfWeek) {
// day has already passed this week, add one week:
$mutator->addWeek();
@ -187,7 +187,7 @@ trait CalculateXOccurrencesSince
$date->addYear();
app('log')->debug(sprintf('Date is now %s', $date->format('Y-m-d')));
}
$obj = clone $date;
$obj = clone $date;
while ($total < $count) {
app('log')->debug(sprintf('total (%d) < count (%d) so go.', $total, $count));
app('log')->debug(sprintf('attempts (%d) %% skipmod (%d) === %d', $attempts, $skipMod, $attempts % $skipMod));

View File

@ -44,7 +44,7 @@ trait FiltersWeekends
return $dates;
}
$return = [];
$return = [];
/** @var Carbon $date */
foreach ($dates as $date) {
@ -58,7 +58,7 @@ trait FiltersWeekends
// is weekend and must set back to Friday?
if (RecurrenceRepetition::WEEKEND_TO_FRIDAY === $repetition->weekend) {
$clone = clone $date;
$clone = clone $date;
$clone->addDays(5 - $date->dayOfWeekIso);
app('log')->debug(
sprintf('Date is %s, and this is in the weekend, so corrected to %s (Friday).', $date->format('D d M Y'), $clone->format('D d M Y'))
@ -70,7 +70,7 @@ trait FiltersWeekends
// postpone to Monday?
if (RecurrenceRepetition::WEEKEND_TO_MONDAY === $repetition->weekend) {
$clone = clone $date;
$clone = clone $date;
$clone->addDays(8 - $date->dayOfWeekIso);
app('log')->debug(
sprintf('Date is %s, and this is in the weekend, so corrected to %s (Monday).', $date->format('D d M Y'), $clone->format('D d M Y'))

View File

@ -54,10 +54,10 @@ trait UserGroupTrait
/**
* @throws FireflyException
*/
public function setUser(null | Authenticatable | User $user): void
public function setUser(null|Authenticatable|User $user): void
{
if ($user instanceof User) {
$this->user = $user;
$this->user = $user;
if (null === $user->userGroup) {
throw new FireflyException(sprintf('User #%d has no user group.', $user->id));
}
@ -70,15 +70,16 @@ trait UserGroupTrait
*/
public function setUserGroupById(int $userGroupId): void
{
$memberships = GroupMembership::where('user_id', $this->user->id)
->where('user_group_id', $userGroupId)
->count();
$memberships = GroupMembership::where('user_id', $this->user->id)
->where('user_group_id', $userGroupId)
->count()
;
if (0 === $memberships) {
throw new FireflyException(sprintf('User #%d has no access to administration #%d', $this->user->id, $userGroupId));
}
/** @var null|UserGroup $userGroup */
$userGroup = UserGroup::find($userGroupId);
$userGroup = UserGroup::find($userGroupId);
if (null === $userGroup) {
throw new FireflyException(sprintf('Cannot find administration for user #%d', $this->user->id));
}

View File

@ -82,12 +82,12 @@ trait AppendsLocationData
$data['latitude'] = null;
$data['zoom_level'] = null;
$longitudeKey = $this->getLocationKey($prefix, 'longitude');
$latitudeKey = $this->getLocationKey($prefix, 'latitude');
$zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level');
$isValidPOST = $this->isValidPost($prefix);
$isValidPUT = $this->isValidPUT($prefix);
$isValidEmptyPUT = $this->isValidEmptyPUT($prefix);
$longitudeKey = $this->getLocationKey($prefix, 'longitude');
$latitudeKey = $this->getLocationKey($prefix, 'latitude');
$zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level');
$isValidPOST = $this->isValidPost($prefix);
$isValidPUT = $this->isValidPUT($prefix);
$isValidEmptyPUT = $this->isValidEmptyPUT($prefix);
// for a POST (store), all fields must be present and not NULL.
if ($isValidPOST) {
@ -245,9 +245,9 @@ trait AppendsLocationData
$zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level');
return (
null === $this->get($longitudeKey)
&& null === $this->get($latitudeKey)
&& null === $this->get($zoomLevelKey))
null === $this->get($longitudeKey)
&& null === $this->get($latitudeKey)
&& null === $this->get($zoomLevelKey))
&& (
'PUT' === $this->method()
|| ('POST' === $this->method() && $this->routeIs('*.update'))

View File

@ -40,7 +40,7 @@ trait ChecksLogin
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
// Only allow logged-in users
$check = auth()->check();
$check = auth()->check();
if (!$check) {
return false;
}
@ -79,7 +79,7 @@ trait ChecksLogin
public function getUserGroup(): ?UserGroup
{
/** @var User $user */
$user = auth()->user();
$user = auth()->user();
app('log')->debug('Now in getUserGroup()');
/** @var null|UserGroup $userGroup */
@ -91,7 +91,7 @@ trait ChecksLogin
app('log')->debug(sprintf('Request class has no user_group_id parameter, grab default from user (group #%d).', $user->user_group_id));
$userGroupId = (int) $user->user_group_id;
}
$userGroup = UserGroup::find($userGroupId);
$userGroup = UserGroup::find($userGroupId);
if (null === $userGroup) {
app('log')->error(sprintf('Request class has user_group_id (#%d), but group does not exist.', $userGroupId));

View File

@ -27,6 +27,4 @@ namespace FireflyIII\Support\Request;
/**
* Trait ConvertAPIDataTypes
*/
trait ConvertAPIDataTypes
{
}
trait ConvertAPIDataTypes {}

View File

@ -38,13 +38,13 @@ trait GetFilterInstructions
return [];
}
foreach ($set as $info) {
$column = $info['column'] ?? 'NOPE';
$filterValue = (string) ($info['filter'] ?? self::INVALID_FILTER);
$column = $info['column'] ?? 'NOPE';
$filterValue = (string) ($info['filter'] ?? self::INVALID_FILTER);
if (false === in_array($column, $allowed, true)) {
// skip invalid column
continue;
}
$filterType = $config[$column] ?? false;
$filterType = $config[$column] ?? false;
switch ($filterType) {
default:

View File

@ -35,8 +35,8 @@ trait GetSortInstructions
return [];
}
foreach ($set as $info) {
$column = $info['column'] ?? 'NOPE';
$direction = $info['direction'] ?? 'NOPE';
$column = $info['column'] ?? 'NOPE';
$direction = $info['direction'] ?? 'NOPE';
if ('asc' !== $direction && 'desc' !== $direction) {
// skip invalid direction
continue;

View File

@ -35,16 +35,16 @@ use Illuminate\Support\Collection;
class AccountSearch implements GenericSearchInterface
{
/** @var string */
public const string SEARCH_ALL = 'all';
public const string SEARCH_ALL = 'all';
/** @var string */
public const string SEARCH_IBAN = 'iban';
public const string SEARCH_IBAN = 'iban';
/** @var string */
public const string SEARCH_ID = 'id';
public const string SEARCH_ID = 'id';
/** @var string */
public const string SEARCH_NAME = 'name';
public const string SEARCH_NAME = 'name';
/** @var string */
public const string SEARCH_NUMBER = 'number';
@ -61,9 +61,10 @@ class AccountSearch implements GenericSearchInterface
public function search(): Collection
{
$searchQuery = $this->user->accounts()
->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->whereIn('account_types.type', $this->types);
->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->whereIn('account_types.type', $this->types)
;
$like = sprintf('%%%s%%', $this->query);
$originalQuery = $this->query;
@ -134,7 +135,7 @@ class AccountSearch implements GenericSearchInterface
$this->types = $types;
}
public function setUser(null | Authenticatable | User $user): void
public function setUser(null|Authenticatable|User $user): void
{
if ($user instanceof User) {
$this->user = $user;

View File

@ -57,8 +57,6 @@ use Gdbots\QueryParser\Node\Word;
use Gdbots\QueryParser\QueryParser;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use LogicException;
use TypeError;
/**
* Class OperatorQuerySearch
@ -151,7 +149,7 @@ class OperatorQuerySearch implements SearchInterface
try {
$query1 = $parser->parse($query);
} catch (LogicException | TypeError $e) {
} catch (\LogicException|\TypeError $e) {
app('log')->error($e->getMessage());
app('log')->error(sprintf('Could not parse search: "%s".', $query));
@ -203,7 +201,7 @@ class OperatorQuerySearch implements SearchInterface
case Emoticon::class:
case Emoji::class:
case Mention::class:
$allWords = (string) $searchNode->getValue();
$allWords = (string) $searchNode->getValue();
app('log')->debug(sprintf('Add words "%s" to search string, because Node class is "%s"', $allWords, $class));
$this->words[] = $allWords;
@ -214,10 +212,10 @@ class OperatorQuerySearch implements SearchInterface
/** @var Field $searchNode */
// used to search for x:y
$operator = strtolower($searchNode->getValue());
$value = $searchNode->getNode()->getValue();
$prohibited = BoolOperator::PROHIBITED === $searchNode->getBoolOperator();
$context = config(sprintf('search.operators.%s.needs_context', $operator));
$operator = strtolower($searchNode->getValue());
$value = $searchNode->getNode()->getValue();
$prohibited = BoolOperator::PROHIBITED === $searchNode->getBoolOperator();
$context = config(sprintf('search.operators.%s.needs_context', $operator));
// is an operator that needs no context, and value is false, then prohibited = true.
if ('false' === $value && in_array($operator, $this->validOperators, true) && false === $context && !$prohibited) {
@ -277,15 +275,15 @@ class OperatorQuerySearch implements SearchInterface
throw new FireflyException(sprintf('Unsupported search operator: "%s"', $operator));
// some search operators are ignored, basically:
// some search operators are ignored, basically:
case 'user_action':
app('log')->info(sprintf('Ignore search operator "%s"', $operator));
return false;
//
// all account related searches:
//
//
// all account related searches:
//
case 'account_is':
$this->searchAccount($value, SearchDirection::BOTH, StringPosition::IS);
@ -447,7 +445,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'source_account_id':
$account = $this->accountRepository->find((int) $value);
$account = $this->accountRepository->find((int) $value);
if (null !== $account) {
$this->collector->setSourceAccounts(new Collection([$account]));
}
@ -459,7 +457,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-source_account_id':
$account = $this->accountRepository->find((int) $value);
$account = $this->accountRepository->find((int) $value);
if (null !== $account) {
$this->collector->excludeSourceAccounts(new Collection([$account]));
}
@ -471,25 +469,25 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'journal_id':
$parts = explode(',', $value);
$parts = explode(',', $value);
$this->collector->setJournalIds($parts);
break;
case '-journal_id':
$parts = explode(',', $value);
$parts = explode(',', $value);
$this->collector->excludeJournalIds($parts);
break;
case 'id':
$parts = explode(',', $value);
$parts = explode(',', $value);
$this->collector->setIds($parts);
break;
case '-id':
$parts = explode(',', $value);
$parts = explode(',', $value);
$this->collector->excludeIds($parts);
break;
@ -575,7 +573,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'destination_account_id':
$account = $this->accountRepository->find((int) $value);
$account = $this->accountRepository->find((int) $value);
if (null !== $account) {
$this->collector->setDestinationAccounts(new Collection([$account]));
}
@ -586,7 +584,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-destination_account_id':
$account = $this->accountRepository->find((int) $value);
$account = $this->accountRepository->find((int) $value);
if (null !== $account) {
$this->collector->excludeDestinationAccounts(new Collection([$account]));
}
@ -597,8 +595,8 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'account_id':
$parts = explode(',', $value);
$collection = new Collection();
$parts = explode(',', $value);
$collection = new Collection();
foreach ($parts as $accountId) {
$account = $this->accountRepository->find((int) $accountId);
if (null !== $account) {
@ -615,8 +613,8 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-account_id':
$parts = explode(',', $value);
$collection = new Collection();
$parts = explode(',', $value);
$collection = new Collection();
foreach ($parts as $accountId) {
$account = $this->accountRepository->find((int) $accountId);
if (null !== $account) {
@ -632,48 +630,48 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// cash account
//
//
// cash account
//
case 'source_is_cash':
$account = $this->getCashAccount();
$account = $this->getCashAccount();
$this->collector->setSourceAccounts(new Collection([$account]));
break;
case '-source_is_cash':
$account = $this->getCashAccount();
$account = $this->getCashAccount();
$this->collector->excludeSourceAccounts(new Collection([$account]));
break;
case 'destination_is_cash':
$account = $this->getCashAccount();
$account = $this->getCashAccount();
$this->collector->setDestinationAccounts(new Collection([$account]));
break;
case '-destination_is_cash':
$account = $this->getCashAccount();
$account = $this->getCashAccount();
$this->collector->excludeDestinationAccounts(new Collection([$account]));
break;
case 'account_is_cash':
$account = $this->getCashAccount();
$account = $this->getCashAccount();
$this->collector->setAccounts(new Collection([$account]));
break;
case '-account_is_cash':
$account = $this->getCashAccount();
$account = $this->getCashAccount();
$this->collector->excludeAccounts(new Collection([$account]));
break;
//
// description
//
//
// description
//
case 'description_starts':
$this->collector->descriptionStarts([$value]);
@ -695,7 +693,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'description_contains':
$this->words[] = $value;
$this->words[] = $value;
return false;
@ -714,11 +712,11 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// currency
//
//
// currency
//
case 'currency_is':
$currency = $this->findCurrency($value);
$currency = $this->findCurrency($value);
if (null !== $currency) {
$this->collector->setCurrency($currency);
}
@ -729,7 +727,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-currency_is':
$currency = $this->findCurrency($value);
$currency = $this->findCurrency($value);
if (null !== $currency) {
$this->collector->excludeCurrency($currency);
}
@ -740,7 +738,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'foreign_currency_is':
$currency = $this->findCurrency($value);
$currency = $this->findCurrency($value);
if (null !== $currency) {
$this->collector->setForeignCurrency($currency);
}
@ -751,7 +749,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-foreign_currency_is':
$currency = $this->findCurrency($value);
$currency = $this->findCurrency($value);
if (null !== $currency) {
$this->collector->excludeForeignCurrency($currency);
}
@ -761,9 +759,9 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// attachments
//
//
// attachments
//
case 'has_attachments':
case '-has_no_attachments':
app('log')->debug('Set collector to filter on attachments.');
@ -778,8 +776,8 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// categories
//
// categories
case '-has_any_category':
case 'has_no_category':
$this->collector->withoutCategory();
@ -793,7 +791,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'category_is':
$category = $this->categoryRepository->findByName($value);
$category = $this->categoryRepository->findByName($value);
if (null !== $category) {
$this->collector->setCategory($category);
@ -804,7 +802,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-category_is':
$category = $this->categoryRepository->findByName($value);
$category = $this->categoryRepository->findByName($value);
if (null !== $category) {
$this->collector->excludeCategory($category);
@ -814,7 +812,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'category_ends':
$result = $this->categoryRepository->categoryEndsWith($value, 1337);
$result = $this->categoryRepository->categoryEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setCategories($result);
}
@ -825,7 +823,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-category_ends':
$result = $this->categoryRepository->categoryEndsWith($value, 1337);
$result = $this->categoryRepository->categoryEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeCategories($result);
}
@ -836,7 +834,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'category_starts':
$result = $this->categoryRepository->categoryStartsWith($value, 1337);
$result = $this->categoryRepository->categoryStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setCategories($result);
}
@ -847,7 +845,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-category_starts':
$result = $this->categoryRepository->categoryStartsWith($value, 1337);
$result = $this->categoryRepository->categoryStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeCategories($result);
}
@ -858,7 +856,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'category_contains':
$result = $this->categoryRepository->searchCategory($value, 1337);
$result = $this->categoryRepository->searchCategory($value, 1337);
if ($result->count() > 0) {
$this->collector->setCategories($result);
}
@ -869,7 +867,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-category_contains':
$result = $this->categoryRepository->searchCategory($value, 1337);
$result = $this->categoryRepository->searchCategory($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeCategories($result);
}
@ -879,9 +877,9 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// budgets
//
//
// budgets
//
case '-has_any_budget':
case 'has_no_budget':
$this->collector->withoutBudget();
@ -895,7 +893,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'budget_contains':
$result = $this->budgetRepository->searchBudget($value, 1337);
$result = $this->budgetRepository->searchBudget($value, 1337);
if ($result->count() > 0) {
$this->collector->setBudgets($result);
}
@ -906,7 +904,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-budget_contains':
$result = $this->budgetRepository->searchBudget($value, 1337);
$result = $this->budgetRepository->searchBudget($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBudgets($result);
}
@ -917,7 +915,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'budget_is':
$budget = $this->budgetRepository->findByName($value);
$budget = $this->budgetRepository->findByName($value);
if (null !== $budget) {
$this->collector->setBudget($budget);
@ -928,7 +926,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-budget_is':
$budget = $this->budgetRepository->findByName($value);
$budget = $this->budgetRepository->findByName($value);
if (null !== $budget) {
$this->collector->excludeBudget($budget);
@ -939,7 +937,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'budget_ends':
$result = $this->budgetRepository->budgetEndsWith($value, 1337);
$result = $this->budgetRepository->budgetEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setBudgets($result);
}
@ -950,7 +948,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-budget_ends':
$result = $this->budgetRepository->budgetEndsWith($value, 1337);
$result = $this->budgetRepository->budgetEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBudgets($result);
}
@ -961,7 +959,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'budget_starts':
$result = $this->budgetRepository->budgetStartsWith($value, 1337);
$result = $this->budgetRepository->budgetStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setBudgets($result);
}
@ -972,7 +970,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-budget_starts':
$result = $this->budgetRepository->budgetStartsWith($value, 1337);
$result = $this->budgetRepository->budgetStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBudgets($result);
}
@ -982,9 +980,9 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// bill
//
//
// bill
//
case '-has_any_bill':
case 'has_no_bill':
$this->collector->withoutBill();
@ -998,7 +996,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'bill_contains':
$result = $this->billRepository->searchBill($value, 1337);
$result = $this->billRepository->searchBill($value, 1337);
if ($result->count() > 0) {
$this->collector->setBills($result);
@ -1009,7 +1007,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-bill_contains':
$result = $this->billRepository->searchBill($value, 1337);
$result = $this->billRepository->searchBill($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBills($result);
@ -1020,7 +1018,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'bill_is':
$bill = $this->billRepository->findByName($value);
$bill = $this->billRepository->findByName($value);
if (null !== $bill) {
$this->collector->setBill($bill);
@ -1031,7 +1029,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-bill_is':
$bill = $this->billRepository->findByName($value);
$bill = $this->billRepository->findByName($value);
if (null !== $bill) {
$this->collector->excludeBills(new Collection([$bill]));
@ -1042,7 +1040,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'bill_ends':
$result = $this->billRepository->billEndsWith($value, 1337);
$result = $this->billRepository->billEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setBills($result);
}
@ -1053,7 +1051,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-bill_ends':
$result = $this->billRepository->billEndsWith($value, 1337);
$result = $this->billRepository->billEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBills($result);
}
@ -1064,7 +1062,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'bill_starts':
$result = $this->billRepository->billStartsWith($value, 1337);
$result = $this->billRepository->billStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setBills($result);
}
@ -1075,7 +1073,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-bill_starts':
$result = $this->billRepository->billStartsWith($value, 1337);
$result = $this->billRepository->billStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBills($result);
}
@ -1085,9 +1083,9 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// tags
//
//
// tags
//
case '-has_any_tag':
case 'has_no_tag':
$this->collector->withoutTags();
@ -1102,7 +1100,7 @@ class OperatorQuerySearch implements SearchInterface
case '-tag_is_not':
case 'tag_is':
$result = $this->tagRepository->findByTag($value);
$result = $this->tagRepository->findByTag($value);
if (null !== $result) {
$this->includeTags[] = $result->id;
$this->includeTags = array_unique($this->includeTags);
@ -1116,7 +1114,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'tag_contains':
$tags = $this->tagRepository->searchTag($value);
$tags = $this->tagRepository->searchTag($value);
if (0 === $tags->count()) {
app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
$this->collector->findNothing();
@ -1130,7 +1128,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'tag_starts':
$tags = $this->tagRepository->tagStartsWith($value);
$tags = $this->tagRepository->tagStartsWith($value);
if (0 === $tags->count()) {
app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
$this->collector->findNothing();
@ -1144,7 +1142,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-tag_starts':
$tags = $this->tagRepository->tagStartsWith($value);
$tags = $this->tagRepository->tagStartsWith($value);
if (0 === $tags->count()) {
app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
$this->collector->findNothing();
@ -1157,7 +1155,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case 'tag_ends':
$tags = $this->tagRepository->tagEndsWith($value);
$tags = $this->tagRepository->tagEndsWith($value);
if (0 === $tags->count()) {
app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
$this->collector->findNothing();
@ -1170,7 +1168,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-tag_ends':
$tags = $this->tagRepository->tagEndsWith($value);
$tags = $this->tagRepository->tagEndsWith($value);
if (0 === $tags->count()) {
app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
$this->collector->findNothing();
@ -1183,7 +1181,7 @@ class OperatorQuerySearch implements SearchInterface
break;
case '-tag_contains':
$tags = $this->tagRepository->searchTag($value)->keyBy('id');
$tags = $this->tagRepository->searchTag($value)->keyBy('id');
if (0 === $tags->count()) {
app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
@ -1198,7 +1196,7 @@ class OperatorQuerySearch implements SearchInterface
case '-tag_is':
case 'tag_is_not':
$result = $this->tagRepository->findByTag($value);
$result = $this->tagRepository->findByTag($value);
if (null !== $result) {
$this->excludeTags[] = $result->id;
$this->excludeTags = array_unique($this->excludeTags);
@ -1206,9 +1204,9 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// notes
//
//
// notes
//
case 'notes_contains':
$this->collector->notesContain($value);
@ -1271,14 +1269,14 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// amount
//
//
// amount
//
case 'amount_is':
// strip comma's, make dots.
app('log')->debug(sprintf('Original value "%s"', $value));
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->amountIs($amount);
@ -1287,8 +1285,8 @@ class OperatorQuerySearch implements SearchInterface
case '-amount_is':
// strip comma's, make dots.
app('log')->debug(sprintf('Original value "%s"', $value));
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->amountIsNot($amount);
@ -1296,9 +1294,9 @@ class OperatorQuerySearch implements SearchInterface
case 'foreign_amount_is':
// strip comma's, make dots.
$value = str_replace(',', '.', $value);
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
$amount = app('steam')->positive($value);
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->foreignAmountIs($amount);
@ -1306,9 +1304,9 @@ class OperatorQuerySearch implements SearchInterface
case '-foreign_amount_is':
// strip comma's, make dots.
$value = str_replace(',', '.', $value);
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
$amount = app('steam')->positive($value);
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->foreignAmountIsNot($amount);
@ -1317,9 +1315,9 @@ class OperatorQuerySearch implements SearchInterface
case '-amount_more':
case 'amount_less':
// strip comma's, make dots.
$value = str_replace(',', '.', $value);
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
$amount = app('steam')->positive($value);
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->amountLess($amount);
@ -1328,9 +1326,9 @@ class OperatorQuerySearch implements SearchInterface
case '-foreign_amount_more':
case 'foreign_amount_less':
// strip comma's, make dots.
$value = str_replace(',', '.', $value);
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
$amount = app('steam')->positive($value);
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->foreignAmountLess($amount);
@ -1340,8 +1338,8 @@ class OperatorQuerySearch implements SearchInterface
case 'amount_more':
app('log')->debug(sprintf('Now handling operator "%s"', $operator));
// strip comma's, make dots.
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->amountMore($amount);
@ -1351,16 +1349,16 @@ class OperatorQuerySearch implements SearchInterface
case 'foreign_amount_more':
app('log')->debug(sprintf('Now handling operator "%s"', $operator));
// strip comma's, make dots.
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
$value = str_replace(',', '.', $value);
$amount = app('steam')->positive($value);
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->foreignAmountMore($amount);
break;
//
// transaction type
//
//
// transaction type
//
case 'transaction_type':
$this->collector->setTypes([ucfirst($value)]);
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
@ -1373,152 +1371,152 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// dates
//
//
// dates
//
case '-date_on':
case 'date_on':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setExactDateParams($range, $prohibited);
return false;
case 'date_before':
case '-date_after':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setDateBeforeParams($range);
return false;
case 'date_after':
case '-date_before':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setDateAfterParams($range);
return false;
case 'interest_date_on':
case '-interest_date_on':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('interest_date', $range, $prohibited);
return false;
case 'interest_date_before':
case '-interest_date_after':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('interest_date', $range);
return false;
case 'interest_date_after':
case '-interest_date_before':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('interest_date', $range);
return false;
case 'book_date_on':
case '-book_date_on':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('book_date', $range, $prohibited);
return false;
case 'book_date_before':
case '-book_date_after':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('book_date', $range);
return false;
case 'book_date_after':
case '-book_date_before':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('book_date', $range);
return false;
case 'process_date_on':
case '-process_date_on':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('process_date', $range, $prohibited);
return false;
case 'process_date_before':
case '-process_date_after':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('process_date', $range);
return false;
case 'process_date_after':
case '-process_date_before':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('process_date', $range);
return false;
case 'due_date_on':
case '-due_date_on':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('due_date', $range, $prohibited);
return false;
case 'due_date_before':
case '-due_date_after':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('due_date', $range);
return false;
case 'due_date_after':
case '-due_date_before':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('due_date', $range);
return false;
case 'payment_date_on':
case '-payment_date_on':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('payment_date', $range, $prohibited);
return false;
case 'payment_date_before':
case '-payment_date_after':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('payment_date', $range);
return false;
case 'payment_date_after':
case '-payment_date_before':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('payment_date', $range);
return false;
case 'invoice_date_on':
case '-invoice_date_on':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('invoice_date', $range, $prohibited);
return false;
case 'invoice_date_before':
case '-invoice_date_after':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('invoice_date', $range);
return false;
case 'invoice_date_after':
case '-invoice_date_before':
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('invoice_date', $range);
return false;
@ -1526,7 +1524,7 @@ class OperatorQuerySearch implements SearchInterface
case 'created_at_on':
case '-created_at_on':
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setExactObjectDateParams('created_at', $range, $prohibited);
return false;
@ -1534,7 +1532,7 @@ class OperatorQuerySearch implements SearchInterface
case 'created_at_before':
case '-created_at_after':
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setObjectDateBeforeParams('created_at', $range);
return false;
@ -1542,7 +1540,7 @@ class OperatorQuerySearch implements SearchInterface
case 'created_at_after':
case '-created_at_before':
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setObjectDateAfterParams('created_at', $range);
return false;
@ -1550,7 +1548,7 @@ class OperatorQuerySearch implements SearchInterface
case 'updated_at_on':
case '-updated_at_on':
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setExactObjectDateParams('updated_at', $range, $prohibited);
return false;
@ -1558,7 +1556,7 @@ class OperatorQuerySearch implements SearchInterface
case 'updated_at_before':
case '-updated_at_after':
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setObjectDateBeforeParams('updated_at', $range);
return false;
@ -1566,14 +1564,14 @@ class OperatorQuerySearch implements SearchInterface
case 'updated_at_after':
case '-updated_at_before':
app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
$range = $this->parseDateRange($operator, $value);
$range = $this->parseDateRange($operator, $value);
$this->setObjectDateAfterParams('updated_at', $range);
return false;
//
// external URL
//
//
// external URL
//
case '-any_external_url':
case 'no_external_url':
$this->collector->withoutExternalUrl();
@ -1638,9 +1636,9 @@ class OperatorQuerySearch implements SearchInterface
break;
//
// other fields
//
//
// other fields
//
case 'external_id_is':
$this->collector->setExternalId($value);
@ -1842,7 +1840,7 @@ class OperatorQuerySearch implements SearchInterface
$operator = substr($operator, 1);
}
$config = config(sprintf('search.operators.%s', $operator));
$config = config(sprintf('search.operators.%s', $operator));
if (null === $config) {
throw new FireflyException(sprintf('No configuration for search operator "%s"', $operator));
}
@ -1896,7 +1894,7 @@ class OperatorQuerySearch implements SearchInterface
}
}
// string position (default): starts with:
$stringMethod = 'str_starts_with';
$stringMethod = 'str_starts_with';
// string position: ends with:
if (StringPosition::ENDS === $stringPosition) {
@ -1910,7 +1908,7 @@ class OperatorQuerySearch implements SearchInterface
}
// get accounts:
$accounts = $this->accountRepository->searchAccount($value, $searchTypes, 1337);
$accounts = $this->accountRepository->searchAccount($value, $searchTypes, 1337);
if (0 === $accounts->count() && false === $prohibited) {
app('log')->debug('Found zero accounts, search for non existing account, NO results will be returned.');
$this->collector->findNothing();
@ -1923,7 +1921,7 @@ class OperatorQuerySearch implements SearchInterface
return;
}
app('log')->debug(sprintf('Found %d accounts, will filter.', $accounts->count()));
$filtered = $accounts->filter(
$filtered = $accounts->filter(
static function (Account $account) use ($value, $stringMethod) {
return $stringMethod(strtolower($account->name), strtolower($value));
}
@ -1978,7 +1976,7 @@ class OperatorQuerySearch implements SearchInterface
}
// string position (default): starts with:
$stringMethod = 'str_starts_with';
$stringMethod = 'str_starts_with';
// string position: ends with:
if (StringPosition::ENDS === $stringPosition) {
@ -1992,7 +1990,7 @@ class OperatorQuerySearch implements SearchInterface
}
// search for accounts:
$accounts = $this->accountRepository->searchAccountNr($value, $searchTypes, 1337);
$accounts = $this->accountRepository->searchAccountNr($value, $searchTypes, 1337);
if (0 === $accounts->count()) {
app('log')->debug('Found zero accounts, search for invalid account.');
$this->collector->findNothing();
@ -2002,7 +2000,7 @@ class OperatorQuerySearch implements SearchInterface
// if found, do filter
app('log')->debug(sprintf('Found %d accounts, will filter.', $accounts->count()));
$filtered = $accounts->filter(
$filtered = $accounts->filter(
static function (Account $account) use ($value, $stringMethod) {
// either IBAN or account number
$ibanMatch = $stringMethod(strtolower((string) $account->iban), strtolower($value));

View File

@ -24,18 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\Support;
use Carbon\Carbon;
use DB;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use stdClass;
use Str;
use ValueError;
/**
* Class Steam.
@ -44,8 +38,8 @@ class Steam
{
public function getAccountCurrency(Account $account): ?TransactionCurrency
{
$type = $account->accountType->type;
$list = config('firefly.valid_currency_account_types');
$type = $account->accountType->type;
$list = config('firefly.valid_currency_account_types');
// return null if not in this list.
if (!in_array($type, $list, true)) {
@ -55,6 +49,7 @@ class Steam
if (null === $result) {
return null;
}
return TransactionCurrency::find((int) $result->data);
}
@ -72,7 +67,6 @@ class Steam
return $sum;
}
public function finalAccountBalanceInRange(Account $account, Carbon $start, Carbon $end): array
{
// expand period.
@ -80,7 +74,7 @@ class Steam
$end->addDay()->endOfDay();
// set up cache
$cache = new CacheProperties();
$cache = new CacheProperties();
$cache->addProperty($account->id);
$cache->addProperty('final-balance-in-range');
$cache->addProperty($start);
@ -89,51 +83,52 @@ class Steam
// return $cache->get();
}
$balances = [];
$formatted = $start->format('Y-m-d');
$startBalance = $this->finalAccountBalance($account, $start);
$defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
$currency = $this->getAccountCurrency($account) ?? $defaultCurrency;
$currencies = [
$balances = [];
$formatted = $start->format('Y-m-d');
$startBalance = $this->finalAccountBalance($account, $start);
$defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
$currency = $this->getAccountCurrency($account) ?? $defaultCurrency;
$currencies = [
$currency->id => $currency,
$defaultCurrency->id => $defaultCurrency,
];
$startBalance[$defaultCurrency->code] ??= '0';
$startBalance[$currency->code] ??= '0';
$balances[$formatted] = $startBalance;
$balances[$formatted] = $startBalance;
// sums up the balance changes per day, for foreign, native and normal amounts.
$set = $account->transactions()
->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s'))
->groupBy('transaction_journals.date')
->groupBy('transactions.transaction_currency_id')
->groupBy('transactions.foreign_currency_id')
->orderBy('transaction_journals.date', 'ASC')
->whereNull('transaction_journals.deleted_at')
->get(
[ // @phpstan-ignore-line
'transaction_journals.date',
'transactions.transaction_currency_id',
DB::raw('SUM(transactions.amount) AS modified'),
'transactions.foreign_currency_id',
DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'),
DB::raw('SUM(transactions.native_amount) AS modified_native'),
]
);
$set = $account->transactions()
->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s'))
->groupBy('transaction_journals.date')
->groupBy('transactions.transaction_currency_id')
->groupBy('transactions.foreign_currency_id')
->orderBy('transaction_journals.date', 'ASC')
->whereNull('transaction_journals.deleted_at')
->get(
[ // @phpstan-ignore-line
'transaction_journals.date',
'transactions.transaction_currency_id',
\DB::raw('SUM(transactions.amount) AS modified'),
'transactions.foreign_currency_id',
\DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'),
\DB::raw('SUM(transactions.native_amount) AS modified_native'),
]
)
;
$currentBalance = $startBalance;
$currentBalance = $startBalance;
/** @var Transaction $entry */
foreach ($set as $entry) {
// normal, native and foreign amount
$carbon = new Carbon($entry->date, $entry->date_tz);
$modified = (string) (null === $entry->modified ? '0' : $entry->modified);
$foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign);
$nativeModified = (string) (null === $entry->modified_native ? '0' : $entry->modified_native);
$carbon = new Carbon($entry->date, $entry->date_tz);
$modified = (string) (null === $entry->modified ? '0' : $entry->modified);
$foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign);
$nativeModified = (string) (null === $entry->modified_native ? '0' : $entry->modified_native);
// add "modified" to amount if the currency id matches the account currency id.
if ($entry->transaction_currency_id === $currency->id) {
@ -142,7 +137,7 @@ class Steam
}
// always add the native balance, even if it ends up at zero.
$currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeModified);
$currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeModified);
// add modified foreign to the array
if (null !== $entry->foreign_currency_id) {
@ -159,11 +154,13 @@ class Steam
return $balances;
}
public function finalAccountsBalance(Collection $accounts, Carbon $date): array {
public function finalAccountsBalance(Collection $accounts, Carbon $date): array
{
$balances = [];
foreach ($accounts as $account) {
$balances[$account->id] = $this->finalAccountBalance($account, $date);
}
return $balances;
}
@ -186,10 +183,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;
@ -261,26 +258,22 @@ class Steam
* THAT currency.
* "native_balance" the balance according to the "native_amount" + "native_foreign_amount" fields.
* "ABC" the balance in this particular currency code (may repeat for each found currency).
*
* @param Account $account
* @param Carbon $date
*
* @return array
*/
public function finalAccountBalance(Account $account, Carbon $date): array
{
$native = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
$currency = $this->getAccountCurrency($account) ?? $native;
$return = [
$native = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
$currency = $this->getAccountCurrency($account) ?? $native;
$return = [
'native_balance' => '0',
];
Log::debug(sprintf('Now in finalAccountBalance("%s", "%s")', $account->name, $date->format('Y-m-d H:i:s')));
// first, the "balance", as described earlier.
$array = $account->transactions()
->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', $currency->id)
->get(['transactions.amount'])->toArray();
->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', $currency->id)
->get(['transactions.amount'])->toArray()
;
$return['balance'] = $this->sumTransactions($array, 'amount');
//Log::debug(sprintf('balance is %s', $return['balance']));
// add virtual balance:
@ -290,9 +283,10 @@ class Steam
// then, native balance (if necessary(
if ($native->id !== $currency->id) {
$array = $account->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
->get(['transactions.native_amount'])->toArray();
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s'))
->get(['transactions.native_amount'])->toArray()
;
$return['native_balance'] = $this->sumTransactions($array, 'native_amount');
// Log::debug(sprintf('native_balance is %s', $return['native_balance']));
$return['native_balance'] = bcadd('' === (string) $account->native_virtual_balance ? '0' : $account->native_virtual_balance, $return['balance']);
@ -307,6 +301,7 @@ class Steam
->get(['transaction_currencies.code', 'transactions.amount'])->toArray();
$others = $this->groupAndSumTransactions($array, 'code', 'amount');
// Log::debug('All others are (joined)', $others);
return array_merge($return, $others);
}
@ -318,6 +313,7 @@ class Steam
$groupKey = $item[$group] ?? 'unknown';
$return[$groupKey] = bcadd($return[$groupKey] ?? '0', $item[$field]);
}
return $return;
}
@ -330,7 +326,7 @@ class Steam
try {
$hostName = gethostbyaddr($ipAddress);
} catch (Exception $e) {
} catch (\Exception $e) {
app('log')->error($e->getMessage());
$hostName = $ipAddress;
}
@ -346,15 +342,15 @@ class Steam
{
$list = [];
$set = auth()->user()->transactions()
->whereIn('transactions.account_id', $accounts)
->groupBy(['transactions.account_id', 'transaction_journals.user_id'])
->get(['transactions.account_id', DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line
$set = auth()->user()->transactions()
->whereIn('transactions.account_id', $accounts)
->groupBy(['transactions.account_id', 'transaction_journals.user_id'])
->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line
;
/** @var Transaction $entry */
foreach ($set as $entry) {
$date = new Carbon($entry->max_date, config('app.timezone'));
$date = new Carbon($entry->max_date, config('app.timezone'));
$date->setTimezone(config('app.timezone'));
$list[(int)$entry->account_id] = $date;
}
@ -429,9 +425,9 @@ class Steam
public function getSafeUrl(string $unknownUrl, string $safeUrl): string
{
// Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl));
$returnUrl = $safeUrl;
$unknownHost = parse_url($unknownUrl, PHP_URL_HOST);
$safeHost = parse_url($safeUrl, PHP_URL_HOST);
$returnUrl = $safeUrl;
$unknownHost = parse_url($unknownUrl, PHP_URL_HOST);
$safeHost = parse_url($safeUrl, PHP_URL_HOST);
if (null !== $unknownHost && $unknownHost === $safeHost) {
$returnUrl = $unknownUrl;
@ -439,7 +435,7 @@ class Steam
// URL must not lead to weird pages
$forbiddenWords = ['jscript', 'json', 'debug', 'serviceworker', 'offline', 'delete', '/login', '/attachments/view'];
if (Str::contains($returnUrl, $forbiddenWords)) {
if (\Str::contains($returnUrl, $forbiddenWords)) {
$returnUrl = $safeUrl;
}
@ -468,7 +464,7 @@ class Steam
*/
public function floatalize(string $value): string
{
$value = strtoupper($value);
$value = strtoupper($value);
if (!str_contains($value, 'E')) {
return $value;
}
@ -537,7 +533,7 @@ class Steam
if (-1 === bccomp($amount, '0')) {
$amount = bcmul($amount, '-1');
}
} catch (ValueError $e) {
} catch (\ValueError $e) {
Log::error(sprintf('ValueError in Steam::positive("%s"): %s', $amount, $e->getMessage()));
Log::error($e->getTraceAsString());

View File

@ -24,8 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Support\System;
use Artisan;
use Crypt;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Contracts\Encryption\DecryptException;
use Laravel\Passport\Console\KeysCommand;
@ -67,7 +65,7 @@ class OAuthKeys
try {
$privateKey = (string) app('fireflyconfig')->get(self::PRIVATE_KEY)?->data;
$publicKey = (string) app('fireflyconfig')->get(self::PUBLIC_KEY)?->data;
} catch (ContainerExceptionInterface | FireflyException | NotFoundExceptionInterface $e) {
} catch (ContainerExceptionInterface|FireflyException|NotFoundExceptionInterface $e) {
app('log')->error(sprintf('Could not validate keysInDatabase(): %s', $e->getMessage()));
app('log')->error($e->getTraceAsString());
}
@ -89,16 +87,16 @@ class OAuthKeys
public static function generateKeys(): void
{
Artisan::registerCommand(new KeysCommand());
Artisan::call('firefly-iii:laravel-passport-keys');
\Artisan::registerCommand(new KeysCommand());
\Artisan::call('firefly-iii:laravel-passport-keys');
}
public static function storeKeysInDB(): void
{
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
app('fireflyconfig')->set(self::PRIVATE_KEY, Crypt::encrypt(file_get_contents($private)));
app('fireflyconfig')->set(self::PUBLIC_KEY, Crypt::encrypt(file_get_contents($public)));
app('fireflyconfig')->set(self::PRIVATE_KEY, \Crypt::encrypt(file_get_contents($private)));
app('fireflyconfig')->set(self::PUBLIC_KEY, \Crypt::encrypt(file_get_contents($public)));
}
/**
@ -110,8 +108,8 @@ class OAuthKeys
$publicKey = (string) app('fireflyconfig')->get(self::PUBLIC_KEY)?->data;
try {
$privateContent = Crypt::decrypt($privateKey);
$publicContent = Crypt::decrypt($publicKey);
$privateContent = \Crypt::decrypt($privateKey);
$publicContent = \Crypt::decrypt($publicKey);
} catch (DecryptException $e) {
app('log')->error('Could not decrypt pub/private keypair.');
app('log')->error($e->getMessage());
@ -122,8 +120,8 @@ class OAuthKeys
return false;
}
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
file_put_contents($private, $privateContent);
file_put_contents($public, $publicContent);

View File

@ -108,8 +108,8 @@ class AmountFormat extends AbstractExtension
return new TwigFunction(
'formatAmountBySymbol',
static function (string $amount, string $symbol, ?int $decimalPlaces = null, ?bool $coloured = null): string {
$decimalPlaces ??= 2;
$coloured ??= true;
$decimalPlaces ??= 2;
$coloured ??= true;
$currency = new TransactionCurrency();
$currency->symbol = $symbol;
$currency->decimal_places = $decimalPlaces;

View File

@ -78,6 +78,7 @@ class General extends AbstractExtension
if (!$convertToNative || $currency->code === $native->code) {
$strings[] = app('amount')->formatAnything($currency, $balance, false);
}
continue;
}
if ('native_balance' === $key) {
@ -85,6 +86,7 @@ class General extends AbstractExtension
if ($convertToNative) {
$strings[] = app('amount')->formatAnything($native, $balance, false);
}
continue;
}
if ($key !== $currency->code) {
@ -108,15 +110,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';
}
);
}
@ -138,7 +140,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':
@ -147,7 +149,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':
@ -163,7 +165,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':
@ -174,7 +176,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':
@ -186,7 +188,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':
@ -282,7 +284,7 @@ class General extends AbstractExtension
$args = func_get_args();
$route = $args[0]; // name of the route.
if (Route::getCurrentRoute()->getName() === $route) {
if (\Route::getCurrentRoute()->getName() === $route) {
return 'active';
}
@ -302,7 +304,7 @@ class General extends AbstractExtension
static function (): string {
$args = func_get_args();
$route = $args[0]; // name of the route.
$name = Route::getCurrentRoute()->getName() ?? '';
$name = \Route::getCurrentRoute()->getName() ?? '';
if (str_contains($name, $route)) {
return 'active';
}
@ -322,11 +324,11 @@ 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(
Route::getCurrentRoute()->getName(),
\Route::getCurrentRoute()->getName(),
$route
)) {
return 'active';
@ -349,7 +351,7 @@ class General extends AbstractExtension
static function (): string {
$args = func_get_args();
$route = $args[0]; // name of the route.
$name = Route::getCurrentRoute()->getName() ?? '';
$name = \Route::getCurrentRoute()->getName() ?? '';
if (str_contains($name, $route)) {
return 'menu-open';
}

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Support\Twig;
use Config;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
@ -64,7 +63,7 @@ class Rule extends AbstractExtension
$possibleTriggers = [];
foreach ($ruleTriggers as $key) {
if ('user_action' !== $key) {
$possibleTriggers[$key] = (string) trans('firefly.rule_trigger_' . $key . '_choice');
$possibleTriggers[$key] = (string) trans('firefly.rule_trigger_'.$key.'_choice');
}
}
unset($ruleTriggers);
@ -81,10 +80,10 @@ class Rule extends AbstractExtension
'allRuleActions',
static function () {
// array of valid values for actions
$ruleActions = array_keys(Config::get('firefly.rule-actions'));
$ruleActions = array_keys(\Config::get('firefly.rule-actions'));
$possibleActions = [];
foreach ($ruleActions as $key) {
$possibleActions[$key] = (string) trans('firefly.rule_action_' . $key . '_choice');
$possibleActions[$key] = (string) trans('firefly.rule_action_'.$key.'_choice');
}
unset($ruleActions);
asort($possibleActions);

View File

@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Support\Twig;
use Carbon\Carbon;
use DB;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
@ -87,7 +86,7 @@ class TransactionGroupTwig extends AbstractExtension
$colored = false;
}
$result = app('amount')->formatFlat($array['currency_symbol'], (int) $array['currency_decimal_places'], $amount, $colored);
$result = app('amount')->formatFlat($array['currency_symbol'], (int) $array['currency_decimal_places'], $amount, $colored);
if (TransactionType::TRANSFER === $type) {
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
}
@ -120,9 +119,9 @@ class TransactionGroupTwig extends AbstractExtension
*/
private function foreignJournalArrayAmount(array $array): string
{
$type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL;
$amount = $array['foreign_amount'] ?? '0';
$colored = true;
$type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL;
$amount = $array['foreign_amount'] ?? '0';
$colored = true;
$sourceType = $array['source_account_type'] ?? 'invalid';
$amount = $this->signAmount($amount, $type, $sourceType);
@ -130,7 +129,7 @@ class TransactionGroupTwig extends AbstractExtension
if (TransactionType::TRANSFER === $type) {
$colored = false;
}
$result = app('amount')->formatFlat($array['foreign_currency_symbol'], (int) $array['foreign_currency_decimal_places'], $amount, $colored);
$result = app('amount')->formatFlat($array['foreign_currency_symbol'], (int) $array['foreign_currency_decimal_places'], $amount, $colored);
if (TransactionType::TRANSFER === $type) {
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
}
@ -171,12 +170,12 @@ class TransactionGroupTwig extends AbstractExtension
$colored = true;
$sourceType = $first->account()->first()->accountType()->first()->type;
$amount = $this->signAmount($amount, $type, $sourceType);
$amount = $this->signAmount($amount, $type, $sourceType);
if (TransactionType::TRANSFER === $type) {
$colored = false;
}
$result = app('amount')->formatFlat($currency->symbol, $currency->decimal_places, $amount, $colored);
$result = app('amount')->formatFlat($currency->symbol, $currency->decimal_places, $amount, $colored);
if (TransactionType::TRANSFER === $type) {
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
}
@ -197,7 +196,7 @@ class TransactionGroupTwig extends AbstractExtension
*/
private function foreignJournalObjectAmount(TransactionJournal $journal): string
{
$type = $journal->transactionType->type;
$type = $journal->transactionType->type;
/** @var Transaction $first */
$first = $journal->transactions()->where('amount', '<', 0)->first();
@ -206,12 +205,12 @@ class TransactionGroupTwig extends AbstractExtension
$colored = true;
$sourceType = $first->account()->first()->accountType()->first()->type;
$amount = $this->signAmount($amount, $type, $sourceType);
$amount = $this->signAmount($amount, $type, $sourceType);
if (TransactionType::TRANSFER === $type) {
$colored = false;
}
$result = app('amount')->formatFlat($currency->symbol, $currency->decimal_places, $amount, $colored);
$result = app('amount')->formatFlat($currency->symbol, $currency->decimal_places, $amount, $colored);
if (TransactionType::TRANSFER === $type) {
$result = sprintf('<span class="text-info money-transfer">%s</span>', $result);
}
@ -224,11 +223,12 @@ class TransactionGroupTwig extends AbstractExtension
return new TwigFunction(
'journalHasMeta',
static function (int $journalId, string $metaField) {
$count = DB::table('journal_meta')
->where('name', $metaField)
->where('transaction_journal_id', $journalId)
->whereNull('deleted_at')
->count();
$count = \DB::table('journal_meta')
->where('name', $metaField)
->where('transaction_journal_id', $journalId)
->whereNull('deleted_at')
->count()
;
return 1 === $count;
}
@ -241,11 +241,12 @@ class TransactionGroupTwig extends AbstractExtension
'journalGetMetaDate',
static function (int $journalId, string $metaField) {
/** @var null|TransactionJournalMeta $entry */
$entry = DB::table('journal_meta')
->where('name', $metaField)
->where('transaction_journal_id', $journalId)
->whereNull('deleted_at')
->first();
$entry = \DB::table('journal_meta')
->where('name', $metaField)
->where('transaction_journal_id', $journalId)
->whereNull('deleted_at')
->first()
;
if (null === $entry) {
return today(config('app.timezone'));
}
@ -261,11 +262,12 @@ class TransactionGroupTwig extends AbstractExtension
'journalGetMetaField',
static function (int $journalId, string $metaField) {
/** @var null|TransactionJournalMeta $entry */
$entry = DB::table('journal_meta')
->where('name', $metaField)
->where('transaction_journal_id', $journalId)
->whereNull('deleted_at')
->first();
$entry = \DB::table('journal_meta')
->where('name', $metaField)
->where('transaction_journal_id', $journalId)
->whereNull('deleted_at')
->first()
;
if (null === $entry) {
return '';
}

View File

@ -14,17 +14,14 @@
"/public/v1/js/app.js.LICENSE.txt": "/public/v1/js/app.js.LICENSE.txt",
"/public/v1/js/app_vue.js": "/public/v1/js/app_vue.js",
"/public/v1/js/app_vue.js.LICENSE.txt": "/public/v1/js/app_vue.js.LICENSE.txt",
"/public/v1/js/create.js": "/public/v1/js/create.js",
"/public/v1/js/create.js.LICENSE.txt": "/public/v1/js/create.js.LICENSE.txt",
"/public/v1/js/create_transaction.js": "/public/v1/js/create_transaction.js",
"/public/v1/js/create_transaction.js.LICENSE.txt": "/public/v1/js/create_transaction.js.LICENSE.txt",
"/public/v1/js/edit.js": "/public/v1/js/edit.js",
"/public/v1/js/edit.js.LICENSE.txt": "/public/v1/js/edit.js.LICENSE.txt",
"/public/v1/js/edit_transaction.js": "/public/v1/js/edit_transaction.js",
"/public/v1/js/edit_transaction.js.LICENSE.txt": "/public/v1/js/edit_transaction.js.LICENSE.txt",
"/public/v1/js/exchange-rates/index.js": "/public/v1/js/exchange-rates/index.js",
"/public/v1/js/exchange-rates/index.js.LICENSE.txt": "/public/v1/js/exchange-rates/index.js.LICENSE.txt",
"/public/v1/js/exchange-rates/rates.js": "/public/v1/js/exchange-rates/rates.js",
"/public/v1/js/exchange-rates/rates.js.LICENSE.txt": "/public/v1/js/exchange-rates/rates.js.LICENSE.txt",
"/public/v1/js/ff/accounts/create.js": "/public/v1/js/ff/accounts/create.js",
"/public/v1/js/ff/accounts/edit-reconciliation.js": "/public/v1/js/ff/accounts/edit-reconciliation.js",
"/public/v1/js/ff/accounts/edit.js": "/public/v1/js/ff/accounts/edit.js",
@ -93,8 +90,6 @@
"/public/v1/js/ff/transactions/mass/edit-bulk.js": "/public/v1/js/ff/transactions/mass/edit-bulk.js",
"/public/v1/js/ff/transactions/mass/edit.js": "/public/v1/js/ff/transactions/mass/edit.js",
"/public/v1/js/ff/transactions/show.js": "/public/v1/js/ff/transactions/show.js",
"/public/v1/js/index.js": "/public/v1/js/index.js",
"/public/v1/js/index.js.LICENSE.txt": "/public/v1/js/index.js.LICENSE.txt",
"/public/v1/js/lib/Chart.bundle.min.js": "/public/v1/js/lib/Chart.bundle.min.js",
"/public/v1/js/lib/accounting.min.js": "/public/v1/js/lib/accounting.min.js",
"/public/v1/js/lib/bootstrap-multiselect.js": "/public/v1/js/lib/bootstrap-multiselect.js",
@ -153,8 +148,6 @@
"/public/v1/js/lib/vue.js": "/public/v1/js/lib/vue.js",
"/public/v1/js/profile.js": "/public/v1/js/profile.js",
"/public/v1/js/profile.js.LICENSE.txt": "/public/v1/js/profile.js.LICENSE.txt",
"/public/v1/js/show.js": "/public/v1/js/show.js",
"/public/v1/js/show.js.LICENSE.txt": "/public/v1/js/show.js.LICENSE.txt",
"/public/v1/js/webhooks/create.js": "/public/v1/js/webhooks/create.js",
"/public/v1/js/webhooks/create.js.LICENSE.txt": "/public/v1/js/webhooks/create.js.LICENSE.txt",
"/public/v1/js/webhooks/edit.js": "/public/v1/js/webhooks/edit.js",

View File

@ -136,9 +136,9 @@
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates. Inverse is automatically calculated if not provided. Will go back to last found rate.",
"header_exchange_rates_rates": "Wechselkurse",
"header_exchange_rates_table": "Tabelle mit Wechselkursen",
"help_rate_form": "On this day, how many {to} will you get for one {from}?",
"add_new_rate": "Add a new exchange rate",
"save_new_rate": "Save new rate"
"help_rate_form": "An diesem Tag, wie viele {to} werden Sie f\u00fcr einen {from} bekommen?",
"add_new_rate": "Neuen Wechselkurs hinzuf\u00fcgen",
"save_new_rate": "Neuen Kurs speichern"
},
"form": {
"url": "URL",
@ -158,7 +158,7 @@
"webhook_delivery": "Zustellung",
"from_currency_to_currency": "{from} &rarr; {to}",
"to_currency_from_currency": "{to} &rarr; {from}",
"rate": "Rate"
"rate": "Kurs"
},
"list": {
"active": "Aktiv?",

View File

@ -130,15 +130,15 @@
"response": "Odpowied\u017a",
"visit_webhook_url": "Odwied\u017a adres URL webhooka",
"reset_webhook_secret": "Resetuj sekret webhooka",
"header_exchange_rates": "Exchange rates",
"exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">the documentation<\/a>.",
"exchange_rates_from_to": "Between {from} and {to} (and the other way around)",
"exchange_rates_intro_rates": "Firefly III bla bla bla exchange rates. Inverse is automatically calculated if not provided. Will go back to last found rate.",
"header_exchange_rates_rates": "Exchange rates",
"header_exchange_rates_table": "Table with exchange rates",
"help_rate_form": "On this day, how many {to} will you get for one {from}?",
"add_new_rate": "Add a new exchange rate",
"save_new_rate": "Save new rate"
"header_exchange_rates": "Kursy wymiany",
"exchange_rates_intro": "Firefly III obs\u0142uguje pobieranie i korzystanie z kurs\u00f3w wymiany walut. Wi\u0119cej informacji na ten temat w <a href=\"https:\/\/docs.firefly-iii.org\/LOL_NOT_FINISHED_YET_TODO\">dokumentacji<\/a>.",
"exchange_rates_from_to": "Pomi\u0119dzy {from} i {to} (i odwrotnie)",
"exchange_rates_intro_rates": "Firefly III bla bla bla kurs wymiany. Odwrotno\u015b\u0107 jest obliczana automatycznie, je\u015bli nie zosta\u0142a podana. Zostanie u\u017cyty ostatni znaleziony kurs.",
"header_exchange_rates_rates": "Kursy wymiany",
"header_exchange_rates_table": "Tabela z kursami wymiany walut",
"help_rate_form": "W tym dniu, ile {to} otrzymasz za jeden {from}?",
"add_new_rate": "Dodaj nowy kurs wymiany",
"save_new_rate": "Zapisz nowy kurs"
},
"form": {
"url": "URL",
@ -158,7 +158,7 @@
"webhook_delivery": "Dor\u0119czenie",
"from_currency_to_currency": "{from} &rarr; {to}",
"to_currency_from_currency": "{to} &rarr; {from}",
"rate": "Rate"
"rate": "Kurs"
},
"list": {
"active": "Jest aktywny?",

View File

@ -1320,9 +1320,9 @@ return [
'pref_languages_help' => 'Firefly III supports several languages. Which one do you prefer?',
'pref_locale_help' => 'Firefly III allows you to set other local settings, like how currencies, numbers and dates are formatted. Entries in this list may not be supported by your system. Firefly III doesn\'t have the correct date settings for every locale; contact me for improvements.',
'pref_locale_no_demo' => 'This feature won\'t work for the demo user.',
'pref_convert_to_native' => 'Display amounts in your native currency',
'pref_convert_to_native_help' => 'This option will make Firefly III try to display and show your native currency in as many places as possible, converting amounts where necessary. This sacrifices accuracy for ease of use, because conversion is not always exact. Please verify that Firefly III has the necessary conversion rates on the "exchange rates"-page.',
'pref_convert_native_help' => 'Display native amounts',
'pref_convert_to_native' => 'Display amounts in your native currency',
'pref_convert_to_native_help' => 'This option will make Firefly III try to display and show your native currency in as many places as possible, converting amounts where necessary. This sacrifices accuracy for ease of use, because conversion is not always exact. Please verify that Firefly III has the necessary conversion rates on the "exchange rates"-page.',
'pref_convert_native_help' => 'Display native amounts',
'pref_custom_fiscal_year' => 'Fiscal year settings',
'pref_custom_fiscal_year_label' => 'Enabled',
'pref_custom_fiscal_year_help' => 'In countries that use a financial year other than January 1 to December 31, you can switch this on and specify start / end days of the fiscal year',