mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-29 18:20:01 +00:00
Implemented #595 for transactions.
This commit is contained in:
@@ -14,16 +14,19 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalTaskerInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Navigation;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Steam;
|
||||
use View;
|
||||
|
||||
/**
|
||||
@@ -59,109 +62,78 @@ class TransactionController extends Controller
|
||||
*
|
||||
* @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);
|
||||
$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;
|
||||
$page = intval($request->get('page')) === 0 ? 1 : intval($request->get('page'));
|
||||
// to make sure we only grab a subset, based on the current date (in session):
|
||||
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
|
||||
$end = session('end', Navigation::endOfPeriod(new Carbon, $range));
|
||||
$start = null;
|
||||
$end = null;
|
||||
$periods = new Collection;
|
||||
|
||||
/** @var JournalCollectorInterface $collector */
|
||||
$collector = app(JournalCollectorInterface::class);
|
||||
$collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts()->setRange($start, $end)->withBudgetInformation()
|
||||
->withCategoryInformation();
|
||||
$collector->withOpposingAccount();
|
||||
$collector->disableInternalFilter();
|
||||
$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);
|
||||
// prep for "all" view.
|
||||
if ($moment === 'all') {
|
||||
$subTitle = trans('firefly.all_' . $what);
|
||||
$first = $repository->first();
|
||||
$start = $first->date ?? new Carbon;
|
||||
$end = new Carbon;
|
||||
}
|
||||
|
||||
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')));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $what
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
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'));
|
||||
// fix title:
|
||||
if (((strlen($moment) > 0 && $moment !== 'all') || strlen($moment) === 0) && $count > 0) {
|
||||
$subTitle = trans(
|
||||
'firefly.title_' . $what . '_between',
|
||||
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
|
||||
);
|
||||
}
|
||||
|
||||
/** @var JournalCollectorInterface $collector */
|
||||
$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'));
|
||||
return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'journals', 'periods', 'start', 'end', 'moment'));
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -75,14 +75,10 @@ Breadcrumbs::register(
|
||||
|
||||
// push when is 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:
|
||||
if (strlen($moment) > 0 && $moment !== 'all') {
|
||||
$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')))]
|
||||
);
|
||||
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')))]);
|
||||
$breadcrumbs->push($title, route('accounts.show', [$account->id, $moment]));
|
||||
}
|
||||
|
||||
@@ -255,12 +251,12 @@ Breadcrumbs::register(
|
||||
|
||||
// push when is 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:
|
||||
if (strlen($moment) > 0 && $moment !== 'all') {
|
||||
$title = trans('firefly.without_budget_between', ['start' => $start->formatLocalized(strval(trans('config.month_and_day'))),
|
||||
'end' => $end->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')))]
|
||||
);
|
||||
$breadcrumbs->push($title, route('budgets.no-budget', [$moment]));
|
||||
}
|
||||
@@ -282,11 +278,8 @@ Breadcrumbs::register(
|
||||
$breadcrumbs->push(e($budget->name), route('budgets.show', [$budget->id]));
|
||||
|
||||
$title = trans(
|
||||
'firefly.budget_in_period_breadcrumb', [
|
||||
'name' => $budget->name,
|
||||
'start' => $budgetLimit->start_date->formatLocalized(strval(trans('config.month_and_day'))),
|
||||
'end' => $budgetLimit->end_date->formatLocalized(strval(trans('config.month_and_day'))),
|
||||
]
|
||||
'firefly.between_dates_breadcrumb', ['start' => $budgetLimit->start_date->formatLocalized(strval(trans('config.month_and_day'))),
|
||||
'end' => $budgetLimit->end_date->formatLocalized(strval(trans('config.month_and_day'))),]
|
||||
);
|
||||
|
||||
$breadcrumbs->push(
|
||||
@@ -360,12 +353,13 @@ Breadcrumbs::register(
|
||||
|
||||
// push when is 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:
|
||||
if (strlen($moment) > 0 && $moment !== 'all') {
|
||||
$title = trans('firefly.without_category_between', ['start' => $start->formatLocalized(strval(trans('config.month_and_day'))),
|
||||
'end' => $end->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')))]
|
||||
);
|
||||
$breadcrumbs->push($title, route('categories.no-category', [$moment]));
|
||||
}
|
||||
@@ -741,36 +735,27 @@ Breadcrumbs::register(
|
||||
* TRANSACTIONS
|
||||
*/
|
||||
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->push(trans('breadcrumbs.' . $what . '_list'), route('transactions.index', [$what]));
|
||||
}
|
||||
);
|
||||
if($moment === 'all') {
|
||||
$breadcrumbs->push(trans('firefly.everything'), route('transactions.index', [$what, 'all']));
|
||||
}
|
||||
|
||||
Breadcrumbs::register(
|
||||
'transactions.index.all', function (BreadCrumbGenerator $breadcrumbs, string $what) {
|
||||
$breadcrumbs->parent('transactions.index', $what);
|
||||
// when is specific period:
|
||||
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')))]);
|
||||
$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(
|
||||
'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]));
|
||||
}
|
||||
);
|
||||
@@ -792,7 +777,7 @@ Breadcrumbs::register(
|
||||
'transactions.show', function (BreadCrumbGenerator $breadcrumbs, TransactionJournal $journal) {
|
||||
|
||||
$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]));
|
||||
}
|
||||
);
|
||||
@@ -817,7 +802,7 @@ Breadcrumbs::register(
|
||||
if ($journals->count() > 0) {
|
||||
$journalIds = $journals->pluck('id')->toArray();
|
||||
$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));
|
||||
|
||||
return;
|
||||
@@ -832,7 +817,7 @@ Breadcrumbs::register(
|
||||
|
||||
$journalIds = $journals->pluck('id')->toArray();
|
||||
$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));
|
||||
}
|
||||
);
|
||||
|
Reference in New Issue
Block a user