This commit is contained in:
James Cole
2019-09-03 17:06:30 +02:00
parent a8b521bdd5
commit ddabf6a246
5 changed files with 127 additions and 96 deletions

View File

@@ -68,10 +68,7 @@ class SearchController extends Controller
$modifiers = $searcher->getModifiers(); $modifiers = $searcher->getModifiers();
$subTitle = (string)trans('breadcrumbs.search_result', ['query' => $query]); $subTitle = (string)trans('breadcrumbs.search_result', ['query' => $query]);
return view( return view('search.index', compact('query', 'modifiers', 'fullQuery', 'subTitle'));
'search.index',
compact('query', 'modifiers', 'fullQuery', 'subTitle')
);
} }
/** /**

View File

@@ -74,7 +74,7 @@ class TagRepository implements TagRepositoryInterface
} }
/** /**
* @param Tag $tag * @param Tag $tag
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* *
@@ -92,7 +92,7 @@ class TagRepository implements TagRepositoryInterface
} }
/** /**
* @param Tag $tag * @param Tag $tag
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* *
@@ -156,7 +156,7 @@ class TagRepository implements TagRepositoryInterface
} }
/** /**
* @param Tag $tag * @param Tag $tag
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* *
@@ -206,6 +206,20 @@ class TagRepository implements TagRepositoryInterface
return $this->user->tags()->whereNotNull('date')->orderBy('date', 'ASC')->first(); return $this->user->tags()->whereNotNull('date')->orderBy('date', 'ASC')->first();
} }
/**
* Find one or more tags based on the query.
*
* @param string $query
*
* @return Collection
*/
public function searchTag(string $query): Collection
{
$search = sprintf('%%%s%%', $query);
return $this->user->tags()->where('tag', 'LIKE', $search)->get(['tags.*']);
}
/** /**
* Search the users tags. * Search the users tags.
* *
@@ -234,7 +248,7 @@ class TagRepository implements TagRepositoryInterface
} }
/** /**
* @param Tag $tag * @param Tag $tag
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* *
@@ -266,7 +280,7 @@ class TagRepository implements TagRepositoryInterface
} }
/** /**
* @param Tag $tag * @param Tag $tag
* @param Carbon|null $start * @param Carbon|null $start
* @param Carbon|null $end * @param Carbon|null $end
* *
@@ -335,7 +349,7 @@ class TagRepository implements TagRepositoryInterface
foreach ($tags as $tag) { foreach ($tags as $tag) {
$amount = (string)$tag->amount_sum; $amount = (string)$tag->amount_sum;
$amount = '' === $amount ? '0' : $amount; $amount = '' === $amount ? '0' : $amount;
$amountMin = bcsub($amount, $min); $amountMin = bcsub($amount, $min);
$pointsForTag = bcmul($amountMin, $pointsPerCoin); $pointsForTag = bcmul($amountMin, $pointsPerCoin);
$fontSize = bcadd($minimumFont, $pointsForTag); $fontSize = bcadd($minimumFont, $pointsForTag);
Log::debug(sprintf('Tag "%s": Amount is %s, so points is %s', $tag->tag, $amount, $fontSize)); Log::debug(sprintf('Tag "%s": Amount is %s, so points is %s', $tag->tag, $amount, $fontSize));
@@ -352,37 +366,39 @@ class TagRepository implements TagRepositoryInterface
} }
/** /**
* @param int|null $year * @param Tag $tag
* @param Carbon $start
* @param Carbon $end
* *
* @return Collection * @return array
*/ */
private function getTagsInYear(?int $year): Collection public function transferredInPeriod(Tag $tag, Carbon $start, Carbon $end): array
{ {
// get all tags in the year (if present): /** @var GroupCollectorInterface $collector */
$tagQuery = $this->user->tags() $collector = app(GroupCollectorInterface::class);
->leftJoin('tag_transaction_journal', 'tag_transaction_journal.tag_id', '=', 'tags.id') $collector->setUser($this->user);
->leftJoin('transaction_journals', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') $collector->setRange($start, $end)->setTypes([TransactionType::TRANSFER])->setTag($tag);
->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where(
function (Builder $query) {
$query->where('transactions.amount', '>', 0);
$query->orWhereNull('transactions.amount');
}
)
->groupBy(['tags.id', 'tags.tag']);
// add date range (or not): return $collector->getExtractedJournals();
if (null === $year) { }
Log::debug('Get tags without a date.');
$tagQuery->whereNull('tags.date');
}
if (null !== $year) {
Log::debug(sprintf('Get tags with year %s.', $year));
$tagQuery->where('tags.date', '>=', $year . '-01-01 00:00:00')->where('tags.date', '<=', $year . '-12-31 23:59:59');
}
return $tagQuery->get(['tags.id', 'tags.tag', DB::raw('SUM(transactions.amount) as amount_sum')]); /**
* @param Tag $tag
* @param array $data
*
* @return Tag
*/
public function update(Tag $tag, array $data): Tag
{
$tag->tag = $data['tag'];
$tag->date = $data['date'];
$tag->description = $data['description'];
$tag->latitude = $data['latitude'];
$tag->longitude = $data['longitude'];
$tag->zoomLevel = $data['zoom_level'];
$tag->save();
return $tag;
} }
/** /**
@@ -436,38 +452,36 @@ class TagRepository implements TagRepositoryInterface
} }
/** /**
* @param Tag $tag * @param int|null $year
* @param Carbon $start
* @param Carbon $end
* *
* @return array * @return Collection
*/ */
public function transferredInPeriod(Tag $tag, Carbon $start, Carbon $end): array private function getTagsInYear(?int $year): Collection
{ {
/** @var GroupCollectorInterface $collector */ // get all tags in the year (if present):
$collector = app(GroupCollectorInterface::class); $tagQuery = $this->user->tags()
$collector->setUser($this->user); ->leftJoin('tag_transaction_journal', 'tag_transaction_journal.tag_id', '=', 'tags.id')
$collector->setRange($start, $end)->setTypes([TransactionType::TRANSFER])->setTag($tag); ->leftJoin('transaction_journals', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where(
function (Builder $query) {
$query->where('transactions.amount', '>', 0);
$query->orWhereNull('transactions.amount');
}
)
->groupBy(['tags.id', 'tags.tag']);
return $collector->getExtractedJournals(); // add date range (or not):
} if (null === $year) {
Log::debug('Get tags without a date.');
$tagQuery->whereNull('tags.date');
}
if (null !== $year) {
Log::debug(sprintf('Get tags with year %s.', $year));
$tagQuery->where('tags.date', '>=', $year . '-01-01 00:00:00')->where('tags.date', '<=', $year . '-12-31 23:59:59');
}
/** return $tagQuery->get(['tags.id', 'tags.tag', DB::raw('SUM(transactions.amount) as amount_sum')]);
* @param Tag $tag
* @param array $data
*
* @return Tag
*/
public function update(Tag $tag, array $data): Tag
{
$tag->tag = $data['tag'];
$tag->date = $data['date'];
$tag->description = $data['description'];
$tag->latitude = $data['latitude'];
$tag->longitude = $data['longitude'];
$tag->zoomLevel = $data['zoom_level'];
$tag->save();
return $tag;
} }
} }

