diff --git a/app/Helpers/Collector/GroupSumCollector.php b/app/Helpers/Collector/GroupSumCollector.php new file mode 100644 index 0000000000..65b6085e5b --- /dev/null +++ b/app/Helpers/Collector/GroupSumCollector.php @@ -0,0 +1,195 @@ +. + */ + +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; + } +} \ No newline at end of file diff --git a/app/Helpers/Collector/GroupSumCollectorInterface.php b/app/Helpers/Collector/GroupSumCollectorInterface.php new file mode 100644 index 0000000000..8e41d7a635 --- /dev/null +++ b/app/Helpers/Collector/GroupSumCollectorInterface.php @@ -0,0 +1,73 @@ +. + */ + +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; +} \ No newline at end of file diff --git a/app/Http/Controllers/Transaction/CreateController.php b/app/Http/Controllers/Transaction/CreateController.php new file mode 100644 index 0000000000..0b635372a5 --- /dev/null +++ b/app/Http/Controllers/Transaction/CreateController.php @@ -0,0 +1,35 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Http\Controllers\Transaction; + + +use FireflyIII\Http\Controllers\Controller; + +/** + * Class CreateController + */ +class CreateController extends Controller +{ + +} \ No newline at end of file diff --git a/app/Http/Controllers/Transaction/IndexController.php b/app/Http/Controllers/Transaction/IndexController.php new file mode 100644 index 0000000000..03180bc831 --- /dev/null +++ b/app/Http/Controllers/Transaction/IndexController.php @@ -0,0 +1,91 @@ +. + */ + +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')); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Transaction/SingleController.php b/app/Http/Controllers/Transaction/SingleController.php index fd120cd33d..7724e628a0 100644 --- a/app/Http/Controllers/Transaction/SingleController.php +++ b/app/Http/Controllers/Transaction/SingleController.php @@ -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')); diff --git a/app/Http/Controllers/Transaction/SplitController.php b/app/Http/Controllers/Transaction/SplitController.php index d173d3f24e..37d6fbabc6 100644 --- a/app/Http/Controllers/Transaction/SplitController.php +++ b/app/Http/Controllers/Transaction/SplitController.php @@ -61,6 +61,7 @@ class SplitController extends Controller */ public function __construct() { + throw new FireflyException('Do not use me.'); parent::__construct(); // some useful repositories: diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 68350d0fe3..548ebb69d1 100644 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -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'); diff --git a/app/Providers/JournalServiceProvider.php b/app/Providers/JournalServiceProvider.php index 9340ce2a96..ce3cea775a 100644 --- a/app/Providers/JournalServiceProvider.php +++ b/app/Providers/JournalServiceProvider.php @@ -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; + } + ); + } } diff --git a/app/Support/Http/Controllers/PeriodOverview.php b/app/Support/Http/Controllers/PeriodOverview.php index f8910867d2..ef11025cc3 100644 --- a/app/Support/Http/Controllers/PeriodOverview.php +++ b/app/Support/Http/Controllers/PeriodOverview.php @@ -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')] + ), ] ); } diff --git a/composer.lock b/composer.lock index 2087eb1038..6e7d4fa53e 100644 --- a/composer.lock +++ b/composer.lock @@ -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", diff --git a/config/firefly.php b/config/firefly.php index 1980ca7b82..75e73a34d1 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -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', diff --git a/resources/views/v1/list/periods.twig b/resources/views/v1/list/periods.twig index ac6bcb0dc7..c9e5bcd6bd 100644 --- a/resources/views/v1/list/periods.twig +++ b/resources/views/v1/list/periods.twig @@ -12,29 +12,31 @@ {{ period.transactions }} {% 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 %} {{ 'spent'|_ }} - {{ formatAmountByCurrency(arr.currency, arr.amount) }} + {{ formatAmountBySymbol(array.sum * -1, array.currency_symbol, array.currency_decimal_places) }} {% endif %} {% endfor %} - {% for arr in period.earned %} - {% if arr.amount !=0 %} + {% for array in period.earned.sums %} + {% if array.sum !=0 %} {{ 'earned'|_ }} - {{ formatAmountByCurrency(arr.currency, arr.amount) }} + {{ formatAmountBySymbol(array.sum, array.currency_symbol, array.currency_decimal_places) }} {% endif %} {% endfor %} - {% for arr in period.transferred %} - {% if arr.amount !=0 %} + {% for array in period.transferred.sums %} + {% if array.sum !=0 %} {{ 'transferred'|_ }} - {{ formatAmountByCurrency(arr.currency, arr.amount, false) }} + {{ formatAmountBySymbol(array.sum, array.currency_symbol, array.currency_decimal_places, false) }} {% endif %} {% endfor %} diff --git a/resources/views/v1/transactions/index.twig b/resources/views/v1/transactions/index.twig index 3d24800fd5..5a35f687ba 100644 --- a/resources/views/v1/transactions/index.twig +++ b/resources/views/v1/transactions/index.twig @@ -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 %}
-

{{ 'showEverything'|_ }}

+

{{ 'showEverything'|_ }}

{% endif %} @@ -24,10 +24,10 @@
- {% if what == 'transfers' %} - {{ ('new_' ~ what)|_ }} + {% if transactionType == 'transfers' %} + {{ ('new_' ~ transactionType)|_ }} {% else %} - {{ ('new_' ~ what)|_ }} + {{ ('new_' ~ transactionType)|_ }} {% endif %}
{# actual list #} @@ -38,12 +38,12 @@ {% if periods.count > 0 %}

- {{ 'show_all_no_filter'|_ }} + {{ 'show_all_no_filter'|_ }}

{% else %}

- {{ 'show_the_current_period_and_overview'|_ }} + {{ 'show_the_current_period_and_overview'|_ }}

{% endif %}
@@ -63,7 +63,7 @@ {% if periods.count > 0 %}
-

{{ 'showEverything'|_ }}

+

{{ 'showEverything'|_ }}

{% endif %} diff --git a/resources/views/v1/transactions/single/create.twig b/resources/views/v1/transactions/single/create.twig index ff3053edb2..d8723699fb 100644 --- a/resources/views/v1/transactions/single/create.twig +++ b/resources/views/v1/transactions/single/create.twig @@ -5,7 +5,7 @@ {% endblock %} {% block content %} -
+ diff --git a/routes/web.php b/routes/web.php index 20471b4953..60692280ba 100644 --- a/routes/web.php +++ b/routes/web.php @@ -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']);