Implemented for transactions.

This commit is contained in:
James Cole 2017-03-11 07:41:26 +01:00
parent 9dd2f447cc
commit 4abc271805
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
9 changed files with 257 additions and 226 deletions

View File

@ -14,16 +14,19 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers; namespace FireflyIII\Http\Controllers;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\JournalCollectorInterface; use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalTaskerInterface; use FireflyIII\Repositories\Journal\JournalTaskerInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log; use Log;
use Navigation; use Navigation;
use Preferences; use Preferences;
use Response; use Response;
use Steam;
use View; use View;
/** /**
@ -59,109 +62,78 @@ class TransactionController extends Controller
* *
* @return View * @return View
*/ */
public function index(Request $request, JournalRepositoryInterface $repository, string $what) public function index(Request $request, JournalRepositoryInterface $repository, string $what, string $moment = '')
{ {
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data); // default values:
$subTitleIcon = config('firefly.transactionIconsByWhat.' . $what); $subTitleIcon = config('firefly.transactionIconsByWhat.' . $what);
$types = config('firefly.transactionTypesByWhat.' . $what); $types = config('firefly.transactionTypesByWhat.' . $what);
$subTitle = trans('firefly.title_' . $what); $page = intval($request->get('page')) == 0 ? 1 : intval($request->get('page'));
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
$count = 0;
$loop = 0;
$range = Preferences::get('viewRange', '1M')->data; $range = Preferences::get('viewRange', '1M')->data;
$page = intval($request->get('page')) === 0 ? 1 : intval($request->get('page')); $start = null;
// to make sure we only grab a subset, based on the current date (in session): $end = null;
$start = session('start', Navigation::startOfPeriod(new Carbon, $range)); $periods = new Collection;
$end = session('end', Navigation::endOfPeriod(new Carbon, $range));
/** @var JournalCollectorInterface $collector */ // prep for "all" view.
$collector = app(JournalCollectorInterface::class); if ($moment === 'all') {
$collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts()->setRange($start, $end)->withBudgetInformation() $subTitle = trans('firefly.all_' . $what);
->withCategoryInformation(); $first = $repository->first();
$collector->withOpposingAccount(); $start = $first->date ?? new Carbon;
$collector->disableInternalFilter(); $end = new Carbon;
$journals = $collector->getPaginatedJournals();
$journals->setPath('transactions/' . $what);
unset($start, $end);
// then also show a list of periods where the user can click on, based on the
// user's range and the oldest journal the user has:
$first = $repository->first();
$blockStart = is_null($first->id) ? new Carbon : $first->date;
$blockStart = Navigation::startOfPeriod($blockStart, $range);
$blockEnd = Navigation::endOfX(new Carbon, $range);
$entries = new Collection;
while ($blockEnd >= $blockStart) {
Log::debug(sprintf('Now at blockEnd: %s', $blockEnd->format('Y-m-d')));
$blockEnd = Navigation::startOfPeriod($blockEnd, $range);
$dateStr = $blockEnd->format('Y-m-d');
$dateName = Navigation::periodShow($blockEnd, $range);
$entries->push([$dateStr, $dateName]);
$blockEnd = Navigation::subtractPeriod($blockEnd, $range, 1);
} }
return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'journals', 'entries')); // prep for "specific date" view.
if (strlen($moment) > 0 && $moment !== 'all') {
$start = new Carbon($moment);
$end = Navigation::endOfPeriod($start, $range);
$subTitle = trans(
'firefly.title_' . $what . '_between',
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
);
$periods = $this->getPeriodEntries($what);
}
} // prep for current period
if (strlen($moment) === 0) {
$start = clone session('start', Navigation::startOfPeriod(new Carbon, $range));
$end = clone session('end', Navigation::endOfPeriod(new Carbon, $range));
$periods = $this->getPeriodEntries($what);
$subTitle = trans(
'firefly.title_' . $what . '_between',
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
);
}
// grab journals, but be prepared to jump a period back to get the right ones:
Log::info('Now at transaction loop start.');
while ($count === 0 && $loop < 3) {
$loop++;
Log::info('Count is zero, search for journals.');
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($start, $end)->setTypes($types)->setLimit($pageSize)->setPage($page)->withOpposingAccount()
->disableInternalFilter();
$journals = $collector->getPaginatedJournals();
$journals->setPath('/budgets/list/no-budget');
$count = $journals->getCollection()->count();
if ($count === 0) {
$start->subDay();
$start = Navigation::startOfPeriod($start, $range);
$end = Navigation::endOfPeriod($start, $range);
Log::info(sprintf('Count is still zero, go back in time to "%s" and "%s"!', $start->format('Y-m-d'), $end->format('Y-m-d')));
}
}
/** // fix title:
* @param Request $request if (((strlen($moment) > 0 && $moment !== 'all') || strlen($moment) === 0) && $count > 0) {
* @param string $what $subTitle = trans(
* 'firefly.title_' . $what . '_between',
* @return View ['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
*/ );
public function indexAll(Request $request, string $what) }
{
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
$subTitleIcon = config('firefly.transactionIconsByWhat.' . $what);
$types = config('firefly.transactionTypesByWhat.' . $what);
$subTitle = sprintf('%s (%s)', trans('firefly.title_' . $what), strtolower(trans('firefly.everything')));
$page = intval($request->get('page')) === 0 ? 1 : intval($request->get('page'));
/** @var JournalCollectorInterface $collector */ return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'journals', 'periods', 'start', 'end', 'moment'));
$collector = app(JournalCollectorInterface::class);
$collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts()->withBudgetInformation()->withCategoryInformation();
$collector->withOpposingAccount();
$collector->disableInternalFilter();
$journals = $collector->getPaginatedJournals();
$journals->setPath('transactions/' . $what . '/all');
return view('transactions.index-all', compact('subTitle', 'what', 'subTitleIcon', 'journals'));
}
/**
* @param Request $request
* @param string $what
*
* @param string $date
*
* @return View
*/
public function indexByDate(Request $request, string $what, string $date)
{
$carbon = new Carbon($date);
$range = Preferences::get('viewRange', '1M')->data;
$start = Navigation::startOfPeriod($carbon, $range);
$end = Navigation::endOfPeriod($carbon, $range);
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
$subTitleIcon = config('firefly.transactionIconsByWhat.' . $what);
$types = config('firefly.transactionTypesByWhat.' . $what);
$subTitle = trans('firefly.title_' . $what) . ' (' . Navigation::periodShow($carbon, $range) . ')';
$page = intval($request->get('page')) === 0 ? 1 : intval($request->get('page'));
Log::debug(sprintf('Transaction index by date will show between %s and %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts();
$collector->setRange($start, $end)->withBudgetInformation()->withCategoryInformation();
$collector->withOpposingAccount();
$collector->disableInternalFilter();
$journals = $collector->getPaginatedJournals();
$journals->setPath('transactions/' . $what . '/' . $date);
return view('transactions.index-date', compact('subTitle', 'what', 'subTitleIcon', 'journals', 'carbon'));
} }
@ -215,4 +187,78 @@ class TransactionController extends Controller
} }
/**
* @param string $what
*
* @return Collection
* @throws FireflyException
*/
private function getPeriodEntries(string $what): Collection
{
$repository = app(JournalRepositoryInterface::class);
$first = $repository->first();
$start = $first->date ?? new Carbon;
$range = Preferences::get('viewRange', '1M')->data;
$start = Navigation::startOfPeriod($start, $range);
$end = Navigation::endOfX(new Carbon, $range);
$entries = new Collection;
$types = config('firefly.transactionTypesByWhat.' . $what);
// properties for cache
$cache = new CacheProperties;
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($what);
$cache->addProperty('transaction-list-entries');
if ($cache->has()) {
return $cache->get(); // @codeCoverageIgnore
}
Log::debug('Going to get period expenses and incomes.');
while ($end >= $start) {
$end = Navigation::startOfPeriod($end, $range);
$currentEnd = Navigation::endOfPeriod($end, $range);
// count journals without budget in this period:
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($end, $currentEnd)->withOpposingAccount()->setTypes($types)->disableInternalFilter();
$set = $collector->getJournals();
$sum = $set->sum('transaction_amount');
$journals = $set->count();
$dateStr = $end->format('Y-m-d');
$dateName = Navigation::periodShow($end, $range);
$array = [
'string' => $dateStr,
'name' => $dateName,
'count' => $journals,
'spent' => 0,
'earned' => 0,
'transferred' => 0,
'date' => clone $end,
];
switch ($what) {
default:
throw new FireflyException(sprintf('Cannot handle "%s"', $what));
case 'withdrawal':
$array['spent'] = $sum;
break;
case 'deposit':
$array['earned'] = $sum;
break;
case 'transfers':
case 'transfer':
$array['transferred'] = Steam::positive($sum);
break;
}
$entries->push($array);
$end = Navigation::subtractPeriod($end, $range, 1);
}
$cache->store($entries);
return $entries;
}
} }