View File

@@ -71,6 +71,14 @@ interface TagRepositoryInterface
*/ */
public function findByTag(string $tag): ?Tag; public function findByTag(string $tag): ?Tag;
/**
* Find one or more tags based on the query.
* @param string $query
*
* @return Collection
*/
public function searchTag(string $query): Collection;
/** /**
* @param int $tagId * @param int $tagId
* *

View File

@@ -29,6 +29,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -55,6 +56,8 @@ class Search implements SearchInterface
private $originalQuery = ''; private $originalQuery = '';
/** @var float */ /** @var float */
private $startTime; private $startTime;
/** @var TagRepositoryInterface */
private $tagRepository;
/** @var User */ /** @var User */
private $user; private $user;
/** @var array */ /** @var array */
@@ -74,6 +77,7 @@ class Search implements SearchInterface
$this->categoryRepository = app(CategoryRepositoryInterface::class); $this->categoryRepository = app(CategoryRepositoryInterface::class);
$this->budgetRepository = app(BudgetRepositoryInterface::class); $this->budgetRepository = app(BudgetRepositoryInterface::class);
$this->billRepository = app(BillRepositoryInterface::class); $this->billRepository = app(BillRepositoryInterface::class);
$this->tagRepository = app(TagRepositoryInterface::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)));
@@ -130,22 +134,6 @@ class Search implements SearchInterface
} }
} }
/**
* @param string $string
*/
private function extractModifier(string $string): void
{
$parts = explode(':', $string);
if (2 === count($parts) && '' !== trim((string)$parts[1]) && '' !== trim((string)$parts[0])) {
$type = trim((string)$parts[0]);
$value = trim((string)$parts[1]);
if (in_array($type, $this->validModifiers, true)) {
// filter for valid type
$this->modifiers->push(['type' => $type, 'value' => $value]);
}
}
}
/** /**
* @return float * @return float
*/ */
@@ -177,6 +165,26 @@ class Search implements SearchInterface
} }
/**
* @param int $limit
*/
public function setLimit(int $limit): void
{
$this->limit = $limit;
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
$this->accountRepository->setUser($user);
$this->billRepository->setUser($user);
$this->categoryRepository->setUser($user);
$this->budgetRepository->setUser($user);
}
/** /**
* @param GroupCollectorInterface $collector * @param GroupCollectorInterface $collector
* *
@@ -187,7 +195,7 @@ class Search implements SearchInterface
{ {
/* /*
* TODO: * TODO:
* 'bill', * 'bill'?
*/ */
$totalAccounts = new Collection; $totalAccounts = new Collection;
@@ -225,6 +233,13 @@ class Search implements SearchInterface
$collector->setBills($result); $collector->setBills($result);
} }
break; break;
case 'tag':
$result = $this->tagRepository->searchTag($modifier['value']);
if ($result->count() > 0) {
$collector->setTags($result);
}
break;
break;
case 'budget': case 'budget':
$result = $this->budgetRepository->searchBudget($modifier['value']); $result = $this->budgetRepository->searchBudget($modifier['value']);
if ($result->count() > 0) { if ($result->count() > 0) {
@@ -279,22 +294,18 @@ class Search implements SearchInterface
} }
/** /**
* @param int $limit * @param string $string
*/ */
public function setLimit(int $limit): void private function extractModifier(string $string): void
{ {
$this->limit = $limit; $parts = explode(':', $string);
} if (2 === count($parts) && '' !== trim((string)$parts[1]) && '' !== trim((string)$parts[0])) {
$type = trim((string)$parts[0]);
/** $value = trim((string)$parts[1]);
* @param User $user if (in_array($type, $this->validModifiers, true)) {
*/ // filter for valid type
public function setUser(User $user): void $this->modifiers->push(['type' => $type, 'value' => $value]);
{ }
$this->user = $user; }
$this->accountRepository->setUser($user);
$this->billRepository->setUser($user);
$this->categoryRepository->setUser($user);
$this->budgetRepository->setUser($user);
} }
} }

View File

@@ -516,8 +516,9 @@ return [
'default_currency' => 'EUR', 'default_currency' => 'EUR',
'default_language' => 'en_US', 'default_language' => 'en_US',
'search_modifiers' => ['amount_is', 'amount', 'amount_max', 'amount_min', 'amount_less', 'amount_more', 'source', 'destination', 'category', 'search_modifiers' => ['amount_is', 'amount', 'amount_max', 'amount_min', 'amount_less', 'amount_more', 'source', 'destination', 'category',
'budget', 'bill', 'type', 'date', 'date_before', 'date_after', 'on', 'before', 'after','from','to'], 'budget', 'bill', 'type', 'date', 'date_before', 'date_after', 'on', 'before', 'after','from','to','tag'],
// tag notes has_attachments // TODO notes has_attachments
'cer_providers' => [ 'cer_providers' => [
'fixer' => FixerIOv2::class, 'fixer' => FixerIOv2::class,
'ratesapi' => RatesApiIOv1::class, 'ratesapi' => RatesApiIOv1::class,