New code for overview. Temp submit.

This commit is contained in:
James Cole 2019-04-19 07:00:19 +02:00
parent 4d3af1dcde
commit 912fe99981
15 changed files with 558 additions and 168 deletions

View File

@ -0,0 +1,195 @@
<?php
/**
* GroupSumCollector.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Helpers\Collector;
use Carbon\Carbon;
use FireflyIII\Models\Transaction;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* Class GroupSumCollector
*/
class GroupSumCollector implements GroupSumCollectorInterface
{
/** @var array The fields to select. */
private $fields;
/** @var bool Will be true if query has joined transaction type table. */
private $hasJoinedTypeTable;
/** @var HasMany The query object. */
private $query;
/** @var User The user object. */
private $user;
/**
* GroupSumCollector constructor.
*/
public function __construct()
{
$this->hasJoinedTypeTable = false;
$this->fields = [
'transactions.amount',
'transactions.transaction_currency_id as currency_id',
'local.code as currency_code',
'local.name as currency_name',
'local.symbol as currency_symbol',
'local.decimal_places as currency_decimal_places',
'transactions.foreign_amount',
'transactions.foreign_currency_id',
'foreign.code as foreign_currency_code',
'foreign.name as foreign_currency_name',
'foreign.symbol as foreign_currency_symbol',
'foreign.decimal_places as foreign_currency_decimal_places',
];
}
/**
* @return array
*/
public function getSum(): array
{
$result = $this->query->get($this->fields);
$return = [
'count' => 0,
'sums' => [],
];
if (0 === $result->count()) {
return $return;
}
foreach ($result as $row) {
$return['count']++;
$currencyId = (int)$row->currency_id;
if (!isset($return['sums'][$currencyId])) {
$return['sums'][$currencyId] = [
'sum' => '0',
'currency_id' => $currencyId,
'currency_code' => $row->currency_code,
'currency_symbol' => $row->currency_symbol,
'currency_name' => $row->currency_name,
'currency_decimal_places' => (int)$row->currency_decimal_places,
];
}
// add amounts:
$return['sums'][$currencyId]['sum'] = bcadd($return['sums'][$currencyId]['sum'], (string)$row->amount);
// same but for foreign amounts:
if (null !== $row->foreign_currency_id) {
$foreignCurrencyId = (int)$row->foreign_currency_id;
$return['sums'][$foreignCurrencyId] = [
'sum' => '0',
'currency_id' => $foreignCurrencyId,
'currency_code' => $row->foreign_currency_code,
'currency_symbol' => $row->foreign_currency_symbol,
'currency_name' => $row->foreign_currency_name,
'currency_decimal_places' => (int)$row->foreign_currency_decimal_places,
];
$return['sums'][$foreignCurrencyId]['sum'] = bcadd($return['sums'][$foreignCurrencyId]['sum'], (string)$row->foreign_amount);
}
}
return $return;
}
/**
* Reset the query.
*
* @return GroupSumCollectorInterface
*/
public function resetQuery(): GroupSumCollectorInterface
{
$this->startQuery();
$this->hasJoinedTypeTable = false;
return $this;
}
/**
* Limit the sum to a set of transaction types.
*
* @param array $types
*
* @return GroupSumCollectorInterface
*/
public function setTypes(array $types): GroupSumCollectorInterface
{
if (false === $this->hasJoinedTypeTable) {
$this->joinTypeTable();
}
$this->query->whereIn('transaction_types.type', $types);
return $this;
}
/**
* Set the user object and start the query.
*
* @param User $user
*
* @return GroupSumCollectorInterface
*/
public function setUser(User $user): GroupSumCollectorInterface
{
$this->user = $user;
$this->startQuery();
return $this;
}
private function joinTypeTable(): void
{
$this->hasJoinedTypeTable = true;
$this->query->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
}
/**
*
*/
private function startQuery(): void
{
$this->query = Transaction::
leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->leftJoin('transaction_currencies as local', 'local.id', '=', 'transactions.transaction_currency_id')
->leftJoin('transaction_currencies as foreign', 'foreign.id', '=', 'transactions.foreign_currency_id')
->where('transaction_journals.user_id', $this->user->id)
->whereNull('transaction_journals.deleted_at')
->whereNull('transactions.deleted_at')
->where('transactions.amount', '>', 0);
}
/**
* @param Carbon $start
* @param Carbon $end
*
* @return GroupSumCollectorInterface
*/
public function setRange(Carbon $start, Carbon $end): GroupSumCollectorInterface
{
$this->query
->where('transaction_journals.date','>=',$start->format('Y-m-d H:i:s'))
->where('transaction_journals.date','<=',$end->format('Y-m-d H:i:s'));
return $this;
}
}