View File

@ -75,14 +75,10 @@ Breadcrumbs::register(
// push when is all: // push when is all:
if ($moment === 'all') { if ($moment === 'all') {
$breadcrumbs->push(trans('firefly.all_journals_for_account', ['name' => $account->name]), route('accounts.show', [$account->id])); $breadcrumbs->push(trans('firefly.everything'), route('accounts.show', [$account->id]));
} }
// when is specific period: // when is specific period:
if (strlen($moment) > 0 && $moment !== 'all') { if (strlen($moment) > 0 && $moment !== 'all') {$title = trans('firefly.between_dates_breadcrumb', ['start' => $start->formatLocalized(strval(trans('config.month_and_day'))), 'end' => $end->formatLocalized(strval(trans('config.month_and_day')))]);
$title = trans('firefly.journals_in_period_for_account', ['name' => $account->name,
'start' => $start->formatLocalized(strval(trans('config.month_and_day'))),
'end' => $end->formatLocalized(strval(trans('config.month_and_day')))]
);
$breadcrumbs->push($title, route('accounts.show', [$account->id, $moment])); $breadcrumbs->push($title, route('accounts.show', [$account->id, $moment]));
} }
@ -255,12 +251,12 @@ Breadcrumbs::register(
// push when is all: // push when is all:
if ($moment === 'all') { if ($moment === 'all') {
$breadcrumbs->push(trans('firefly.all_journals_without_budget'), route('budgets.no-budget', ['all'])); $breadcrumbs->push(trans('firefly.everything'), route('budgets.no-budget', ['all']));
} }
// when is specific period: // when is specific period:
if (strlen($moment) > 0 && $moment !== 'all') { if (strlen($moment) > 0 && $moment !== 'all') {
$title = trans('firefly.without_budget_between', ['start' => $start->formatLocalized(strval(trans('config.month_and_day'))), $title = trans('firefly.between_dates_breadcrumb', ['start' => $start->formatLocalized(strval(trans('config.month_and_day'))),
'end' => $end->formatLocalized(strval(trans('config.month_and_day')))] 'end' => $end->formatLocalized(strval(trans('config.month_and_day')))]
); );
$breadcrumbs->push($title, route('budgets.no-budget', [$moment])); $breadcrumbs->push($title, route('budgets.no-budget', [$moment]));
} }
@ -282,11 +278,8 @@ Breadcrumbs::register(
$breadcrumbs->push(e($budget->name), route('budgets.show', [$budget->id])); $breadcrumbs->push(e($budget->name), route('budgets.show', [$budget->id]));
$title = trans( $title = trans(
'firefly.budget_in_period_breadcrumb', [ 'firefly.between_dates_breadcrumb', ['start' => $budgetLimit->start_date->formatLocalized(strval(trans('config.month_and_day'))),
'name' => $budget->name, 'end' => $budgetLimit->end_date->formatLocalized(strval(trans('config.month_and_day'))),]
'start' => $budgetLimit->start_date->formatLocalized(strval(trans('config.month_and_day'))),
'end' => $budgetLimit->end_date->formatLocalized(strval(trans('config.month_and_day'))),
]
); );
$breadcrumbs->push( $breadcrumbs->push(
@ -360,12 +353,13 @@ Breadcrumbs::register(
// push when is all: // push when is all:
if ($moment === 'all') { if ($moment === 'all') {
$breadcrumbs->push(trans('firefly.all_journals_without_category'), route('categories.no-category', ['all'])); $breadcrumbs->push(trans('firefly.everything'), route('categories.no-category', ['all']));
} }
// when is specific period: // when is specific period:
if (strlen($moment) > 0 && $moment !== 'all') { if (strlen($moment) > 0 && $moment !== 'all') {
$title = trans('firefly.without_category_between', ['start' => $start->formatLocalized(strval(trans('config.month_and_day'))), $title = trans(
'end' => $end->formatLocalized(strval(trans('config.month_and_day')))] 'firefly.between_dates_breadcrumb', ['start' => $start->formatLocalized(strval(trans('config.month_and_day'))),
'end' => $end->formatLocalized(strval(trans('config.month_and_day')))]
); );
$breadcrumbs->push($title, route('categories.no-category', [$moment])); $breadcrumbs->push($title, route('categories.no-category', [$moment]));
} }
@ -741,36 +735,27 @@ Breadcrumbs::register(
* TRANSACTIONS * TRANSACTIONS
*/ */
Breadcrumbs::register( Breadcrumbs::register(
'transactions.index', function (BreadCrumbGenerator $breadcrumbs, string $what) { 'transactions.index', function (BreadCrumbGenerator $breadcrumbs, string $what, string $moment = '', Carbon $start, Carbon $end) {
$breadcrumbs->parent('home'); $breadcrumbs->parent('home');
$breadcrumbs->push(trans('breadcrumbs.' . $what . '_list'), route('transactions.index', [$what])); $breadcrumbs->push(trans('breadcrumbs.' . $what . '_list'), route('transactions.index', [$what]));
} if($moment === 'all') {
); $breadcrumbs->push(trans('firefly.everything'), route('transactions.index', [$what, 'all']));
}
Breadcrumbs::register( // when is specific period:
'transactions.index.all', function (BreadCrumbGenerator $breadcrumbs, string $what) { if (strlen($moment) > 0 && $moment !== 'all') {
$breadcrumbs->parent('transactions.index', $what); $title = trans('firefly.between_dates_breadcrumb', ['start' => $start->formatLocalized(strval(trans('config.month_and_day'))), 'end' => $end->formatLocalized(strval(trans('config.month_and_day')))]);
$breadcrumbs->push($title, route('transactions.index', [$what, $moment]));
}
$title = sprintf('%s (%s)', trans('breadcrumbs.' . $what . '_list'), strtolower(trans('firefly.everything')));
$breadcrumbs->push($title, route('transactions.index.all', [$what]));
}
);
Breadcrumbs::register(
'transactions.index.date', function (BreadCrumbGenerator $breadcrumbs, string $what, Carbon $date) {
$breadcrumbs->parent('transactions.index', $what);
$range = Preferences::get('viewRange', '1M')->data;
$title = trans('breadcrumbs.' . $what . '_list') . ' (' . Navigation::periodShow($date, $range) . ')';
$breadcrumbs->push($title, route('transactions.index.date', [$what, $date->format('Y-m-d')]));
} }
); );
Breadcrumbs::register( Breadcrumbs::register(
'transactions.create', function (BreadCrumbGenerator $breadcrumbs, string $what) { 'transactions.create', function (BreadCrumbGenerator $breadcrumbs, string $what) {
$breadcrumbs->parent('transactions.index', $what); $breadcrumbs->parent('transactions.index', $what,'', new Carbon, new Carbon);
$breadcrumbs->push(trans('breadcrumbs.create_' . e($what)), route('transactions.create', [$what])); $breadcrumbs->push(trans('breadcrumbs.create_' . e($what)), route('transactions.create', [$what]));
} }
); );
@ -792,7 +777,7 @@ Breadcrumbs::register(
'transactions.show', function (BreadCrumbGenerator $breadcrumbs, TransactionJournal $journal) { 'transactions.show', function (BreadCrumbGenerator $breadcrumbs, TransactionJournal $journal) {
$what = strtolower($journal->transactionType->type); $what = strtolower($journal->transactionType->type);
$breadcrumbs->parent('transactions.index', $what); $breadcrumbs->parent('transactions.index', $what,'', new Carbon, new Carbon);
$breadcrumbs->push($journal->description, route('transactions.show', [$journal->id])); $breadcrumbs->push($journal->description, route('transactions.show', [$journal->id]));
} }
); );
@ -817,7 +802,7 @@ Breadcrumbs::register(
if ($journals->count() > 0) { if ($journals->count() > 0) {
$journalIds = $journals->pluck('id')->toArray(); $journalIds = $journals->pluck('id')->toArray();
$what = strtolower($journals->first()->transactionType->type); $what = strtolower($journals->first()->transactionType->type);
$breadcrumbs->parent('transactions.index', $what); $breadcrumbs->parent('transactions.index', $what,'', new Carbon, new Carbon);
$breadcrumbs->push(trans('firefly.mass_edit_journals'), route('transactions.mass.edit', $journalIds)); $breadcrumbs->push(trans('firefly.mass_edit_journals'), route('transactions.mass.edit', $journalIds));
return; return;
@ -832,7 +817,7 @@ Breadcrumbs::register(
$journalIds = $journals->pluck('id')->toArray(); $journalIds = $journals->pluck('id')->toArray();
$what = strtolower($journals->first()->transactionType->type); $what = strtolower($journals->first()->transactionType->type);
$breadcrumbs->parent('transactions.index', $what); $breadcrumbs->parent('transactions.index', $what,'', new Carbon, new Carbon);
$breadcrumbs->push(trans('firefly.mass_edit_journals'), route('transactions.mass.delete', $journalIds)); $breadcrumbs->push(trans('firefly.mass_edit_journals'), route('transactions.mass.delete', $journalIds));
} }
); );

View File

@ -72,7 +72,7 @@ class Navigation
* @return \Carbon\Carbon * @return \Carbon\Carbon
* @throws FireflyException * @throws FireflyException
*/ */
public function endOfPeriod(Carbon $end, string $repeatFreq): Carbon public function endOfPeriod(\Carbon\Carbon $end, string $repeatFreq): Carbon
{ {
$currentEnd = clone $end; $currentEnd = clone $end;

View File

@ -115,13 +115,22 @@ return [
'multi_select_no_selection' => 'None selected', 'multi_select_no_selection' => 'None selected',
'multi_select_all_selected' => 'All selected', 'multi_select_all_selected' => 'All selected',
'multi_select_filter_placeholder' => 'Find..', 'multi_select_filter_placeholder' => 'Find..',
'between_dates_breadcrumb' => 'Between :start and :end',
'all_journals_without_budget' => 'All transactions without a budget', 'all_journals_without_budget' => 'All transactions without a budget',
'all_journals_without_category' => 'All transactions without a category',
'journals_without_budget' => 'Transactions without a budget', 'journals_without_budget' => 'Transactions without a budget',
'all_journals_without_category' => 'All transactions without a category',
'journals_without_category' => 'Transactions without a category', 'journals_without_category' => 'Transactions without a category',
'all_journals_for_account' => 'All transactions for account :name', 'all_journals_for_account' => 'All transactions for account :name',
'journals_in_period_for_account' => 'All transactions for account :name between :start and :end', 'journals_in_period_for_account' => 'All transactions for account :name between :start and :end',
'transferred' => 'Transferred', 'transferred' => 'Transferred',
'all_withdrawal' => 'All expenses',
'title_withdrawal_between' => 'All expenses between :start and :end',
'all_deposit' => 'All revenue',
'title_deposit_between' => 'All revenue between :start and :end',
'all_transfers' => 'All transfers',
'title_transfers_between' => 'All transfers between :start and :end',
'all_transfer' => 'All transfers',
'title_transfer_between' => 'All transfers between :start and :end',
// repeat frequencies: // repeat frequencies:

View File

@ -1,27 +0,0 @@
{% extends "./layout/default" %}
{% block breadcrumbs %}
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, what) }}
{% endblock %}
{% block content %}
{% if journals.count == 0 %}
{% include 'partials.empty' with {what: what, type: 'transactions',route: route('transactions.create', [what])} %}
{% else %}
<div class="row">
<div class="col-lg-12 col-sm-12 col-md-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ subTitle }}</h3>
</div>
<div class="box-body">
{% include 'list.journals-tasker' %}
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}
{% block scripts %}
<script type="text/javascript" src="js/ff/transactions/list.js"></script>
{% endblock %}

View File

@ -1,33 +0,0 @@
{% extends "./layout/default" %}
{% block breadcrumbs %}
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, what, carbon) }}
{% endblock %}
{% block content %}
{% if journals.count == 0 %}
<div class="row">
<div class="col-lg-12 col-sm-12 col-md-12">
<p class="well">
{{ 'no_transactions_in_period'|_ }}
</p>
</div>
</div>
{% else %}
<div class="row">
<div class="col-lg-12 col-sm-12 col-md-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ subTitle }}</h3>
</div>
<div class="box-body">
{% include 'list.journals-tasker' %}
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}
{% block scripts %}
<script type="text/javascript" src="js/ff/transactions/list.js"></script>
{% endblock %}

View File

@ -1,46 +1,93 @@
{% extends "./layout/default" %} {% extends "./layout/default" %}
{% block breadcrumbs %} {% block breadcrumbs %}
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, what) }} {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, what, moment, start, end) }}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{# upper show-all instruction #}
{% if periods.count > 0 %}
<div class="row"> <div class="row">
<div class="col-lg-10 col-md-10 col-sm-12"> <div class="col-lg-offset-10 col-lg-2 col-md-offset-10 col-md-2 col-sm-12 col-xs-12">
<div class="box"> <p class="small text-center"><a href="{{ route('transactions.index',[what, 'all']) }}">{{ 'showEverything'|_ }}</a></p>
<div class="box-header with-border"> </div>
<h3 class="box-title">{{ subTitle }}</h3> </div>
</div> {% endif %}
<div class="box-body">
{% include 'list.journals-tasker' %} <div class="row">
<div class="{% if periods.count > 0 %}col-lg-10 col-md-10 col-sm-12{% else %}col-lg-12 col-md-12 col-sm-12{% endif %}">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ subTitle }}</h3>
</div>
<div class="box-body ">
{% include 'list.journals-tasker' with {'journals': journals} %}
{% if periods.count > 0 %}
<p> <p>
<i class="fa fa-calendar" aria-hidden="true"></i> <i class="fa fa-calendar" aria-hidden="true"></i>
<a href="{{ route('transactions.index.all', [what]) }}"> <a href="{{ route('transactions.index', [what, 'all']) }}">{{ 'show_all_no_filter'|_ }}</a>
{{ 'show_all_no_filter'|_ }}
</a>
</p> </p>
</div> {% else %}
<p>
<i class="fa fa-calendar" aria-hidden="true"></i>
<a href="{{ route('transactions.index', [what]) }}">{{ 'show_the_current_period_and_overview'|_ }}</a>
</p>
{% endif %}
</div> </div>
</div> </div>
</div>
{% if periods.count > 0 %}
<div class="col-lg-2 col-md-2 col-sm-12 col-xs-12"> <div class="col-lg-2 col-md-2 col-sm-12 col-xs-12">
{% for entry in entries %} {% for entry in periods %}
<div class="box"> <div class="box {% if entry.date == start %}box-solid box-primary{% endif %}">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"> <h3 class="box-title"><a href="{{ route('transactions.index',[what, entry.string]) }}">{{ entry.name }}</a>
<a href="{{ route('transactions.index.date',[what,entry[0]]) }}">{{ entry[1] }}</a>
</h3> </h3>
</div> </div>
<div class="box-body"> <div class="box-body no-padding">
&nbsp; <table class="table table-hover">
<tr>
<td style="width:33%;">{{ 'transactions'|_ }}</td>
<td style="text-align: right;">{{ entry.count }}</td>
</tr>
{% if what == 'withdrawal' %}
<tr>
<td style="width:33%;">{{ 'spent'|_ }}</td>
<td style="text-align: right;">{{ entry.spent|formatAmount }}</td>
</tr>
{% endif %}
{% if what == 'deposit' %}
<tr>
<td style="width:33%;">{{ 'earned'|_ }}</td>
<td style="text-align: right;">{{ entry.earned|formatAmount }}</td>
</tr>
{% endif %}
{% if what == 'transfers' or what == 'transfer' %}
<tr>
<td style="width:33%;">{{ 'transferred'|_ }}</td>
<td style="text-align: right;" class="text-info">{{ entry.transferred|formatAmountPlain }}</td>
</tr>
{% endif %}
</table>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
{% endif %}
</div>
{# lower show-all instruction #}
{% if periods.count > 0 %}
<div class="row">
<div class="col-lg-offset-10 col-lg-2 col-md-offset-10 col-md-2 col-sm-12 col-xs-12">
<p class="small text-center"><a href="{{ route('transactions.index',[what, 'all']) }}">{{ 'showEverything'|_ }}</a></p>
</div>
</div> </div>
{% endif %}
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="js/ff/transactions/list.js"></script> <script type="text/javascript" src="js/ff/transactions/list.js"></script>

View File

@ -662,11 +662,11 @@ Route::group(
*/ */
Route::group( Route::group(
['middleware' => 'user-full-auth', 'prefix' => 'transactions', 'as' => 'transactions.'], function () { ['middleware' => 'user-full-auth', 'prefix' => 'transactions', 'as' => 'transactions.'], function () {
Route::get('{what}', ['uses' => 'TransactionController@index', 'as' => 'index'])->where(['what' => 'withdrawal|deposit|transfers|transfer']); Route::get('{what}/{moment?}', ['uses' => 'TransactionController@index', 'as' => 'index'])->where(['what' => 'withdrawal|deposit|transfers|transfer']);
Route::get('{what}/all', ['uses' => 'TransactionController@indexAll', 'as' => 'index.all'])->where(['what' => 'withdrawal|deposit|transfers|transfer']); // Route::get('{what}/all', ['uses' => 'TransactionController@indexAll', 'as' => 'index.all'])->where(['what' => 'withdrawal|deposit|transfers|transfer']);
Route::get('{what}/{date}', ['uses' => 'TransactionController@indexByDate', 'as' => 'index.date'])->where( // Route::get('{what}/{date}', ['uses' => 'TransactionController@indexByDate', 'as' => 'index.date'])->where(
['what' => 'withdrawal|deposit|transfers|transfer'] // ['what' => 'withdrawal|deposit|transfers|transfer']
); // );
Route::get('show/{tj}', ['uses' => 'TransactionController@show', 'as' => 'show']); Route::get('show/{tj}', ['uses' => 'TransactionController@show', 'as' => 'show']);
Route::post('reorder', ['uses' => 'TransactionController@reorder', 'as' => 'reorder']); Route::post('reorder', ['uses' => 'TransactionController@reorder', 'as' => 'reorder']);
} }

View File

@ -43,6 +43,7 @@ class TransactionControllerTest extends TestCase
$collector->shouldReceive('withOpposingAccount')->andReturnSelf(); $collector->shouldReceive('withOpposingAccount')->andReturnSelf();
$collector->shouldReceive('disableInternalFilter')->andReturnSelf(); $collector->shouldReceive('disableInternalFilter')->andReturnSelf();
$collector->shouldReceive('getPaginatedJournals')->andReturn(new LengthAwarePaginator([], 0, 10)); $collector->shouldReceive('getPaginatedJournals')->andReturn(new LengthAwarePaginator([], 0, 10));
$collector->shouldReceive('getJournals')->andReturn(new Collection);
$this->be($this->user()); $this->be($this->user());
$response = $this->get(route('transactions.index', ['transfer'])); $response = $this->get(route('transactions.index', ['transfer']));
@ -52,14 +53,14 @@ class TransactionControllerTest extends TestCase
} }
/** /**
* @covers \FireflyIII\Http\Controllers\TransactionController::indexAll * @covers \FireflyIII\Http\Controllers\TransactionController::index
*/ */
public function testIndexAll() public function testIndexAll()
{ {
// mock stuff // mock stuff
$repository = $this->mock(JournalRepositoryInterface::class); $repository = $this->mock(JournalRepositoryInterface::class);
$collector = $this->mock(JournalCollectorInterface::class); $collector = $this->mock(JournalCollectorInterface::class);
$repository->shouldReceive('first')->once()->andReturn(new TransactionJournal); $repository->shouldReceive('first')->twice()->andReturn(new TransactionJournal);
$collector->shouldReceive('setTypes')->andReturnSelf(); $collector->shouldReceive('setTypes')->andReturnSelf();
$collector->shouldReceive('setLimit')->andReturnSelf(); $collector->shouldReceive('setLimit')->andReturnSelf();
@ -71,23 +72,24 @@ class TransactionControllerTest extends TestCase
$collector->shouldReceive('withOpposingAccount')->andReturnSelf(); $collector->shouldReceive('withOpposingAccount')->andReturnSelf();
$collector->shouldReceive('disableInternalFilter')->andReturnSelf(); $collector->shouldReceive('disableInternalFilter')->andReturnSelf();
$collector->shouldReceive('getPaginatedJournals')->andReturn(new LengthAwarePaginator([], 0, 10)); $collector->shouldReceive('getPaginatedJournals')->andReturn(new LengthAwarePaginator([], 0, 10));
$collector->shouldReceive('getJournals')->andReturn(new Collection);
$this->be($this->user()); $this->be($this->user());
$response = $this->get(route('transactions.index.all', ['transfer'])); $response = $this->get(route('transactions.index', ['transfer','all']));
$response->assertStatus(200); $response->assertStatus(200);
// has bread crumb // has bread crumb
$response->assertSee('<ol class="breadcrumb">'); $response->assertSee('<ol class="breadcrumb">');
} }
/** /**
* @covers \FireflyIII\Http\Controllers\TransactionController::indexByDate * @covers \FireflyIII\Http\Controllers\TransactionController::index
*/ */
public function testIndexByDate() public function testIndexByDate()
{ {
// mock stuff // mock stuff
$repository = $this->mock(JournalRepositoryInterface::class); $repository = $this->mock(JournalRepositoryInterface::class);
$collector = $this->mock(JournalCollectorInterface::class); $collector = $this->mock(JournalCollectorInterface::class);
$repository->shouldReceive('first')->once()->andReturn(new TransactionJournal); $repository->shouldReceive('first')->twice()->andReturn(new TransactionJournal);
$collector->shouldReceive('setTypes')->andReturnSelf(); $collector->shouldReceive('setTypes')->andReturnSelf();
$collector->shouldReceive('setLimit')->andReturnSelf(); $collector->shouldReceive('setLimit')->andReturnSelf();
@ -99,9 +101,11 @@ class TransactionControllerTest extends TestCase
$collector->shouldReceive('withOpposingAccount')->andReturnSelf(); $collector->shouldReceive('withOpposingAccount')->andReturnSelf();
$collector->shouldReceive('disableInternalFilter')->andReturnSelf(); $collector->shouldReceive('disableInternalFilter')->andReturnSelf();
$collector->shouldReceive('getPaginatedJournals')->andReturn(new LengthAwarePaginator([], 0, 10)); $collector->shouldReceive('getPaginatedJournals')->andReturn(new LengthAwarePaginator([], 0, 10));
$collector->shouldReceive('getJournals')->andReturn(new Collection);
$this->be($this->user()); $this->be($this->user());
$response = $this->get(route('transactions.index.date', ['transfer', '2016-01-01'])); $response = $this->get(route('transactions.index', ['transfer', '2016-01-01']));
$response->assertStatus(200); $response->assertStatus(200);
// has bread crumb // has bread crumb
$response->assertSee('<ol class="breadcrumb">'); $response->assertSee('<ol class="breadcrumb">');