Merge branch 'develop' into feature/credit_calc

# Conflicts:
#	app/Repositories/Account/AccountRepository.php
This commit is contained in:
James Cole
2021-05-02 06:27:32 +02:00
99 changed files with 1254 additions and 555 deletions

View File

@@ -0,0 +1,132 @@
<?php
declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
use DB;
use Illuminate\Console\Command;
/**
* Class FixPostgresSequences
*/
class FixPostgresSequences extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Fixes issues with PostgreSQL sequences.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly-iii:fix-pgsql-sequences';
/**
* Execute the console command.
*
* @return int
*/
public function handle(): int
{
if (DB::connection()->getName() !== 'pgsql') {
$this->info('Command executed successfully.');
return 0;
}
$this->line('Going to verify PostgreSQL table sequences.');
$tablesToCheck = [
'2fa_tokens',
'account_meta',
'account_types',
'accounts',
'attachments',
'auto_budgets',
'available_budgets',
'bills',
'budget_limits',
'budget_transaction',
'budget_transaction_journal',
'budgets',
'categories',
'category_transaction',
'category_transaction_journal',
'configuration',
'currency_exchange_rates',
'export_jobs',
'failed_jobs',
'group_journals',
'import_jobs',
'jobs',
'journal_links',
'journal_meta',
'limit_repetitions',
'link_types',
'locations',
'migrations',
'notes',
'oauth_clients',
'oauth_personal_access_clients',
'object_groups',
'permissions',
'piggy_bank_events',
'piggy_bank_repetitions',
'piggy_banks',
'preferences',
'recurrences',
'recurrences_meta',
'recurrences_repetitions',
'recurrences_transactions',
'roles',
'rt_meta',
'rule_actions',
'rule_groups',
'rule_triggers',
'rules',
'tag_transaction_journal',
'tags',
'telemetry',
'transaction_currencies',
'transaction_groups',
'transaction_journals',
'transaction_types',
'transactions',
'users',
'webhook_attempts',
'webhook_messages',
'webhooks',
];
foreach ($tablesToCheck as $tableToCheck) {
$this->info(sprintf('Checking the next id sequence for table "%s".', $tableToCheck));
$highestId = DB::table($tableToCheck)->select(DB::raw('MAX(id)'))->first();
$nextId = DB::table($tableToCheck)->select(DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first();
if(null === $nextId) {
$this->line(sprintf('nextval is NULL for table "%s", go to next table.', $tableToCheck));
continue;
}
if ($nextId->nextval < $highestId->max) {
DB::select(sprintf('SELECT setval(\'%s_id_seq\', %d)', $tableToCheck, $highestId->max));
$highestId = DB::table($tableToCheck)->select(DB::raw('MAX(id)'))->first();
$nextId = DB::table($tableToCheck)->select(DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first();
if ($nextId->nextval > $highestId->max) {
$this->info(sprintf('Table "%s" autoincrement corrected.', $tableToCheck));
}
if ($nextId->nextval <= $highestId->max) {
$this->warn(sprintf('Arff! The nextval sequence is still all screwed up on table "%s".', $tableToCheck));
}
}
if ($nextId->nextval >= $highestId->max) {
$this->info(sprintf('Table "%s" autoincrement is correct.', $tableToCheck));
}
}
return 0;
}
}

View File

@@ -130,6 +130,11 @@ class UpgradeDatabase extends Command
$result = Artisan::output();
echo $result;
$this->line('Fix PostgreSQL sequences.');
Artisan::call('firefly-iii:fix-pgsql-sequences');
$result = Artisan::output();
echo $result;
$this->line('Now decrypting the database (if necessary)...');
Artisan::call('firefly-iii:decrypt-all');
$result = Artisan::output();

View File

@@ -101,7 +101,7 @@ class StandardMessageGenerator implements MessageGeneratorInterface
*/
private function getWebhooks(): Collection
{
return $this->user->webhooks()->where('active', 1)->where('trigger', $this->trigger)->get(['webhooks.*']);
return $this->user->webhooks()->where('active', true)->where('trigger', $this->trigger)->get(['webhooks.*']);
}
/**

View File

@@ -497,7 +497,7 @@ class GroupCollector implements GroupCollectorInterface
->where(
static function (EloquentBuilder $q1) {
$q1->where('attachments.attachable_type', TransactionJournal::class);
$q1->where('attachments.uploaded', 1);
$q1->where('attachments.uploaded', true);
$q1->orWhereNull('attachments.attachable_type');
}
);

View File

@@ -354,7 +354,7 @@ class ProfileController extends Controller
$user = auth()->user();
$isInternalAuth = $this->internalAuth;
$isInternalIdentity = $this->internalIdentity;
$count = DB::table('oauth_clients')->where('personal_access_client', 1)->whereNull('user_id')->count();
$count = DB::table('oauth_clients')->where('personal_access_client', true)->whereNull('user_id')->count();
$subTitle = $user->email;
$userId = $user->id;
$enabled2FA = null !== $user->mfa_secret;

View File

@@ -158,6 +158,7 @@ class SelectController extends Controller
$rule->ruleTriggers = $triggers;
// create new rule engine:
/** @var RuleEngineInterface $newRuleEngine */
$newRuleEngine = app(RuleEngineInterface::class);
// set rules:

View File

@@ -64,6 +64,7 @@ class InstallController extends Controller
$this->upgradeCommands = [
// there are 3 initial commands
'migrate' => ['--seed' => true, '--force' => true],
'firefly-iii:fix-pgsql-sequences' => [],
'firefly-iii:decrypt-all' => [],
'firefly-iii:restore-oauth-keys' => [],
'generate-keys' => [], // an exception :(

View File

@@ -77,6 +77,10 @@ class IndexController extends Controller
*/
public function index(Request $request, string $objectType, Carbon $start = null, Carbon $end = null)
{
if('transfers' === $objectType) {
$objectType = 'transfer';
}
$subTitleIcon = config('firefly.transactionIconsByType.' . $objectType);
$types = config('firefly.transactionTypesByType.' . $objectType);
$page = (int)$request->get('page');

View File

@@ -269,7 +269,7 @@ class AccountRepository implements AccountRepositoryInterface
if (0 !== count($types)) {
$query->accountTypeIn($types);
}
$query->where('active', 1);
$query->where('active', true);
$query->orderBy('accounts.account_type_id', 'ASC');
$query->orderBy('accounts.order', 'ASC');
$query->orderBy('accounts.name', 'ASC');
@@ -650,7 +650,7 @@ class AccountRepository implements AccountRepositoryInterface
public function searchAccount(string $query, array $types, int $limit): Collection
{
$dbQuery = $this->user->accounts()
->where('active', 1)
->where('active', true)
->orderBy('accounts.order', 'ASC')
->orderBy('accounts.account_type_id', 'ASC')
->orderBy('accounts.name', 'ASC')
@@ -678,8 +678,8 @@ class AccountRepository implements AccountRepositoryInterface
public function searchAccountNr(string $query, array $types, int $limit): Collection
{
$dbQuery = $this->user->accounts()->distinct()
->leftJoin('account_meta', 'accounts.id', 'account_meta.account_id')
->where('accounts.active', 1)
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('accounts.active', true)
->orderBy('accounts.order', 'ASC')
->orderBy('accounts.account_type_id', 'ASC')
->orderBy('accounts.name', 'ASC')

View File

@@ -166,7 +166,7 @@ class BillRepository implements BillRepositoryInterface
public function getActiveBills(): Collection
{
return $this->user->bills()
->where('active', 1)
->where('active', true)
->orderBy('bills.name', 'ASC')
->get(['bills.*', DB::raw('((bills.amount_min + bills.amount_max) / 2) AS expectedAmount'),]);
}

View File

@@ -197,7 +197,7 @@ class BudgetRepository implements BudgetRepositoryInterface
*/
public function getActiveBudgets(): Collection
{
return $this->user->budgets()->where('active', 1)
return $this->user->budgets()->where('active', true)
->orderBy('order', 'ASC')
->orderBy('name', 'ASC')
->get();
@@ -282,7 +282,7 @@ class BudgetRepository implements BudgetRepositoryInterface
$search->where('name', 'LIKE', sprintf('%%%s%%', $query));
}
$search->orderBy('order', 'ASC')
->orderBy('name', 'ASC')->where('active', 1);
->orderBy('name', 'ASC')->where('active', true);
return $search->take($limit)->get();
}

View File

@@ -448,7 +448,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
*/
public function searchCurrency(string $search, int $limit): Collection
{
$query = TransactionCurrency::where('enabled', 1);
$query = TransactionCurrency::where('enabled', true);
if ('' !== $search) {
$query->where('name', 'LIKE', sprintf('%%%s%%', $search));
}

View File

@@ -211,8 +211,8 @@ class RuleRepository implements RuleRepositoryInterface
{
$collection = $this->user->rules()
->leftJoin('rule_groups', 'rule_groups.id', '=', 'rules.rule_group_id')
->where('rules.active', 1)
->where('rule_groups.active', 1)
->where('rules.active', true)
->where('rule_groups.active', true)
->orderBy('rule_groups.order', 'ASC')
->orderBy('rules.order', 'ASC')
->orderBy('rules.id', 'ASC')
@@ -238,8 +238,8 @@ class RuleRepository implements RuleRepositoryInterface
{
$collection = $this->user->rules()
->leftJoin('rule_groups', 'rule_groups.id', '=', 'rules.rule_group_id')
->where('rules.active', 1)
->where('rule_groups.active', 1)
->where('rules.active', true)
->where('rule_groups.active', true)
->orderBy('rule_groups.order', 'ASC')
->orderBy('rules.order', 'ASC')
->orderBy('rules.id', 'ASC')

View File

@@ -150,7 +150,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
*/
public function getActiveGroups(): Collection
{
return $this->user->ruleGroups()->with(['rules'])->where('rule_groups.active', 1)->orderBy('order', 'ASC')->get(['rule_groups.*']);
return $this->user->ruleGroups()->with(['rules'])->where('rule_groups.active', true)->orderBy('order', 'ASC')->get(['rule_groups.*']);
}
/**
@@ -161,7 +161,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
public function getActiveRules(RuleGroup $group): Collection
{
return $group->rules()
->where('rules.active', 1)
->where('rules.active', true)
->get(['rules.*']);
}
@@ -176,7 +176,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
->where('rule_triggers.trigger_type', 'user_action')
->where('rule_triggers.trigger_value', 'store-journal')
->where('rules.active', 1)
->where('rules.active', true)
->get(['rules.*']);
}
@@ -191,7 +191,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
->where('rule_triggers.trigger_type', 'user_action')
->where('rule_triggers.trigger_value', 'update-journal')
->where('rules.active', 1)
->where('rules.active', true)
->get(['rules.*']);
}
@@ -326,7 +326,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
*/
public function maxOrder(): int
{
return (int)$this->user->ruleGroups()->where('active', 1)->max('order');
return (int)$this->user->ruleGroups()->where('active', true)->max('order');
}
/**
@@ -337,7 +337,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
$this->user->ruleGroups()->where('active', false)->update(['order' => 0]);
$set = $this->user
->ruleGroups()
->where('active', 1)
->where('active', true)
->whereNull('deleted_at')
->orderBy('order', 'ASC')
->orderBy('title', 'DESC')

View File

@@ -102,7 +102,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
$journals = $group->transactionJournals->pluck('id')->toArray();
$set = Attachment::whereIn('attachable_id', $journals)
->where('attachable_type', TransactionJournal::class)
->where('uploaded', 1)
->where('uploaded', true)
->whereNull('deleted_at')->get();
$result = [];

View File

@@ -96,7 +96,7 @@ trait JournalServiceTrait
$search = null;
// first attempt, find by ID.
if (null !== $data['id']) {
$search = $this->accountRepository->findNull($data['id']);
$search = $this->accountRepository->findNull((int) $data['id']);
if (null !== $search && in_array($search->accountType->type, $types, true)) {
Log::debug(
sprintf('Found "account_id" object: #%d, "%s" of type %s', $search->id, $search->name, $search->accountType->type)

View File

@@ -46,7 +46,7 @@ class BudgetList implements BinderInterface
if (auth()->check()) {
if ('allBudgets' === $value) {
return auth()->user()->budgets()->where('active', 1)
return auth()->user()->budgets()->where('active', true)
->orderBy('order', 'ASC')
->orderBy('name', 'ASC')
->get();
@@ -63,7 +63,7 @@ class BudgetList implements BinderInterface
/** @var Collection $collection */
$collection = auth()->user()->budgets()
->where('active', 1)
->where('active', true)
->whereIn('id', $list)
->get();

View File

@@ -61,7 +61,7 @@ trait RuleManagement
],
[
'type' => 'from_account_is',
'value' => (string)trans('firefly.default_rule_trigger_from_account'),
'value' => (string)trans('firefly.default_rule_trigger_source_account'),
'stop_processing' => false,
],

View File

@@ -145,6 +145,7 @@ class SearchRuleEngine implements RuleEngineInterface
*/
public function setRules(Collection $rules): void
{
Log::debug(__METHOD__);
foreach ($rules as $rule) {
if ($rule instanceof Rule) {
@@ -227,8 +228,16 @@ class SearchRuleEngine implements RuleEngineInterface
{
Log::debug(sprintf('Now in findStrictRule(#%d)', $rule->id ?? 0));
$searchArray = [];
/** @var Collection $triggers */
$triggers = $rule->ruleTriggers;
/** @var RuleTrigger $ruleTrigger */
foreach ($rule->ruleTriggers()->where('active', 1)->get() as $ruleTrigger) {
foreach ($triggers as $ruleTrigger) {
if (false === $ruleTrigger->active) {
continue;
}
// if needs no context, value is different:
$needsContext = config(sprintf('firefly.search.operators.%s.needs_context', $ruleTrigger->trigger_type)) ?? true;
if (false === $needsContext) {
@@ -241,6 +250,7 @@ class SearchRuleEngine implements RuleEngineInterface
}
}
// add local operators:
foreach ($this->operators as $operator) {
Log::debug(sprintf('SearchRuleEngine:: add local added operator: %s:"%s"', $operator['type'], $operator['value']));
@@ -373,7 +383,7 @@ class SearchRuleEngine implements RuleEngineInterface
{
Log::debug(sprintf('SearchRuleEngine:: Will now execute actions on transaction journal #%d', $transaction['transaction_journal_id']));
/** @var RuleAction $ruleAction */
foreach ($rule->ruleActions()->where('active', 1)->get() as $ruleAction) {
foreach ($rule->ruleActions()->where('active', true)->get() as $ruleAction) {
$break = $this->processRuleAction($ruleAction, $transaction);
if (true === $break) {
break;
@@ -448,8 +458,15 @@ class SearchRuleEngine implements RuleEngineInterface
// start a search query for individual each trigger:
$total = new Collection;
$count = 0;
/** @var Collection $triggers */
$triggers = $rule->ruleTriggers;
/** @var RuleTrigger $ruleTrigger */
foreach ($rule->ruleTriggers()->where('active', 1)->get() as $ruleTrigger) {
foreach ($triggers as $ruleTrigger) {
if (false === $ruleTrigger->active) {
continue;
}
if ('user_action' === $ruleTrigger->trigger_type) {
Log::debug('Skip trigger type.');
continue;