View File

@ -0,0 +1,73 @@
<?php
/**
* GroupSumCollectorInterface.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Helpers\Collector;
use Carbon\Carbon;
use FireflyIII\User;
/**
* Interface GroupSumCollectorInterface
*/
interface GroupSumCollectorInterface
{
/**
* Return the final sum.
*
* @return array
*/
public function getSum(): array;
/**
* @param Carbon $start
* @param Carbon $end
*
* @return GroupSumCollectorInterface
*/
public function setRange(Carbon $start, Carbon $end): GroupSumCollectorInterface;
/**
* Reset the query.
*
* @return GroupSumCollectorInterface
*/
public function resetQuery(): GroupSumCollectorInterface;
/**
* Limit the sum to a set of transaction types.
*
* @param array $types
*
* @return GroupSumCollectorInterface
*/
public function setTypes(array $types): GroupSumCollectorInterface;
/**
* Set the user object and start the query.
*
* @param User $user
*
* @return GroupSumCollectorInterface
*/
public function setUser(User $user): GroupSumCollectorInterface;
}

View File

@ -0,0 +1,35 @@
<?php
/**
* CreateController.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Transaction;
use FireflyIII\Http\Controllers\Controller;
/**
* Class CreateController
*/
class CreateController extends Controller
{
}

View File

