Merge branch 'develop'

* develop:
  Fixed some rare bugs.
  Extra clear button to reapply rules #307
  Fix trim when null [skip ci]
  Fixed a bug where incoming transactions would not be properly filtered in several reports.
  Removed for #334
  Fix #337 [skip ci]
  Fix #335
  Remove account extra text #336 [skip ci]
  Fixes bug #338
  Refer to correct page [skip ci]
  Catch unset row.
This commit is contained in:
James Cole 2016-10-04 20:08:35 +02:00
commit 724d25f2c2
16 changed files with 89 additions and 129 deletions

View File

@ -221,6 +221,33 @@ class AccountCrud implements AccountCrudInterface
return $result;
}
/**
* @param array $types
*
* @return Collection
*/
public function getActiveAccountsByType(array $types): Collection
{
/** @var Collection $result */
$query = $this->user->accounts()->with(
['accountmeta' => function (HasMany $query) {
$query->where('name', 'accountRole');
}]
);
if (count($types) > 0) {
$query->accountTypeIn($types);
}
$query->where('active', 1);
$result = $query->get(['accounts.*']);
$result = $result->sortBy(
function (Account $account) {
return strtolower($account->name);
}
);
return $result;
}
/**
* @param array $data
*

View File

@ -75,6 +75,13 @@ interface AccountCrudInterface
*/
public function getAccountsByType(array $types): Collection;
/**
* @param array $types
*
* @return Collection
*/
public function getActiveAccountsByType(array $types): Collection;
/**
* @param array $data
*

View File

@ -295,14 +295,14 @@ class AccountController extends Controller
public function store(AccountFormRequest $request, AccountCrudInterface $crud)
{
$accountData = [
'name' => $request->input('name'),
'name' => trim($request->input('name')),
'accountType' => $request->input('what'),
'virtualBalance' => round($request->input('virtualBalance'), 2),
'virtualBalanceCurrency' => intval($request->input('amount_currency_id_virtualBalance')),
'active' => true,
'user' => auth()->user()->id,
'iban' => $request->input('iban'),
'accountNumber' => $request->input('accountNumber'),
'iban' => trim($request->input('iban')),
'accountNumber' => trim($request->input('accountNumber')),
'accountRole' => $request->input('accountRole'),
'openingBalance' => round($request->input('openingBalance'), 2),
'openingBalanceDate' => new Carbon((string)$request->input('openingBalanceDate')),

View File

@ -1,84 +0,0 @@
<?php
/**
* AuthController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Auth;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\User;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Validator;
/**
* Class AuthController
*
* @package FireflyIII\Http\Controllers\Auth
*/
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
/**
* Where to redirect users after login / registration.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new authentication controller instance.
*
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
parent::__construct();
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
*
* @return User
*/
protected function create(array $data)
{
return User::create(
[
'email' => $data['email'],
'password' => bcrypt($data['password']),
]
);
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
*
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make(
$data, [
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]
);
}
}

View File

@ -263,7 +263,7 @@ class CategoryController extends Controller
public function store(CategoryFormRequest $request, CRI $repository)
{
$categoryData = [
'name' => $request->input('name'),
'name' => trim($request->input('name')),
'user' => auth()->user()->id,
];
$category = $repository->store($categoryData);

View File

@ -13,6 +13,7 @@ namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
use ExpandedForm;
use FireflyIII\Crud\Account\AccountCrudInterface;
use FireflyIII\Events\TransactionJournalStored;
use FireflyIII\Events\TransactionJournalUpdated;
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
@ -59,12 +60,12 @@ class TransactionController extends Controller
*/
public function create(string $what = TransactionType::DEPOSIT)
{
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
$crud = app(AccountCrudInterface::class);
$budgetRepository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$piggyRepository = app('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface');
$what = strtolower($what);
$uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
$assetAccounts = ExpandedForm::makeSelectList($crud->getAccountsByType(['Default account', 'Asset account']));
$assetAccounts = ExpandedForm::makeSelectList($crud->getActiveAccountsByType(['Default account', 'Asset account']));
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
$piggyBanks = $piggyRepository->getPiggyBanksWithAmount();
$piggies = ExpandedForm::makeSelectListWithEmpty($piggyBanks);

View File

@ -43,11 +43,11 @@ class JournalFormRequest extends Request
return [
'what' => $this->get('what'),
'description' => $this->get('description'),
'description' => trim($this->get('description')),
'source_account_id' => intval($this->get('source_account_id')),
'source_account_name' => $this->getFieldOrEmptyString('source_account_name'),
'source_account_name' => trim($this->getFieldOrEmptyString('source_account_name')),
'destination_account_id' => intval($this->get('destination_account_id')),
'destination_account_name' => $this->getFieldOrEmptyString('destination_account_name'),
'destination_account_name' => trim($this->getFieldOrEmptyString('destination_account_name')),
'amount' => round($this->get('amount'), 2),
'user' => auth()->user()->id,
'amount_currency_id_amount' => intval($this->get('amount_currency_id_amount')),
@ -56,7 +56,7 @@ class JournalFormRequest extends Request
'book_date' => $this->getDateOrNull('book_date'),
'process_date' => $this->getDateOrNull('process_date'),
'budget_id' => intval($this->get('budget_id')),
'category' => $this->getFieldOrEmptyString('category'),
'category' => trim($this->getFieldOrEmptyString('category')),
'tags' => explode(',', $tags),
'piggy_bank_id' => intval($this->get('piggy_bank_id')),
@ -64,8 +64,8 @@ class JournalFormRequest extends Request
'due_date' => $this->getDateOrNull('due_date'),
'payment_date' => $this->getDateOrNull('payment_date'),
'invoice_date' => $this->getDateOrNull('invoice_date'),
'internal_reference' => $this->get('internal_reference'),
'notes' => $this->get('notes'),
'internal_reference' => trim(strval($this->get('internal_reference'))),
'notes' => trim(strval($this->get('notes'))),
];
}

View File

@ -181,13 +181,13 @@ class ImportValidator
Log::debug(sprintf('No account named %s of type %s, create new account.', $account->name, $type));
$result = $repository->store(
[
'user' => $this->user->id,
'accountType' => config('firefly.shortNamesByFullName.' . $type),
'name' => $account->name,
'user' => $this->user->id,
'accountType' => config('firefly.shortNamesByFullName.' . $type),
'name' => $account->name,
'virtualBalance' => 0,
'active' => true,
'iban' => null,
'openingBalance' => 0,
'active' => true,
'iban' => null,
'openingBalance' => 0,
]
);
}
@ -262,6 +262,7 @@ class ImportValidator
$entry->valid = false;
Log::warning('Cannot import entry. Asset account is NULL and import account is also NULL.');
return $entry;
}
Log::debug('Asset account is OK.', ['id' => $entry->fields['asset-account']->id, 'name' => $entry->fields['asset-account']->name]);

