mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-18 18:44:16 +00:00
Search improvements.
This commit is contained in:
@@ -67,14 +67,10 @@ class SearchController extends Controller
|
|||||||
// parse search terms:
|
// parse search terms:
|
||||||
$searcher->parseQuery($fullQuery);
|
$searcher->parseQuery($fullQuery);
|
||||||
$query = $searcher->getWordsAsString();
|
$query = $searcher->getWordsAsString();
|
||||||
|
$modifiers = $searcher->getModifiers();
|
||||||
|
|
||||||
//also get modifiers to display:
|
|
||||||
|
|
||||||
|
|
||||||
$subTitle = (string)trans('breadcrumbs.search_result', ['query' => $query]);
|
$subTitle = (string)trans('breadcrumbs.search_result', ['query' => $query]);
|
||||||
|
|
||||||
return view('search.index', compact('query', 'fullQuery', 'subTitle'));
|
return view('search.index', compact('query','modifiers', 'fullQuery', 'subTitle'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -92,9 +88,10 @@ class SearchController extends Controller
|
|||||||
$searcher->parseQuery($fullQuery);
|
$searcher->parseQuery($fullQuery);
|
||||||
$searcher->setLimit((int)config('firefly.search_result_limit'));
|
$searcher->setLimit((int)config('firefly.search_result_limit'));
|
||||||
$transactions = $searcher->searchTransactions();
|
$transactions = $searcher->searchTransactions();
|
||||||
|
$searchTime = $searcher->searchTime(); // in seconds
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$html = view('search.search', compact('transactions'))->render();
|
$html = view('search.search', compact('transactions','searchTime'))->render();
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
Log::error(sprintf('Cannot render search.search: %s', $e->getMessage()));
|
Log::error(sprintf('Cannot render search.search: %s', $e->getMessage()));
|
||||||
|
@@ -556,6 +556,25 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
* @param array $types
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function searchAccount(string $query, array $types): Collection
|
||||||
|
{
|
||||||
|
$dbQuery = $this->user->accounts();
|
||||||
|
$search = sprintf('%%%s%%', $query);
|
||||||
|
if (\count($types) > 0) {
|
||||||
|
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||||
|
$dbQuery->whereIn('account_types.type', $types);
|
||||||
|
}
|
||||||
|
$dbQuery->where('name', 'LIKE', $search);
|
||||||
|
|
||||||
|
return $dbQuery->get(['accounts.*']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param User $user
|
* @param User $user
|
||||||
*/
|
*/
|
||||||
|
@@ -36,6 +36,7 @@ use Illuminate\Support\Collection;
|
|||||||
*/
|
*/
|
||||||
interface AccountRepositoryInterface
|
interface AccountRepositoryInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moved here from account CRUD.
|
* Moved here from account CRUD.
|
||||||
*
|
*
|
||||||
@@ -247,6 +248,14 @@ interface AccountRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function oldestJournalDate(Account $account): ?Carbon;
|
public function oldestJournalDate(Account $account): ?Carbon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
* @param array $types
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function searchAccount(string $query, array $types): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param User $user
|
* @param User $user
|
||||||
*/
|
*/
|
||||||
|
@@ -623,6 +623,18 @@ class BillRepository implements BillRepositoryInterface
|
|||||||
return $start;
|
return $start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function searchBill(string $query): Collection
|
||||||
|
{
|
||||||
|
$query = sprintf('%%%s%%', $query);
|
||||||
|
|
||||||
|
return $this->user->bills()->where('name', 'LIKE', $query)->get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param User $user
|
* @param User $user
|
||||||
*/
|
*/
|
||||||
|
@@ -33,7 +33,6 @@ use Illuminate\Support\Collection;
|
|||||||
*/
|
*/
|
||||||
interface BillRepositoryInterface
|
interface BillRepositoryInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Bill $bill
|
* @param Bill $bill
|
||||||
*
|
*
|
||||||
@@ -236,6 +235,13 @@ interface BillRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function nextExpectedMatch(Bill $bill, Carbon $date): Carbon;
|
public function nextExpectedMatch(Bill $bill, Carbon $date): Carbon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function searchBill(string $query): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param User $user
|
* @param User $user
|
||||||
*/
|
*/
|
||||||
|
@@ -635,6 +635,20 @@ class BudgetRepository implements BudgetRepositoryInterface
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function searchBudget(string $query): Collection
|
||||||
|
{
|
||||||
|
$query = sprintf('%%%s%%', $query);
|
||||||
|
|
||||||
|
return $this->user->budgets()->where('name', 'LIKE', $query)->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TransactionCurrency $currency
|
* @param TransactionCurrency $currency
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
@@ -662,8 +676,6 @@ class BudgetRepository implements BudgetRepositoryInterface
|
|||||||
return $availableBudget;
|
return $availableBudget;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Budget $budget
|
* @param Budget $budget
|
||||||
* @param int $order
|
* @param int $order
|
||||||
@@ -903,6 +915,8 @@ class BudgetRepository implements BudgetRepositoryInterface
|
|||||||
return $limit;
|
return $limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Budget $budget
|
* @param Budget $budget
|
||||||
* @param array $data
|
* @param array $data
|
||||||
@@ -922,8 +936,6 @@ class BudgetRepository implements BudgetRepositoryInterface
|
|||||||
return $budget;
|
return $budget;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param AvailableBudget $availableBudget
|
* @param AvailableBudget $availableBudget
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
@@ -169,8 +169,6 @@ interface BudgetRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getBudgets(): Collection;
|
public function getBudgets(): Collection;
|
||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all budgets with these ID's.
|
* Get all budgets with these ID's.
|
||||||
*
|
*
|
||||||
@@ -180,6 +178,8 @@ interface BudgetRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getByIds(array $budgetIds): Collection;
|
public function getByIds(array $budgetIds): Collection;
|
||||||
|
|
||||||
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
@@ -194,6 +194,13 @@ interface BudgetRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array;
|
public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function searchBudget(string $query): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TransactionCurrency $currency
|
* @param TransactionCurrency $currency
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
|
@@ -531,6 +531,18 @@ class CategoryRepository implements CategoryRepositoryInterface
|
|||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function searchCategory(string $query): Collection
|
||||||
|
{
|
||||||
|
$query = sprintf('%%%s%%', $query);
|
||||||
|
|
||||||
|
return $this->user->categories()->where('name', 'LIKE', $query)->get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param User $user
|
* @param User $user
|
||||||
*/
|
*/
|
||||||
|
@@ -40,7 +40,6 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function destroy(Category $category): bool;
|
public function destroy(Category $category): bool;
|
||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $categories
|
* @param Collection $categories
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
@@ -52,6 +51,7 @@ interface CategoryRepositoryInterface
|
|||||||
public function earnedInPeriod(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): string;
|
public function earnedInPeriod(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): string;
|
||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $categories
|
* @param Collection $categories
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
@@ -62,6 +62,8 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function earnedInPeriodCollection(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): Collection;
|
public function earnedInPeriodCollection(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): Collection;
|
||||||
|
|
||||||
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A very cryptic method name that means:
|
* A very cryptic method name that means:
|
||||||
*
|
*
|
||||||
@@ -119,8 +121,6 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getByIds(array $categoryIds): Collection;
|
public function getByIds(array $categoryIds): Collection;
|
||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all the categories belonging to a user.
|
* Returns a list of all the categories belonging to a user.
|
||||||
*
|
*
|
||||||
@@ -128,6 +128,8 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getCategories(): Collection;
|
public function getCategories(): Collection;
|
||||||
|
|
||||||
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return most recent transaction(journal) date or null when never used before.
|
* Return most recent transaction(journal) date or null when never used before.
|
||||||
*
|
*
|
||||||
@@ -138,8 +140,6 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function lastUseDate(Category $category, Collection $accounts): ?Carbon;
|
public function lastUseDate(Category $category, Collection $accounts): ?Carbon;
|
||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $categories
|
* @param Collection $categories
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
@@ -150,6 +150,8 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function periodExpenses(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
public function periodExpenses(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||||
|
|
||||||
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
@@ -169,8 +171,6 @@ interface CategoryRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function periodIncome(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
public function periodIncome(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): array;
|
||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
@@ -182,6 +182,15 @@ interface CategoryRepositoryInterface
|
|||||||
|
|
||||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function searchCategory(string $query): Collection;
|
||||||
|
|
||||||
|
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param User $user
|
* @param User $user
|
||||||
*/
|
*/
|
||||||
|
@@ -26,6 +26,11 @@ use Carbon\Carbon;
|
|||||||
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
|
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
|
||||||
use FireflyIII\Helpers\Filter\DoubleTransactionFilter;
|
use FireflyIII\Helpers\Filter\DoubleTransactionFilter;
|
||||||
use FireflyIII\Helpers\Filter\InternalTransferFilter;
|
use FireflyIII\Helpers\Filter\InternalTransferFilter;
|
||||||
|
use FireflyIII\Models\AccountType;
|
||||||
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
|
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||||
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
|
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
@@ -36,12 +41,22 @@ use Log;
|
|||||||
*/
|
*/
|
||||||
class Search implements SearchInterface
|
class Search implements SearchInterface
|
||||||
{
|
{
|
||||||
|
/** @var AccountRepositoryInterface */
|
||||||
|
private $accountRepository;
|
||||||
|
/** @var BillRepositoryInterface */
|
||||||
|
private $billRepository;
|
||||||
|
/** @var BudgetRepositoryInterface */
|
||||||
|
private $budgetRepository;
|
||||||
|
/** @var CategoryRepositoryInterface */
|
||||||
|
private $categoryRepository;
|
||||||
/** @var int */
|
/** @var int */
|
||||||
private $limit = 100;
|
private $limit = 100;
|
||||||
/** @var Collection */
|
/** @var Collection */
|
||||||
private $modifiers;
|
private $modifiers;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $originalQuery = '';
|
private $originalQuery = '';
|
||||||
|
/** @var float */
|
||||||
|
private $startTime;
|
||||||
/** @var User */
|
/** @var User */
|
||||||
private $user;
|
private $user;
|
||||||
/** @var array */
|
/** @var array */
|
||||||
@@ -54,8 +69,13 @@ class Search implements SearchInterface
|
|||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->modifiers = new Collection;
|
$this->modifiers = new Collection;
|
||||||
$this->validModifiers = (array)config('firefly.search_modifiers');
|
$this->validModifiers = (array)config('firefly.search_modifiers');
|
||||||
|
$this->startTime = microtime(true);
|
||||||
|
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||||
|
$this->categoryRepository = app(CategoryRepositoryInterface::class);
|
||||||
|
$this->budgetRepository = app(BudgetRepositoryInterface::class);
|
||||||
|
$this->billRepository = app(BillRepositoryInterface::class);
|
||||||
|
|
||||||
if ('testing' === config('app.env')) {
|
if ('testing' === config('app.env')) {
|
||||||
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', \get_class($this)));
|
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', \get_class($this)));
|
||||||
@@ -112,6 +132,14 @@ class Search implements SearchInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function searchTime(): float
|
||||||
|
{
|
||||||
|
return microtime(true) - $this->startTime;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return LengthAwarePaginator
|
* @return LengthAwarePaginator
|
||||||
*/
|
*/
|
||||||
@@ -128,8 +156,6 @@ class Search implements SearchInterface
|
|||||||
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
|
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$collector->setSearchWords($this->words);
|
$collector->setSearchWords($this->words);
|
||||||
$collector->removeFilter(InternalTransferFilter::class);
|
$collector->removeFilter(InternalTransferFilter::class);
|
||||||
$collector->addFilter(DoubleTransactionFilter::class);
|
$collector->addFilter(DoubleTransactionFilter::class);
|
||||||
@@ -155,6 +181,10 @@ class Search implements SearchInterface
|
|||||||
public function setUser(User $user): void
|
public function setUser(User $user): void
|
||||||
{
|
{
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
$this->accountRepository->setUser($user);
|
||||||
|
$this->billRepository->setUser($user);
|
||||||
|
$this->categoryRepository->setUser($user);
|
||||||
|
$this->budgetRepository->setUser($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -167,8 +197,6 @@ class Search implements SearchInterface
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* TODO:
|
||||||
* 'source', 'destination',
|
|
||||||
* 'category','budget',
|
|
||||||
* 'bill',
|
* 'bill',
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -176,6 +204,40 @@ class Search implements SearchInterface
|
|||||||
switch ($modifier['type']) {
|
switch ($modifier['type']) {
|
||||||
default:
|
default:
|
||||||
die(sprintf('unsupported modifier: "%s"', $modifier['type']));
|
die(sprintf('unsupported modifier: "%s"', $modifier['type']));
|
||||||
|
case 'source':
|
||||||
|
// source can only be asset, liability or revenue account:
|
||||||
|
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::REVENUE];
|
||||||
|
$accounts = $this->accountRepository->searchAccount($modifier['value'], $searchTypes);
|
||||||
|
if ($accounts->count() > 0) {
|
||||||
|
$collector->setAccounts($accounts);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'destination':
|
||||||
|
// source can only be asset, liability or expense account:
|
||||||
|
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE];
|
||||||
|
$accounts = $this->accountRepository->searchAccount($modifier['value'], $searchTypes);
|
||||||
|
if ($accounts->count() > 0) {
|
||||||
|
$collector->setOpposingAccounts($accounts);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'category':
|
||||||
|
$result = $this->categoryRepository->searchCategory($modifier['value']);
|
||||||
|
if ($result->count() > 0) {
|
||||||
|
$collector->setCategories($result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'bill':
|
||||||
|
$result = $this->billRepository->searchBill($modifier['value']);
|
||||||
|
if ($result->count() > 0) {
|
||||||
|
$collector->setBills($result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'budget':
|
||||||
|
$result = $this->budgetRepository->searchBudget($modifier['value']);
|
||||||
|
if ($result->count() > 0) {
|
||||||
|
$collector->setBudgets($result);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'amount_is':
|
case 'amount_is':
|
||||||
case 'amount':
|
case 'amount':
|
||||||
$amount = app('steam')->positive((string)$modifier['value']);
|
$amount = app('steam')->positive((string)$modifier['value']);
|
||||||
|
@@ -31,6 +31,11 @@ use Illuminate\Support\Collection;
|
|||||||
*/
|
*/
|
||||||
interface SearchInterface
|
interface SearchInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function getModifiers(): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -46,6 +51,11 @@ interface SearchInterface
|
|||||||
*/
|
*/
|
||||||
public function parseQuery(string $query);
|
public function parseQuery(string $query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function searchTime(): float;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return LengthAwarePaginator
|
* @return LengthAwarePaginator
|
||||||
*/
|
*/
|
||||||
|
2
public/v1/js/ff/search/index.js
vendored
2
public/v1/js/ff/search/index.js
vendored
@@ -39,8 +39,6 @@ function searchFailure() {
|
|||||||
|
|
||||||
function presentSearchResults(data) {
|
function presentSearchResults(data) {
|
||||||
$('.search_ongoing').hide();
|
$('.search_ongoing').hide();
|
||||||
$('p.search_count').show();
|
|
||||||
$('span.search_count').text(data.count);
|
|
||||||
$('.search_box').find('.overlay').remove();
|
$('.search_box').find('.overlay').remove();
|
||||||
$('.search_results').html(data.html).show();
|
$('.search_results').html(data.html).show();
|
||||||
|
|
||||||
|
@@ -217,7 +217,27 @@ return [
|
|||||||
// search
|
// search
|
||||||
'search' => 'Search',
|
'search' => 'Search',
|
||||||
'search_query' => 'Query',
|
'search_query' => 'Query',
|
||||||
'search_found_transactions' => 'Number of transactions found:',
|
'search_found_transactions' => 'Firefly III found :count transaction(s) in :time seconds.',
|
||||||
|
'search_for_query' => 'Firefly III is searching for transactions with all of these words in them: <span class="text-info">:query</span>',
|
||||||
|
'search_modifier_amount_is' => 'Amount is exactly :value',
|
||||||
|
'search_modifier_amount' => 'Amount is exactly :value',
|
||||||
|
'search_modifier_amount_max' => 'Amount is at most :value',
|
||||||
|
'search_modifier_amount_min' => 'Amount is at least :value',
|
||||||
|
'search_modifier_amount_less' => 'Amount is less than :value',
|
||||||
|
'search_modifier_amount_more' => 'Amount is more than :value',
|
||||||
|
'search_modifier_source' => 'Source account is :value',
|
||||||
|
'search_modifier_destination' => 'Destination account is :value',
|
||||||
|
'search_modifier_category' => 'Category is :value',
|
||||||
|
'search_modifier_budget' => 'Budget is :value',
|
||||||
|
'search_modifier_bill' => 'Bill is :value',
|
||||||
|
'search_modifier_type' => 'Transaction type is :value',
|
||||||
|
'search_modifier_date' => 'Transaction date is :value',
|
||||||
|
'search_modifier_date_before' => 'Transaction date is before :value',
|
||||||
|
'search_modifier_date_after' => 'Transaction date is after :value',
|
||||||
|
'search_modifier_on' => 'Transaction date is :value',
|
||||||
|
'search_modifier_before' => 'Transaction date is before :value',
|
||||||
|
'search_modifier_after' => 'Transaction date is after :value',
|
||||||
|
'modifiers_applies_are' => 'The following modifiers are applied to the search as well:',
|
||||||
'general_search_error' => 'An error occured while searching. Please check the log files for more information.',
|
'general_search_error' => 'An error occured while searching. Please check the log files for more information.',
|
||||||
'search_box' => 'Search',
|
'search_box' => 'Search',
|
||||||
'search_box_intro' => 'Welcome to the search function of Firefly III. Enter your search query in the box. Make sure you check out the help file because the search is pretty advanced.',
|
'search_box_intro' => 'Welcome to the search function of Firefly III. Enter your search query in the box. Make sure you check out the help file because the search is pretty advanced.',
|
||||||
|
@@ -20,7 +20,8 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="query" class="col-sm-1 control-label">{{ 'search_query'|_ }}</label>
|
<label for="query" class="col-sm-1 control-label">{{ 'search_query'|_ }}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input autocomplete="off" type="text" name="q" id="query" value="{{ fullQuery }}" class="form-control" placeholder="{{ fullQuery }}">
|
<input autocomplete="off" type="text" name="q" id="query" value="{{ fullQuery }}" class="form-control"
|
||||||
|
placeholder="{{ fullQuery }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -29,6 +30,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<p>
|
||||||
|
{{ trans('firefly.search_for_query', {query: query})|raw}}
|
||||||
|
</p>
|
||||||
|
{% if modifiers|length > 0 %}
|
||||||
|
<p>{{ trans('firefly.modifiers_applies_are') }}</p>
|
||||||
|
<ul>
|
||||||
|
{% for modifier in modifiers %}
|
||||||
|
<li>{{ trans('firefly.search_modifier_'~modifier.type, {value: modifier.value}) }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -44,11 +56,7 @@
|
|||||||
<p class="search_ongoing text-center" style="margin-top:70px;">
|
<p class="search_ongoing text-center" style="margin-top:70px;">
|
||||||
{{ 'search_searching'|_ }}
|
{{ 'search_searching'|_ }}
|
||||||
</p>
|
</p>
|
||||||
<p class="search_count" style="display: none;">
|
<div class="search_results" style="display: none;"></div>
|
||||||
{{ 'search_found_transactions'|_ }} <span class="search_count"></span>
|
|
||||||
</p>
|
|
||||||
<div class="search_results" style="display: none;">
|
|
||||||
</div>
|
|
||||||
{# loading indicator #}
|
{# loading indicator #}
|
||||||
<div class="overlay">
|
<div class="overlay">
|
||||||
<i class="fa fa-refresh fa-spin"></i>
|
<i class="fa fa-refresh fa-spin"></i>
|
||||||
|
@@ -1,3 +1,8 @@
|
|||||||
|
<p>
|
||||||
|
<p class="search_count">
|
||||||
|
{{ trans('firefly.search_found_transactions', {count: transactions.count, time: searchTime}) }}
|
||||||
|
</p>
|
||||||
|
|
||||||
<table class="table table-hover table-condensed">
|
<table class="table table-hover table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="ignore">
|
<tr class="ignore">
|
||||||
|
@@ -24,6 +24,7 @@ namespace Tests\Feature\Controllers;
|
|||||||
|
|
||||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||||
use FireflyIII\Support\Search\SearchInterface;
|
use FireflyIII\Support\Search\SearchInterface;
|
||||||
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Log;
|
use Log;
|
||||||
use Mockery;
|
use Mockery;
|
||||||
@@ -61,6 +62,7 @@ class SearchControllerTest extends TestCase
|
|||||||
|
|
||||||
$search->shouldReceive('parseQuery')->once();
|
$search->shouldReceive('parseQuery')->once();
|
||||||
$search->shouldReceive('getWordsAsString')->once()->andReturn('test');
|
$search->shouldReceive('getWordsAsString')->once()->andReturn('test');
|
||||||
|
$search->shouldReceive('getModifiers')->once()->andReturn(new Collection);
|
||||||
$this->be($this->user());
|
$this->be($this->user());
|
||||||
$response = $this->get(route('search.index') . '?q=test');
|
$response = $this->get(route('search.index') . '?q=test');
|
||||||
$response->assertStatus(200);
|
$response->assertStatus(200);
|
||||||
@@ -78,7 +80,8 @@ class SearchControllerTest extends TestCase
|
|||||||
|
|
||||||
$search->shouldReceive('parseQuery')->once();
|
$search->shouldReceive('parseQuery')->once();
|
||||||
$search->shouldReceive('setLimit')->withArgs([50])->once();
|
$search->shouldReceive('setLimit')->withArgs([50])->once();
|
||||||
$search->shouldReceive('searchTransactions')->once()->andReturn(new Collection);
|
$search->shouldReceive('searchTransactions')->once()->andReturn(new LengthAwarePaginator([],0,10));
|
||||||
|
$search->shouldReceive('searchTime')->once()->andReturn(0.2);
|
||||||
|
|
||||||
$this->be($this->user());
|
$this->be($this->user());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user