@ -0,0 +1,91 @@
<?php
/**
* IndexController.php
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Transaction;
use Carbon\Carbon;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Support\Http\Controllers\ModelInformation;
use FireflyIII\Support\Http\Controllers\PeriodOverview;
use Illuminate\Http\Request;
/**
* Class IndexController
*/
class IndexController extends Controller
{
use PeriodOverview;
/**
* Index for a range of transactions.
*
* @param Request $request
* @param string $transactionType
* @param Carbon|null $start
* @param Carbon|null $end
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(Request $request, string $transactionType, Carbon $start = null, Carbon $end = null)
{
$subTitleIcon = config('firefly.transactionIconsByType.' . $transactionType);
$types = config('firefly.transactionTypesByType.' . $transactionType);
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
if (null === $start) {
$start = session('start');
$end = session('end');
}
if (null === $end) {
$end = session('end');
}
if ($end < $start) {
[$start, $end] = [$end, $start];
}
$path = route('transactions.index', [$transactionType, $start->format('Y-m-d'), $end->format('Y-m-d')]);
$startStr = $start->formatLocalized($this->monthAndDayFormat);
$endStr = $end->formatLocalized($this->monthAndDayFormat);
$subTitle = (string)trans(sprintf('firefly.title_%s_between',$transactionType), ['start' => $startStr, 'end' => $endStr]);
$periods = $this->getTransactionPeriodOverview($transactionType, $end);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)
->setTypes($types)
->setLimit($pageSize)
->setPage($page)
->withBudgetInformation()
->withCategoryInformation()
->withAccountInformation();
$groups = $collector->getPaginatedGroups();
$groups->setPath($path);
return view('transactions.index', compact('subTitle', 'transactionType', 'subTitleIcon', 'groups', 'periods', 'start', 'end'));
}
}

View File

@ -49,6 +49,7 @@ use View;
*/
class SingleController extends Controller
{
use ModelInformation;
/** @var AttachmentHelperInterface The attachment helper. */
@ -63,6 +64,7 @@ class SingleController extends Controller
*/
public function __construct()
{
throw new FireflyException('Do not use me.');
parent::__construct();
$maxFileSize = app('steam')->phpBytes(ini_get('upload_max_filesize'));

View File

@ -61,6 +61,7 @@ class SplitController extends Controller
*/
public function __construct()
{
throw new FireflyException('Do not use me.');
parent::__construct();
// some useful repositories:

View File

@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\CountAttachmentsFilter;
@ -71,57 +72,6 @@ class TransactionController extends Controller
);
}
/**
* Index for a range of transactions.
*
* @param Request $request
* @param string $what
* @param Carbon|null $start
* @param Carbon|null $end
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(Request $request, string $what, Carbon $start = null, Carbon $end = null)
{
$subTitleIcon = config('firefly.transactionIconsByWhat.' . $what);
$types = config('firefly.transactionTypesByWhat.' . $what);
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
if (null === $start) {
$start = session('start');
$end = session('end');
}
if (null === $end) {
$end = session('end');
}
if ($end < $start) {
[$start, $end] = [$end, $start];
}
$path = route('transactions.index', [$what, $start->format('Y-m-d'), $end->format('Y-m-d')]);
$startStr = $start->formatLocalized($this->monthAndDayFormat);
$endStr = $end->formatLocalized($this->monthAndDayFormat);
$subTitle = (string)trans('firefly.title_' . $what . '_between', ['start' => $startStr, 'end' => $endStr]);
$periods = $this->getTransactionPeriodOverview($what, $end);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)
->setTypes($types)
->setLimit($pageSize)
->setPage($page)
->withBudgetInformation()
->withCategoryInformation()
->withAccountInformation();
$groups = $collector->getPaginatedGroups();
$groups->setPath($path);
return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'groups', 'periods', 'start', 'end'));
}
/**
* Index for ALL transactions.
*
@ -132,6 +82,7 @@ class TransactionController extends Controller
*/
public function indexAll(Request $request, string $what)
{
throw new FireflyException('Do not use me.');
$subTitleIcon = config('firefly.transactionIconsByWhat.' . $what);
$types = config('firefly.transactionTypesByWhat.' . $what);
$page = (int)$request->get('page');

View File

@ -24,6 +24,8 @@ namespace FireflyIII\Providers;
use FireflyIII\Helpers\Collector\GroupCollector;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Collector\GroupSumCollector;
use FireflyIII\Helpers\Collector\GroupSumCollectorInterface;
use FireflyIII\Helpers\Collector\TransactionCollector;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Repositories\Journal\JournalRepository;
@ -55,6 +57,7 @@ class JournalServiceProvider extends ServiceProvider
$this->registerGroupRepository();
$this->registerCollector();
$this->registerGroupCollector();
$this->registerSumCollector();
}
/**
@ -95,7 +98,10 @@ class JournalServiceProvider extends ServiceProvider
);
}
private function registerGroupRepository()
/**
* Register group repos.
*/
private function registerGroupRepository(): void
{
$this->app->bind(
TransactionGroupRepositoryInterface::class,
@ -129,4 +135,23 @@ class JournalServiceProvider extends ServiceProvider
}
);
}
/**
* Register sum collector.
*/
private function registerSumCollector(): void
{
$this->app->bind(
GroupSumCollectorInterface::class,
function (Application $app) {
/** @var GroupSumCollector $collector */
$collector = app(GroupSumCollector::class);
if ($app->auth->check()) {
$collector->setUser(auth()->user());
}
return $collector;
}
);
}
}

View File