View File

@ -50,9 +50,15 @@ class AbnAmroDescription implements SpecificInterface
public function run(array $row): array
{
$this->row = $row;
if (!isset($row[7])) {
return $row;
}
// Try to parse the description in known formats.
$parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription();
// If the description could not be parsed, specify an unknown opposing
// account, as an opposing account is required
if (!$parsed) {

View File

@ -377,7 +377,10 @@ class AccountRepository implements AccountRepositoryInterface
* The destination of a transfer must be one of the $accounts in order to
* be included. Otherwise, it would not be income.
*/
if (in_array($journal->destination_account_id, $accountIds)) {
$destinations = TransactionJournal::destinationAccountList($journal)->pluck('id')->toArray();
if (count(array_intersect($destinations, $accountIds)) > 0) {
// at least one of $target is in $haystack
return true;
}

View File

@ -189,22 +189,22 @@ class BillRepository implements BillRepositoryInterface
'bills.active',
'bills.name_encrypted',
'bills.match_encrypted'];
$ids = $accounts->pluck('id')->toArray();
$set = $this->user->bills()
->leftJoin(
'transaction_journals', function (JoinClause $join) {
$join->on('transaction_journals.bill_id', '=', 'bills.id')->whereNull('transaction_journals.deleted_at');
}
)
->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '<', 0);
}
)
->whereIn('transactions.account_id', $ids)
->whereNull('transaction_journals.deleted_at')
->groupBy($fields)
->get($fields);
$ids = $accounts->pluck('id')->toArray();
$set = $this->user->bills()
->leftJoin(
'transaction_journals', function (JoinClause $join) {
$join->on('transaction_journals.bill_id', '=', 'bills.id')->whereNull('transaction_journals.deleted_at');
}
)
->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '<', 0);
}
)
->whereIn('transactions.account_id', $ids)
->whereNull('transaction_journals.deleted_at')
->groupBy($fields)
->get($fields);
$set = $set->sortBy(
function (Bill $bill) {

View File

@ -143,7 +143,7 @@ class TagRepository implements TagRepositoryInterface
->transactionJournals()
->sortCorrectly()
->expanded()
->groupBy(['tag_transaction_journal.tag_id'])
->groupBy(['tag_transaction_journal.tag_id','tag_transaction_journal.transaction_journal_id'])
->get(TransactionJournal::queryFields());
return $journals;

View File

@ -48,7 +48,7 @@ class SetBudget implements ActionInterface
public function act(TransactionJournal $journal): bool
{
/** @var BudgetRepositoryInterface $repository */
$repository = app(BudgetRepositoryInterface::class);
$repository = app(BudgetRepositoryInterface::class, [$journal->user]);
$search = $this->action->action_value;
$budgets = $repository->getActiveBudgets();
$budget = $budgets->filter(

View File

@ -17,6 +17,6 @@ return [
'Please follow the instructions on the following page: https://github.com/JC5/firefly-iii/wiki/Upgrade-to-3.7.0',
'3.8' => 'This version of Firefly III requires PHP 7.0.',
'3.10' => 'Please find the full upgrade instructions here: https://github.com/JC5/firefly-iii/wiki/Upgrade-to-3.10',
'4.0' => 'Please find the full upgrade instructions here: https://github.com/JC5/firefly-iii/wiki/Upgrade-to-3.10',
'4.0' => 'Please find the full upgrade instructions here: https://github.com/JC5/firefly-iii/wiki/Upgrade-to-4.0',
],
];

View File

@ -6,13 +6,6 @@
{% block content %}
<div class="row">
<div class="col-lg-6 col-md-8 col-sm-12 col-xs-12">
<p>
{{ ('accountExtraHelp_'~what)|_ }}
</p>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="box" id="account-index-{{ what }}">

View File

@ -104,6 +104,12 @@
class="btn btn-danger"><span
class="fa fa-fw fa-trash"></span></a>
</div>
<br />
<div class="btn-group btn-group-xs">
<a href="{{ route('rules.rule-group.select_transactions',ruleGroup.id) }}" class="btn btn-default"
title=" {{ 'execute_on_existing_transactions_short'|_ }}">
<i class="fa fa-fw fa-check-circle"></i></a>
</div>
</td>
<td>