@ -24,7 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Support\Http\Controllers;
use Carbon\Carbon;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupSumCollectorInterface;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\Account;
@ -74,6 +75,7 @@ trait PeriodOverview
*/
protected function getAccountPeriodOverview(Account $account, Carbon $date): Collection
{
throw new FireflyException('Is using collector.');
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$range = app('preferences')->get('viewRange', '1M')->data;
@ -141,6 +143,7 @@ trait PeriodOverview
*/
protected function getCategoryPeriodOverview(Category $category, Carbon $date): Collection
{
throw new FireflyException('Is using collector.');
/** @var JournalRepositoryInterface $journalRepository */
$journalRepository = app(JournalRepositoryInterface::class);
$range = app('preferences')->get('viewRange', '1M')->data;
@ -211,6 +214,7 @@ trait PeriodOverview
*/
protected function getNoBudgetPeriodOverview(Carbon $date): Collection
{
throw new FireflyException('Is using collector.');
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$first = $repository->firstNull();
@ -272,6 +276,7 @@ trait PeriodOverview
*/
protected function getNoCategoryPeriodOverview(Carbon $theDate): Collection // period overview method.
{
throw new FireflyException('Is using collector.');
Log::debug(sprintf('Now in getNoCategoryPeriodOverview(%s)', $theDate->format('Y-m-d')));
$range = app('preferences')->get('viewRange', '1M')->data;
$first = $this->journalRepos->firstNull();
@ -360,6 +365,7 @@ trait PeriodOverview
*/
protected function getTagPeriodOverview(Tag $tag, Carbon $date): Collection // period overview for tags.
{
throw new FireflyException('Is using collector.');
/** @var TagRepositoryInterface $repository */
$repository = app(TagRepositoryInterface::class);
$range = app('preferences')->get('viewRange', '1M')->data;
@ -415,69 +421,63 @@ trait PeriodOverview
}
/**
* This list shows the overview of a type of transaction, for the period blocks on the list of transactions.
*
* @param string $what
* @param Carbon $date
* @param string $transactionType
* @param Carbon $endDate
*
* @return Collection
* @throws \Exception
*/
protected function getTransactionPeriodOverview(string $what, Carbon $date): Collection // period overview for transactions.
protected function getTransactionPeriodOverview(string $transactionType, Carbon $endDate): Collection
{
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$range = app('preferences')->get('viewRange', '1M')->data;
$endJournal = $repository->firstNull();
$end = null === $endJournal ? new Carbon : $endJournal->date;
$start = clone $date;
$types = config('firefly.transactionTypesByWhat.' . $what);
$start = clone $endDate;
$types = config('firefly.transactionTypesByType.' . $transactionType);
if ($end < $start) {
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
}
// properties for entries with their amounts.
$cache = new CacheProperties;
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('transactions-period-entries');
$cache->addProperty($what);
/** @var array $dates */
$dates = app('navigation')->blockPeriods($start, $end, $range);
$entries = new Collection;
foreach ($dates as $currentDate) {
// get all expenses, income or transfers:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($currentDate['start'], $currentDate['end'])->withAccountInformation()->setTypes($types);
$journals = $collector->getExtractedJournals();
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
$grouped = $this->groupByCurrency($journals);
$spent = [];
$earned = [];
$transferred = [];
if ('expenses' === $what || 'withdrawal' === $what) {
$spent = $grouped;
/** @var GroupSumCollectorInterface $sumCollector */
$sumCollector = app(GroupSumCollectorInterface::class);
$sumCollector->setTypes($types)->setRange($currentDate['start'], $currentDate['end']);
$amounts = $sumCollector->getSum();
$spent = [];
$earned = [];
$transferred = [];
// set to correct array
if ('expenses' === $transactionType || 'withdrawal' === $transactionType) {
$spent = $amounts;
}
if ('revenue' === $what || 'deposit' === $what) {
$earned = $grouped;
if ('revenue' === $transactionType || 'deposit' === $transactionType) {
$earned = $amounts;
}
if ('transfer' === $what || 'transfers' === $what) {
$transferred = $grouped;
if ('transfer' === $transactionType || 'transfers' === $transactionType) {
$transferred = $amounts;
}
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
$entries->push(
[
'transactions' => count($journals),
'transactions' => $amounts['count'],
'title' => $title,
'spent' => $spent,
'earned' => $earned,
'transferred' => $transferred,
'route' => route('transactions.index', [$what, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
'route' => route(
'transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
),
]
);
}

120
composer.lock generated
View File

@ -1309,16 +1309,16 @@
},
{
"name": "laravel/framework",
"version": "v5.8.11",
"version": "v5.8.12",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "a2cf7a7983329d63edc6fde43142b232bb61aa0a"
"reference": "6dd75b67811a265c57144ab15f25a8061ed4721f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/a2cf7a7983329d63edc6fde43142b232bb61aa0a",
"reference": "a2cf7a7983329d63edc6fde43142b232bb61aa0a",
"url": "https://api.github.com/repos/laravel/framework/zipball/6dd75b67811a265c57144ab15f25a8061ed4721f",
"reference": "6dd75b67811a265c57144ab15f25a8061ed4721f",
"shasum": ""
},
"require": {
@ -1452,7 +1452,7 @@
"framework",
"laravel"
],
"time": "2019-04-10T13:05:18+00:00"
"time": "2019-04-16T13:47:32+00:00"
},
{
"name": "laravel/passport",
@ -3305,16 +3305,16 @@
},
{
"name": "symfony/console",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "24206aff3efe6962593297e57ef697ebb220e384"
"reference": "e2840bb38bddad7a0feaf85931e38fdcffdb2f81"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/24206aff3efe6962593297e57ef697ebb220e384",
"reference": "24206aff3efe6962593297e57ef697ebb220e384",
"url": "https://api.github.com/repos/symfony/console/zipball/e2840bb38bddad7a0feaf85931e38fdcffdb2f81",
"reference": "e2840bb38bddad7a0feaf85931e38fdcffdb2f81",
"shasum": ""
},
"require": {
@ -3373,7 +3373,7 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2019-04-01T07:32:59+00:00"
"time": "2019-04-08T14:23:48+00:00"
},
{
"name": "symfony/contracts",
@ -3445,7 +3445,7 @@
},
{
"name": "symfony/css-selector",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
@ -3498,16 +3498,16 @@
},
{
"name": "symfony/debug",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "43ce8ab34c734dcc8a4af576cb86711daab964c5"
"reference": "2d279b6bb1d582dd5740d4d3251ae8c18812ed37"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/43ce8ab34c734dcc8a4af576cb86711daab964c5",
"reference": "43ce8ab34c734dcc8a4af576cb86711daab964c5",
"url": "https://api.github.com/repos/symfony/debug/zipball/2d279b6bb1d582dd5740d4d3251ae8c18812ed37",
"reference": "2d279b6bb1d582dd5740d4d3251ae8c18812ed37",
"shasum": ""
},
"require": {
@ -3550,20 +3550,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2019-03-10T17:09:50+00:00"
"time": "2019-04-11T11:27:41+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544"
"reference": "fbce53cd74ac509cbe74b6f227622650ab759b02"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544",
"reference": "ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/fbce53cd74ac509cbe74b6f227622650ab759b02",
"reference": "fbce53cd74ac509cbe74b6f227622650ab759b02",
"shasum": ""
},
"require": {
@ -3614,20 +3614,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2019-03-30T15:58:42+00:00"
"time": "2019-04-06T13:51:08+00:00"
},
{
"name": "symfony/finder",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "267b7002c1b70ea80db0833c3afe05f0fbde580a"
"reference": "e45135658bd6c14b61850bf131c4f09a55133f69"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/267b7002c1b70ea80db0833c3afe05f0fbde580a",
"reference": "267b7002c1b70ea80db0833c3afe05f0fbde580a",
"url": "https://api.github.com/repos/symfony/finder/zipball/e45135658bd6c14b61850bf131c4f09a55133f69",
"reference": "e45135658bd6c14b61850bf131c4f09a55133f69",
"shasum": ""
},
"require": {
@ -3663,11 +3663,11 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2019-02-23T15:42:05+00:00"
"time": "2019-04-06T13:51:08+00:00"
},
{
"name": "symfony/http-foundation",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
@ -3721,16 +3721,16 @@
},
{
"name": "symfony/http-kernel",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "e8b940bbeebf0f96789b5d17d9d77f8b2613960b"
"reference": "72f5f8f9dd6e6fbda0220ded537610ad20fa2ce8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/e8b940bbeebf0f96789b5d17d9d77f8b2613960b",
"reference": "e8b940bbeebf0f96789b5d17d9d77f8b2613960b",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/72f5f8f9dd6e6fbda0220ded537610ad20fa2ce8",
"reference": "72f5f8f9dd6e6fbda0220ded537610ad20fa2ce8",
"shasum": ""
},
"require": {
@ -3806,7 +3806,7 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
"time": "2019-04-02T19:03:51+00:00"
"time": "2019-04-16T07:20:25+00:00"
},
{
"name": "symfony/polyfill-ctype",
@ -4211,16 +4211,16 @@
},
{
"name": "symfony/process",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "1e6cbb41dadcaf29e0db034d6ad0d039a9df06e6"
"reference": "8cf39fb4ccff793340c258ee7760fd40bfe745fe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/1e6cbb41dadcaf29e0db034d6ad0d039a9df06e6",
"reference": "1e6cbb41dadcaf29e0db034d6ad0d039a9df06e6",
"url": "https://api.github.com/repos/symfony/process/zipball/8cf39fb4ccff793340c258ee7760fd40bfe745fe",
"reference": "8cf39fb4ccff793340c258ee7760fd40bfe745fe",
"shasum": ""
},
"require": {
@ -4256,7 +4256,7 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2019-03-10T20:07:02+00:00"
"time": "2019-04-10T16:20:36+00:00"
},
{
"name": "symfony/psr-http-message-bridge",
@ -4325,16 +4325,16 @@
},
{
"name": "symfony/routing",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
"reference": "319f600c1ea0f981f6bdc2f042cfc1690957c0e0"
"reference": "b9f16550d76897ab0a86c198f8008c6578a5068f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/319f600c1ea0f981f6bdc2f042cfc1690957c0e0",
"reference": "319f600c1ea0f981f6bdc2f042cfc1690957c0e0",
"url": "https://api.github.com/repos/symfony/routing/zipball/b9f16550d76897ab0a86c198f8008c6578a5068f",
"reference": "b9f16550d76897ab0a86c198f8008c6578a5068f",
"shasum": ""
},
"require": {
@ -4397,20 +4397,20 @@
"uri",
"url"
],
"time": "2019-03-30T15:58:42+00:00"
"time": "2019-04-03T13:26:22+00:00"
},
{
"name": "symfony/translation",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "e46933cc31b68f51f7fc5470fb55550407520f56"
"reference": "46c0dede1f925383d13dc783857be2c41efd0b24"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/e46933cc31b68f51f7fc5470fb55550407520f56",
"reference": "e46933cc31b68f51f7fc5470fb55550407520f56",
"url": "https://api.github.com/repos/symfony/translation/zipball/46c0dede1f925383d13dc783857be2c41efd0b24",
"reference": "46c0dede1f925383d13dc783857be2c41efd0b24",
"shasum": ""
},
"require": {
@ -4432,7 +4432,9 @@
"symfony/console": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/finder": "~2.8|~3.0|~4.0",
"symfony/http-kernel": "~3.4|~4.0",
"symfony/intl": "~3.4|~4.0",
"symfony/var-dumper": "~3.4|~4.0",
"symfony/yaml": "~3.4|~4.0"
},
"suggest": {
@ -4470,20 +4472,20 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
"time": "2019-04-01T14:13:08+00:00"
"time": "2019-04-10T16:20:36+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "9f87189ac10b42edf7fb8edc846f1937c6d157cf"
"reference": "f42850fa32b8d7a35a75510810f6ef597674be74"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/9f87189ac10b42edf7fb8edc846f1937c6d157cf",
"reference": "9f87189ac10b42edf7fb8edc846f1937c6d157cf",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/f42850fa32b8d7a35a75510810f6ef597674be74",
"reference": "f42850fa32b8d7a35a75510810f6ef597674be74",
"shasum": ""
},
"require": {
@ -4546,7 +4548,7 @@
"debug",
"dump"
],
"time": "2019-02-23T15:17:42+00:00"
"time": "2019-04-11T11:27:41+00:00"
},
{
"name": "tightenco/collect",
@ -4647,16 +4649,16 @@
},
{
"name": "twig/twig",
"version": "v1.38.4",
"version": "v1.39.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "7732e9e7017d751313811bd118de61302e9c8b35"
"reference": "44890db076c3f0db2bb627a81b246b617bd2413a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/7732e9e7017d751313811bd118de61302e9c8b35",
"reference": "7732e9e7017d751313811bd118de61302e9c8b35",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/44890db076c3f0db2bb627a81b246b617bd2413a",
"reference": "44890db076c3f0db2bb627a81b246b617bd2413a",
"shasum": ""
},
"require": {
@ -4671,7 +4673,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.38-dev"
"dev-master": "1.39-dev"
}
},
"autoload": {
@ -4709,7 +4711,7 @@
"keywords": [
"templating"
],
"time": "2019-03-23T14:27:19+00:00"
"time": "2019-04-16T12:35:10+00:00"
},
{
"name": "vlucas/phpdotenv",
@ -7218,7 +7220,7 @@
},
{
"name": "symfony/filesystem",
"version": "v4.2.5",
"version": "v4.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",

View File

@ -337,6 +337,14 @@ return [
'transfer' => ['Transfer'],
'transfers' => ['Transfer'],
],
'transactionTypesByType' => [
'expenses' => ['Withdrawal'],
'withdrawal' => ['Withdrawal'],
'revenue' => ['Deposit'],
'deposit' => ['Deposit'],
'transfer' => ['Transfer'],
'transfers' => ['Transfer'],
],
'transactionTypesToShort' => [
'Withdrawal' => 'withdrawal',
'Deposit' => 'deposit',

View File

@ -12,29 +12,31 @@
<td style="text-align: right;">{{ period.transactions }}</td>
</tr>
{% endif %}
{% for arr in period.spent %}
{% if arr.amount !=0 %}
{# loop all spent amounts #}
{% for array in period.spent.sums %}
{# actually spent anything: #}
{% if array.sum !=0 %}
<tr>
<td style="width:33%;">{{ 'spent'|_ }}</td>
<td style="text-align: right;">{{ formatAmountByCurrency(arr.currency, arr.amount) }}</td>
<td style="text-align: right;">{{ formatAmountBySymbol(array.sum * -1, array.currency_symbol, array.currency_decimal_places) }}</td>
</tr>
{% endif %}
{% endfor %}
{% for arr in period.earned %}
{% if arr.amount !=0 %}
{% for array in period.earned.sums %}
{% if array.sum !=0 %}
<tr>
<td style="width:33%;">{{ 'earned'|_ }}</td>
<td style="text-align: right;">{{ formatAmountByCurrency(arr.currency, arr.amount) }}</td>
<td style="text-align: right;">{{ formatAmountBySymbol(array.sum, array.currency_symbol, array.currency_decimal_places) }}</td>
</tr>
{% endif %}
{% endfor %}
{% for arr in period.transferred %}
{% if arr.amount !=0 %}
{% for array in period.transferred.sums %}
{% if array.sum !=0 %}
<tr>
<td style="width:33%;">{{ 'transferred'|_ }}</td>
<td style="text-align: right;"><span class="text-info">{{ formatAmountByCurrency(arr.currency, arr.amount, false) }}</span></td>
<td style="text-align: right;"><span class="text-info">{{ formatAmountBySymbol(array.sum, array.currency_symbol, array.currency_decimal_places, false) }}</span></td>
</tr>
{% endif %}
{% endfor %}

View File

@ -1,7 +1,7 @@
{% extends "./layout/default" %}
{% block breadcrumbs %}
{{ Breadcrumbs.render(Route.getCurrentRoute.getName, what, start, end) }}
{{ Breadcrumbs.render(Route.getCurrentRoute.getName, transactionType, start, end) }}
{% endblock %}
{% block content %}
@ -10,7 +10,7 @@
{% 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.all',[what]) }}">{{ 'showEverything'|_ }}</a></p>
<p class="small text-center"><a href="{{ route('transactions.index.all',[transactionType]) }}">{{ 'showEverything'|_ }}</a></p>
</div>
</div>
{% endif %}
@ -24,10 +24,10 @@
</div>
<div class="box-body no-padding">
<div style="padding:8px;">
{% if what == 'transfers' %}
<a href="{{ route('transactions.create', 'transfer') }}" class="btn btn-success"><i class="fa fa-plus fa-fw"></i> {{ ('new_' ~ what)|_ }}</a>
{% if transactionType == 'transfers' %}
<a href="{{ route('transactions.create', 'transfer') }}" class="btn btn-success"><i class="fa fa-plus fa-fw"></i> {{ ('new_' ~ transactionType)|_ }}</a>
{% else %}
<a href="{{ route('transactions.create', what) }}" class="btn btn-success"><i class="fa fa-plus fa-fw"></i> {{ ('new_' ~ what)|_ }}</a>
<a href="{{ route('transactions.create', transactionType) }}" class="btn btn-success"><i class="fa fa-plus fa-fw"></i> {{ ('new_' ~ transactionType)|_ }}</a>
{% endif %}
</div>
{# actual list #}
@ -38,12 +38,12 @@
{% if periods.count > 0 %}
<p>
<i class="fa fa-calendar"></i>
<a href="{{ route('transactions.index.all', [what]) }}">{{ 'show_all_no_filter'|_ }}</a>
<a href="{{ route('transactions.index.all', [transactionType]) }}">{{ 'show_all_no_filter'|_ }}</a>
</p>
{% else %}
<p>
<i class="fa fa-calendar"></i>
<a href="{{ route('transactions.index', [what]) }}">{{ 'show_the_current_period_and_overview'|_ }}</a>
<a href="{{ route('transactions.index', [transactionType]) }}">{{ 'show_the_current_period_and_overview'|_ }}</a>
</p>
{% endif %}
</div>
@ -63,7 +63,7 @@
{% 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.all',[what]) }}">{{ 'showEverything'|_ }}</a></p>
<p class="small text-center"><a href="{{ route('transactions.index.all',[transactionType]) }}">{{ 'showEverything'|_ }}</a></p>
</div>
</div>
{% endif %}

View File

@ -5,7 +5,7 @@
{% endblock %}
{% block content %}
<form method="POST" action="{{ route('transactions.store',what) }}" accept-charset="UTF-8" class="form-horizontal" id="store" enctype="multipart/form-data">
<form method="POST" action="{{ route('transactions.store') }}" accept-charset="UTF-8" class="form-horizontal" id="store" enctype="multipart/form-data">
<input name="_token" type="hidden" value="{{ csrf_token() }}">
<input type="hidden" name="what" value="{{ what }}"/>

View File

@ -873,12 +873,17 @@ Route::group(
Route::group(
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'transactions', 'as' => 'transactions.'], function () {
// TODO improve these routes
Route::get('{what}/all', ['uses' => 'TransactionController@indexAll', 'as' => 'index.all'])->where(['what' => 'withdrawal|deposit|transfers|transfer']);
Route::get('{what}/{start_date?}/{end_date?}', ['uses' => 'TransactionController@index', 'as' => 'index'])->where(
Route::get('{what}/{start_date?}/{end_date?}', ['uses' => 'Transaction\IndexController@index', 'as' => 'index'])->where(
['what' => 'withdrawal|deposit|transfers|transfer']
);
// TODO improve these routes
Route::get('{what}/all', ['uses' => 'TransactionController@indexAll', 'as' => 'index.all'])->where(['what' => 'withdrawal|deposit|transfers|transfer']);
Route::get('debug/{tj}', ['uses' => 'Transaction\SingleController@debugShow', 'as' => 'debug']);
Route::get('debug/{tj}', ['uses' => 'Transaction\SingleController@debugShow', 'as' => 'debug']);
@ -901,7 +906,7 @@ Route::group(
Route::get('create/{what}', ['uses' => 'SingleController@create', 'as' => 'create'])->where(['what' => 'withdrawal|deposit|transfer']);
Route::get('edit/{tj}', ['uses' => 'SingleController@edit', 'as' => 'edit']);
Route::get('delete/{tj}', ['uses' => 'SingleController@delete', 'as' => 'delete']);
Route::post('store/{what}', ['uses' => 'SingleController@store', 'as' => 'store'])->where(['what' => 'withdrawal|deposit|transfer']);
Route::post('store', ['uses' => 'SingleController@store', 'as' => 'store'])->where(['what' => 'withdrawal|deposit|transfer']);
Route::post('update/{tj}', ['uses' => 'SingleController@update', 'as' => 'update']);
Route::post('destroy/{tj}', ['uses' => 'SingleController@destroy', 'as' => 'destroy']);
Route::get('clone/{tj}', ['uses' => 'SingleController@cloneTransaction', 'as' => 'clone']);