Merge branch 'release/4.4.0'

This commit is contained in:
James Cole 2017-04-23 19:07:19 +02:00
commit 5aa7ab5e37
517 changed files with 3682 additions and 1763 deletions

View File

@ -41,6 +41,8 @@ SHOW_INCOMPLETE_TRANSLATIONS=false
CACHE_PREFIX=firefly
EXCHANGE_RATE_SERVICE=fixerio
GOOGLE_MAPS_API_KEY=
ANALYTICS_ID=
SITE_OWNER=mail@example.com

View File

@ -2,7 +2,15 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [4.4.0] - 2017-04-23
### Added
- Firefly III can now handle foreign currencies better, including some code to get the exchange rate live from the web.
- Can now make rules for attachments, see #608, as suggested by dzaikos.
### Fixed
- Fixed #629, reported by forcaeluz
- Fixed #630, reported by welbert
- And more various bug fixes.
## [4.3.8] - 2017-04-08
@ -203,13 +211,6 @@ An intermediate release because something in the Twig and Twigbridge libraries i
- Updated all email messages.
- Made some fonts local
### Deprecated
- Initial release.
### Removed
- Initial release.
### Fixed
- Issue #408
- Various issues with split journals
@ -218,11 +219,6 @@ An intermediate release because something in the Twig and Twigbridge libraries i
- Issue #422, thx [xzaz](https://github.com/xzaz)
- Various import bugs, such as #416 ([zjean](https://github.com/zjean))
### Security
- Initial release.
## [4.1.7] - 2016-11-19
### Added
- Check for database table presence in console commands.
@ -345,15 +341,6 @@ An intermediate release because something in the Twig and Twigbridge libraries i
- New Presidents Choice specific to fix #307
- Added some trimming (#335)
### Changed
- Initial release.
### Deprecated
- Initial release.
### Removed
- Initial release.
### Fixed
- Fixed a bug where incoming transactions would not be properly filtered in several reports.
- #334 by [cyberkov](https://github.com/cyberkov)
@ -361,12 +348,6 @@ An intermediate release because something in the Twig and Twigbridge libraries i
- #336
- #338 found by [roberthorlings](https://github.com/roberthorlings)
### Security
- Initial release.
## [4.0.0] - 2015-09-26
### Added
- Upgraded to Laravel 5.3, most other libraries upgraded as well.

View File

@ -1,63 +0,0 @@
<?php
/**
* ConfigureLogging.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Bootstrap;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Bootstrap\ConfigureLogging as IlluminateConfigureLogging;
use Illuminate\Log\Writer;
/**
* Class ConfigureLogging
*
* @package FireflyIII\Bootstrap
*/
class ConfigureLogging extends IlluminateConfigureLogging
{
/**
* Configure the Monolog handlers for the application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param \Illuminate\Log\Writer $log
*
* @return void
*/
protected function configureDailyHandler(Application $app, Writer $log)
{
$config = $app->make('config');
$maxFiles = $config->get('app.log_max_files');
$log->useDailyFiles(
$app->storagePath() . '/logs/firefly-iii.log', is_null($maxFiles) ? 5 : $maxFiles,
$config->get('app.log_level', 'debug')
);
}
/**
* Configure the Monolog handlers for the application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param \Illuminate\Log\Writer $log
*
* @return void
*/
protected function configureSingleHandler(Application $app, Writer $log)
{
$log->useFiles(
$app->storagePath() . '/logs/firefly-iii.log',
$app->make('config')->get('app.log_level', 'debug')
);
}
}

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Console\Commands;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Console\Commands;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Console\Commands;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Console\Commands;

View File

@ -15,15 +15,22 @@ namespace FireflyIII\Console\Commands;
use DB;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\LimitRepetition;
use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Database\QueryException;
use Log;
use Preferences;
use Schema;
/**
@ -63,8 +70,14 @@ class UpgradeDatabase extends Command
$this->setTransactionIdentifier();
$this->migrateRepetitions();
$this->repairPiggyBanks();
$this->updateAccountCurrencies();
$this->updateJournalCurrencies();
$this->info('Firefly III database is up to date.');
}
/**
* Migrate budget repetitions to new format.
*/
private function migrateRepetitions()
{
if (!Schema::hasTable('budget_limits')) {
@ -102,18 +115,20 @@ class UpgradeDatabase extends Command
/** @var PiggyBankEvent $event */
foreach ($set as $event) {
if (!is_null($event->transaction_journal_id)) {
$type = $event->transactionJournal->transactionType->type;
if ($type !== TransactionType::TRANSFER) {
$event->transaction_journal_id = null;
$event->save();
$this->line(
sprintf('Piggy bank #%d ("%s") was referenced by an invalid event. This has been fixed.', $event->piggy_bank_id,
$event->piggyBank->name
));
}
if (is_null($event->transaction_journal_id)) {
continue;
}
/** @var TransactionJournal $journal */
$journal = $event->transactionJournal()->first();
if (is_null($journal)) {
continue;
}
$type = $journal->transactionType->type;
if ($type !== TransactionType::TRANSFER) {
$event->transaction_journal_id = null;
$event->save();
$this->line(sprintf('Piggy bank #%d was referenced by an invalid event. This has been fixed.', $event->piggy_bank_id));
}
}
}
@ -146,6 +161,57 @@ class UpgradeDatabase extends Command
}
}
/**
*
*/
private function updateAccountCurrencies()
{
$accounts = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
->whereIn('account_types.type', [AccountType::DEFAULT, AccountType::ASSET])->get(['accounts.*']);
/** @var Account $account */
foreach ($accounts as $account) {
// get users preference, fall back to system pref.
$defaultCurrencyCode = Preferences::getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data;
$defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first();
$accountCurrency = intval($account->getMeta('currency_id'));
$openingBalance = $account->getOpeningBalance();
$openingBalanceCurrency = intval($openingBalance->transaction_currency_id);
// both 0? set to default currency:
if ($accountCurrency === 0 && $openingBalanceCurrency === 0) {
AccountMeta::create(['account_id' => $account->id, 'name' => 'currency_id', 'data' => $defaultCurrency->id]);
$this->line(sprintf('Account #%d ("%s") now has a currency setting (%s).', $account->id, $account->name, $defaultCurrencyCode));
continue;
}
// opening balance 0, account not zero? just continue:
if ($accountCurrency > 0 && $openingBalanceCurrency === 0) {
continue;
}
// account is set to 0, opening balance is not?
if ($accountCurrency === 0 && $openingBalanceCurrency > 0) {
AccountMeta::create(['account_id' => $account->id, 'name' => 'currency_id', 'data' => $openingBalanceCurrency]);
$this->line(sprintf('Account #%d ("%s") now has a currency setting (%s).', $account->id, $account->name, $defaultCurrencyCode));
continue;
}
// both are equal, just continue:
if ($accountCurrency === $openingBalanceCurrency) {
continue;
}
// do not match:
if ($accountCurrency !== $openingBalanceCurrency) {
// update opening balance:
$openingBalance->transaction_currency_id = $accountCurrency;
$openingBalance->save();
$this->line(sprintf('Account #%d ("%s") now has a correct currency for opening balance.', $account->id, $account->name));
continue;
}
}
}
/**
* grab all positive transactiosn from this journal that are not deleted. for each one, grab the negative opposing one
* which has 0 as an identifier and give it the same identifier.
@ -189,4 +255,83 @@ class UpgradeDatabase extends Command
$identifier++;
}
}
/**
* Makes sure that withdrawals, deposits and transfers have
* a currency setting matching their respective accounts
*/
private function updateJournalCurrencies()
{
$types = [
TransactionType::WITHDRAWAL => '<',
TransactionType::DEPOSIT => '>',
];
$repository = app(CurrencyRepositoryInterface::class);
$notification = '%s #%d uses %s but should use %s. It has been updated. Please verify this in Firefly III.';
$transfer = 'Transfer #%d has been updated to use the correct currencies. Please verify this in Firefly III.';
foreach ($types as $type => $operator) {
$set = TransactionJournal
::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')->leftJoin(
'transactions', function (JoinClause $join) use ($operator) {
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', $operator, '0');
}
)
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id')
->where('transaction_types.type', $type)
->where('account_meta.name', 'currency_id')
->where('transaction_journals.transaction_currency_id', '!=', DB::raw('account_meta.data'))
->get(['transaction_journals.*', 'account_meta.data as expected_currency_id', 'transactions.amount as transaction_amount']);
/** @var TransactionJournal $journal */
foreach ($set as $journal) {
$expectedCurrency = $repository->find(intval($journal->expected_currency_id));
$line = sprintf($notification, $type, $journal->id, $journal->transactionCurrency->code, $expectedCurrency->code);
$journal->setMeta('foreign_amount', $journal->transaction_amount);
$journal->setMeta('foreign_currency_id', $journal->transaction_currency_id);
$journal->transaction_currency_id = $expectedCurrency->id;
$journal->save();
$this->line($line);
}
}
/*
* For transfers it's slightly different. Both source and destination
* must match the respective currency preference. So we must verify ALL
* transactions.
*/
$set = TransactionJournal
::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->where('transaction_types.type', TransactionType::TRANSFER)
->get(['transaction_journals.*']);
/** @var TransactionJournal $journal */
foreach ($set as $journal) {
$updated = false;
/** @var Transaction $sourceTransaction */
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
$sourceCurrency = $repository->find(intval($sourceTransaction->account->getMeta('currency_id')));
if ($sourceCurrency->id !== $journal->transaction_currency_id) {
$updated = true;
$journal->transaction_currency_id = $sourceCurrency->id;
$journal->save();
}
// destination
$destinationTransaction = $journal->transactions()->where('amount', '>', 0)->first();
$destinationCurrency = $repository->find(intval($destinationTransaction->account->getMeta('currency_id')));
if ($destinationCurrency->id !== $journal->transaction_currency_id) {
$updated = true;
$journal->deleteMeta('foreign_amount');
$journal->deleteMeta('foreign_currency_id');
$journal->setMeta('foreign_amount', $destinationTransaction->amount);
$journal->setMeta('foreign_currency_id', $destinationCurrency->id);
}
if ($updated) {
$line = sprintf($transfer, $journal->id);
$this->line($line);
}
}
}
}

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Console\Commands;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Console\Commands;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Console;
@ -41,7 +41,6 @@ class Kernel extends ConsoleKernel
= [
'Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables',
'Illuminate\Foundation\Bootstrap\LoadConfiguration',
//'FireflyIII\Bootstrap\ConfigureLogging',
'Illuminate\Foundation\Bootstrap\HandleExceptions',
'Illuminate\Foundation\Bootstrap\RegisterFacades',
'Illuminate\Foundation\Bootstrap\SetRequestForConsole',

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Events;
/**

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Events;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Events;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Events;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Events;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Exceptions;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Exceptions;
use ErrorException;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Exceptions;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Exceptions;
/**

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export\Collector;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export\Collector;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export\Collector;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export\Collector;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export\Collector;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export\Entry;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export\Exporter;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export\Exporter;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export\Exporter;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Export;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Chart\Basic;
@ -81,6 +81,9 @@ class ChartJsGenerator implements GeneratorInterface
if (isset($set['fill'])) {
$currentSet['fill'] = $set['fill'];
}
if (isset($set['currency_symbol'])) {
$currentSet['currency_symbol'] = $set['currency_symbol'];
}
$chartData['datasets'][] = $currentSet;
}
@ -105,6 +108,10 @@ class ChartJsGenerator implements GeneratorInterface
],
'labels' => [],
];
// sort by value, keep keys.
asort($data);
$index = 0;
foreach ($data as $key => $value) {

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Chart\Basic;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Audit;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Audit;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Audit;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Budget;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Budget;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Budget;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Category;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Category;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Category;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Standard;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Standard;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Standard;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report;

View File

@ -7,7 +7,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Tag;

View File

@ -7,7 +7,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Tag;

View File

@ -7,7 +7,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Generator\Report\Tag;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Handlers\Events;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Handlers\Events;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Handlers\Events;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Attachments;
use Crypt;

View File

@ -7,7 +7,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Chart;

View File

@ -7,7 +7,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Chart;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use Illuminate\Support\Collection;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Account as AccountModel;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Account as AccountModel;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use Carbon\Carbon;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use Carbon\Carbon;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Category as CategoryModel;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Collector;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Collector;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers;

View File

@ -9,7 +9,8 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Help;
/**

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Report;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Report;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Report;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Report;

View File

@ -28,6 +28,37 @@ class PopupReport implements PopupReportInterface
{
/**
* @param $account
* @param $attributes
*
* @return Collection
*/
public function balanceDifference($account, $attributes): Collection
{
// row that displays difference
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector
->setAccounts(new Collection([$account]))
->setTypes([TransactionType::WITHDRAWAL])
->setRange($attributes['startDate'], $attributes['endDate'])
->withoutBudget();
$journals = $collector->getJournals();
return $journals->filter(
function (Transaction $transaction) {
$tags = $transaction->transactionJournal->tags()->where('tagMode', 'balancingAct')->count();
if ($tags === 0) {
return true;
}
return false;
}
);
}
/**
* @param Budget $budget
* @param Account $account
@ -165,35 +196,4 @@ class PopupReport implements PopupReportInterface
return $journals;
}
/**
* @param $account
* @param $attributes
*
* @return Collection
*/
public function balanceDifference($account, $attributes): Collection
{
// row that displays difference
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector
->setAccounts(new Collection([$account]))
->setTypes([TransactionType::WITHDRAWAL])
->setRange($attributes['startDate'], $attributes['endDate'])
->withoutBudget();
$journals = $collector->getJournals();
return $journals->filter(
function (Transaction $transaction) {
$tags = $transaction->transactionJournal->tags()->where('tagMode', 'balancingAct')->count();
if ($tags === 0) {
return true;
}
return false;
}
);
}
}

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Report;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Helpers\Report;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
@ -22,8 +22,8 @@ use FireflyIII\Http\Requests\AccountFormRequest;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Account\AccountTaskerInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\CacheProperties;
@ -69,12 +69,13 @@ class AccountController extends Controller
public function create(Request $request, string $what = 'asset')
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$currencies = ExpandedForm::makeSelectList($repository->get());
$defaultCurrency = Amount::getDefaultCurrency();
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
$subTitle = trans('firefly.make_new_' . $what . '_account');
$roles = [];
$repository = app(CurrencyRepositoryInterface::class);
$allCurrencies = $repository->get();
$currencySelectList = ExpandedForm::makeSelectList($allCurrencies);
$defaultCurrency = Amount::getDefaultCurrency();
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
$subTitle = trans('firefly.make_new_' . $what . '_account');
$roles = [];
foreach (config('firefly.accountRoles') as $role) {
$roles[$role] = strval(trans('firefly.account_role_' . $role));
}
@ -91,7 +92,7 @@ class AccountController extends Controller
$request->session()->flash('gaEventCategory', 'accounts');
$request->session()->flash('gaEventAction', 'create-' . $what);
return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle', 'currencies', 'roles'));
return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle', 'currencySelectList', 'allCurrencies', 'roles'));
}
@ -147,14 +148,14 @@ class AccountController extends Controller
*/
public function edit(Request $request, Account $account)
{
$what = config('firefly.shortNamesByFullName')[$account->accountType->type];
$subTitle = trans('firefly.edit_' . $what . '_account', ['name' => $account->name]);
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$currencies = ExpandedForm::makeSelectList($repository->get());
$roles = [];
$repository = app(CurrencyRepositoryInterface::class);
$what = config('firefly.shortNamesByFullName')[$account->accountType->type];
$subTitle = trans('firefly.edit_' . $what . '_account', ['name' => $account->name]);
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
$allCurrencies = $repository->get();
$currencySelectList = ExpandedForm::makeSelectList($allCurrencies);
$roles = [];
foreach (config('firefly.accountRoles') as $role) {
$roles[$role] = strval(trans('firefly.account_role_' . $role));
}
@ -173,6 +174,7 @@ class AccountController extends Controller
$openingBalanceAmount = $account->getOpeningBalanceAmount() === '0' ? '' : $openingBalanceAmount;
$openingBalanceDate = $account->getOpeningBalanceDate();
$openingBalanceDate = $openingBalanceDate->year === 1900 ? null : $openingBalanceDate->format('Y-m-d');
$currency = $repository->find(intval($account->getMeta('currency_id')));
$preFilled = [
'accountNumber' => $account->getMeta('accountNumber'),
@ -183,13 +185,18 @@ class AccountController extends Controller
'openingBalanceDate' => $openingBalanceDate,
'openingBalance' => $openingBalanceAmount,
'virtualBalance' => $account->virtual_balance,
'currency_id' => $account->getMeta('currency_id'),
'currency_id' => $currency->id,
];
$request->session()->flash('preFilled', $preFilled);
$request->session()->flash('gaEventCategory', 'accounts');
$request->session()->flash('gaEventAction', 'edit-' . $what);
return view('accounts.edit', compact('currencies', 'account', 'subTitle', 'subTitleIcon', 'openingBalance', 'what', 'roles'));
return view(
'accounts.edit', compact(
'allCurrencies', 'currencySelectList', 'account', 'currency', 'subTitle', 'subTitleIcon', 'openingBalance', 'what', 'roles'
)
);
}
/**
@ -242,14 +249,17 @@ class AccountController extends Controller
if ($account->accountType->type === AccountType::INITIAL_BALANCE) {
return $this->redirectToOriginalAccount($account);
}
$range = Preferences::get('viewRange', '1M')->data;
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $account->accountType->type);
$page = intval($request->get('page')) === 0 ? 1 : intval($request->get('page'));
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
$chartUri = route('chart.account.single', [$account->id]);
$start = null;
$end = null;
$periods = new Collection;
/** @var CurrencyRepositoryInterface $currencyRepos */
$currencyRepos = app(CurrencyRepositoryInterface::class);
$range = Preferences::get('viewRange', '1M')->data;
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $account->accountType->type);
$page = intval($request->get('page')) === 0 ? 1 : intval($request->get('page'));
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
$chartUri = route('chart.account.single', [$account->id]);
$start = null;
$end = null;
$periods = new Collection;
$currency = $currencyRepos->find(intval($account->getMeta('currency_id')));
// prep for "all" view.
if ($moment === 'all') {
@ -283,7 +293,6 @@ class AccountController extends Controller
$periods = $this->getPeriodOverview($account);
}
$accountType = $account->accountType->type;
$count = 0;
$loop = 0;
// grab journals, but be prepared to jump a period back to get the right ones:
@ -316,7 +325,8 @@ class AccountController extends Controller
return view(
'accounts.show', compact('account', 'moment', 'accountType', 'periods', 'subTitleIcon', 'journals', 'subTitle', 'start', 'end', 'chartUri')
'accounts.show',
compact('account', 'currency', 'moment', 'periods', 'subTitleIcon', 'journals', 'subTitle', 'start', 'end', 'chartUri')
);
}
@ -331,7 +341,6 @@ class AccountController extends Controller
{
$data = $request->getAccountData();
$account = $repository->store($data);
$request->session()->flash('success', strval(trans('firefly.stored_new_account', ['name' => $account->name])));
Preferences::mark();
@ -409,14 +418,11 @@ class AccountController extends Controller
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
/** @var AccountTaskerInterface $tasker */
$tasker = app(AccountTaskerInterface::class);
$start = $repository->oldestJournalDate($account);
$range = Preferences::get('viewRange', '1M')->data;
$start = Navigation::startOfPeriod($start, $range);
$end = Navigation::endOfX(new Carbon, $range);
$entries = new Collection;
$start = $repository->oldestJournalDate($account);
$range = Preferences::get('viewRange', '1M')->data;
$start = Navigation::startOfPeriod($start, $range);
$end = Navigation::endOfX(new Carbon, $range);
$entries = new Collection;
// properties for cache
$cache = new CacheProperties;
@ -429,19 +435,28 @@ class AccountController extends Controller
return $cache->get(); // @codeCoverageIgnore
}
// only include asset accounts when this account is an asset:
$assets = new Collection;
if (in_array($account->accountType->type, [AccountType::ASSET, AccountType::DEFAULT])) {
$assets = $repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]);
}
Log::debug('Going to get period expenses and incomes.');
while ($end >= $start) {
$end = Navigation::startOfPeriod($end, $range);
$currentEnd = Navigation::endOfPeriod($end, $range);
$spent = $tasker->amountOutInPeriod(new Collection([$account]), $assets, $end, $currentEnd);
$earned = $tasker->amountInInPeriod(new Collection([$account]), $assets, $end, $currentEnd);
$dateStr = $end->format('Y-m-d');
$dateName = Navigation::periodShow($end, $range);
// try a collector for income:
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->setRange($end, $currentEnd)
->setTypes([TransactionType::DEPOSIT])
->withOpposingAccount();
$earned = strval($collector->getJournals()->sum('transaction_amount'));
// try a collector for expenses:
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->setRange($end, $currentEnd)
->setTypes([TransactionType::WITHDRAWAL])
->withOpposingAccount();
$spent = strval($collector->getJournals()->sum('transaction_amount'));
$dateStr = $end->format('Y-m-d');
$dateName = Navigation::periodShow($end, $range);
$entries->push(
[
'string' => $dateStr,

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Admin;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Admin;

View File

@ -125,8 +125,10 @@ class UserController extends Controller
}
/**
* @param UserFormRequest $request
* @param User $user
* @param UserFormRequest $request
* @param User $user
*
* @param UserRepositoryInterface $repository
*
* @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers;

View File

@ -8,7 +8,7 @@
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;
@ -41,7 +41,9 @@ class ForgotPasswordController extends Controller
/**
* Send a reset link to the given user.
*
* @param Request $request
* @param Request $request
*
* @param UserRepositoryInterface $repository
*
* @return \Illuminate\Http\RedirectResponse
*/

View File

@ -8,7 +8,7 @@
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;
@ -110,7 +110,9 @@ class LoginController extends Controller
/**
* Show the application login form.
*
* @param Request $request
* @param Request $request
*
* @param CookieJar $cookieJar
*
* @return \Illuminate\Http\Response
*/

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;

View File

@ -8,7 +8,7 @@
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;

View File

@ -8,7 +8,7 @@
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;
@ -42,8 +42,8 @@ class TwoFactorController extends Controller
// to make sure the validator in the next step gets the secret, we push it in session
$secretPreference = Preferences::get('twoFactorAuthSecret', null);
$secret = is_null($secretPreference) ? null : $secretPreference->data;
$title = strval(trans('firefly.two_factor_title'));
$secret = is_null($secretPreference) ? null : $secretPreference->data;
$title = strval(trans('firefly.two_factor_title'));
// make sure the user has two factor configured:
$has2FA = Preferences::get('twoFactorAuthEnabled', false)->data;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
@ -191,8 +191,9 @@ class BudgetController extends Controller
}
/**
* @param Request $request
* @param string $moment
* @param Request $request
* @param JournalRepositoryInterface $repository
* @param string $moment
*
* @return View
*/
@ -310,7 +311,7 @@ class BudgetController extends Controller
$journals->setPath('/budgets/show/' . $budget->id);
$subTitle = e($budget->name);
$subTitle = trans('firefly.all_journals_for_budget', ['name' => $budget->name]);
return view('budgets.show', compact('limits', 'budget', 'repetition', 'journals', 'subTitle'));
}

View File

@ -154,6 +154,10 @@ class CategoryController extends Controller
}
/**
* @param Request $request
* @param JournalRepositoryInterface $repository
* @param string $moment
*
* @return View
*/
public function noCategory(Request $request, JournalRepositoryInterface $repository, string $moment = '')
@ -398,7 +402,7 @@ class CategoryController extends Controller
// count journals without budget in this period:
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($end, $currentEnd)->withoutCategory()->withOpposingAccount();
$collector->setAllAssetAccounts()->setRange($end, $currentEnd)->withoutCategory()->withOpposingAccount()->disableInternalFilter();
$count = $collector->getJournals()->count();
// amount transferred

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
@ -26,6 +26,7 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
use Log;
@ -335,19 +336,13 @@ class AccountController extends Controller
/**
* @param Account $account
* @param string $date
* @param Carbon $start
*
* @return \Illuminate\Http\JsonResponse
* @throws FireflyException
*/
public function period(Account $account, string $date)
public function period(Account $account, Carbon $start)
{
try {
$start = new Carbon($date);
} catch (Exception $e) {
Log::error($e->getMessage());
throw new FireflyException('"' . e($date) . '" does not seem to be a valid date. Should be in the format YYYY-MM-DD');
}
$range = Preferences::get('viewRange', '1M')->data;
$end = Navigation::endOfPeriod($start, $range);
$cache = new CacheProperties();
@ -501,11 +496,16 @@ class AccountController extends Controller
}
Log::debug('Regenerate chart.account.account-balance-chart from scratch.');
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$chartData = [];
foreach ($accounts as $account) {
$currency = $repository->find(intval($account->getMeta('currency_id')));
$currentSet = [
'label' => $account->name,
'entries' => [],
'label' => $account->name,
'currency_symbol' => $currency->symbol,
'entries' => [],
];
$currentStart = clone $start;
$range = Steam::balanceInRange($account, $start, clone $end);

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
@ -18,11 +18,14 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
use Navigation;
@ -153,6 +156,144 @@ class BudgetController extends Controller
return Response::json($data);
}
/**
* @param Budget $budget
* @param BudgetLimit|null $budgetLimit
*
* @return \Illuminate\Http\JsonResponse
*/
public function expenseAsset(Budget $budget, BudgetLimit $budgetLimit = null)
{
$cache = new CacheProperties;
$cache->addProperty($budget->id);
$cache->addProperty($budgetLimit->id ?? 0);
$cache->addProperty('chart.budget.expense-asset');
if ($cache->has()) {
return Response::json($cache->get()); // @codeCoverageIgnore
}
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setTypes([TransactionType::WITHDRAWAL])->setBudget($budget);
if (!is_null($budgetLimit->id)) {
$collector->setRange($budgetLimit->start_date, $budgetLimit->end_date);
}
$transactions = $collector->getJournals();
$result = [];
$chartData = [];
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
$assetId = intval($transaction->account_id);
$result[$assetId] = $result[$assetId] ?? '0';
$result[$assetId] = bcadd($transaction->transaction_amount, $result[$assetId]);
}
$names = $this->getAccountNames(array_keys($result));
foreach ($result as $assetId => $amount) {
$chartData[$names[$assetId]] = $amount;
}
$data = $this->generator->pieChart($chartData);
$cache->store($data);
return Response::json($data);
}
/**
* @param Budget $budget
* @param BudgetLimit|null $budgetLimit
*
* @return \Illuminate\Http\JsonResponse
*/
public function expenseCategory(Budget $budget, BudgetLimit $budgetLimit = null)
{
$cache = new CacheProperties;
$cache->addProperty($budget->id);
$cache->addProperty($budgetLimit->id ?? 0);
$cache->addProperty('chart.budget.expense-category');
if ($cache->has()) {
return Response::json($cache->get()); // @codeCoverageIgnore
}
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setTypes([TransactionType::WITHDRAWAL])->setBudget($budget)->withCategoryInformation();
if (!is_null($budgetLimit->id)) {
$collector->setRange($budgetLimit->start_date, $budgetLimit->end_date);
}
$transactions = $collector->getJournals();
$result = [];
$chartData = [];
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
$jrnlCatId = intval($transaction->transaction_journal_category_id);
$transCatId = intval($transaction->transaction_category_id);
$categoryId = max($jrnlCatId, $transCatId);
$result[$categoryId] = $result[$categoryId] ?? '0';
$result[$categoryId] = bcadd($transaction->transaction_amount, $result[$categoryId]);
}
$names = $this->getCategoryNames(array_keys($result));
foreach ($result as $categoryId => $amount) {
$chartData[$names[$categoryId]] = $amount;
}
$data = $this->generator->pieChart($chartData);
$cache->store($data);
return Response::json($data);
}
/**
* @param Budget $budget
* @param BudgetLimit|null $budgetLimit
*
* @return \Illuminate\Http\JsonResponse
*/
public function expenseExpense(Budget $budget, BudgetLimit $budgetLimit = null)
{
$cache = new CacheProperties;
$cache->addProperty($budget->id);
$cache->addProperty($budgetLimit->id ?? 0);
$cache->addProperty('chart.budget.expense-expense');
if ($cache->has()) {
return Response::json($cache->get()); // @codeCoverageIgnore
}
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setTypes([TransactionType::WITHDRAWAL])->setBudget($budget)->withOpposingAccount();
if (!is_null($budgetLimit->id)) {
$collector->setRange($budgetLimit->start_date, $budgetLimit->end_date);
}
$transactions = $collector->getJournals();
$result = [];
$chartData = [];
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
$opposingId = intval($transaction->opposing_account_id);
$result[$opposingId] = $result[$opposingId] ?? '0';
$result[$opposingId] = bcadd($transaction->transaction_amount, $result[$opposingId]);
}
$names = $this->getAccountNames(array_keys($result));
foreach ($result as $opposingId => $amount) {
$name = $names[$opposingId] ?? 'no name';
$chartData[$name] = $amount;
}
$data = $this->generator->pieChart($chartData);
$cache->store($data);
return Response::json($data);
}
/**
* Shows a budget list with spent/left/overspent.
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's exactly five.
@ -288,6 +429,28 @@ class BudgetController extends Controller
return Response::json($data);
}
/**
* @param array $accountIds
*
* @return array
*/
private function getAccountNames(array $accountIds): array
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$accounts = $repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT, AccountType::EXPENSE]);
$grouped = $accounts->groupBy('id')->toArray();
$return = [];
foreach ($accountIds as $accountId) {
if (isset($grouped[$accountId])) {
$return[$accountId] = $grouped[$accountId][0]['name'];
}
}
$return[0] = '(no name)';
return $return;
}
/**
* @param Budget $budget
* @param Carbon $start
@ -314,6 +477,30 @@ class BudgetController extends Controller
return $budgeted;
}
/**
* Small helper function for some of the charts.
*
* @param array $categoryIds
*
* @return array
*/
private function getCategoryNames(array $categoryIds): array
{
/** @var CategoryRepositoryInterface $repository */
$repository = app(CategoryRepositoryInterface::class);
$categories = $repository->getCategories();
$grouped = $categories->groupBy('id')->toArray();
$return = [];
foreach ($categoryIds as $categoryId) {
if (isset($grouped[$categoryId])) {
$return[$categoryId] = $grouped[$categoryId][0]['name'];
}
}
$return[0] = trans('firefly.noCategory');
return $return;
}
/**
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's 6 but ok.

View File

@ -100,9 +100,9 @@ class CategoryController extends Controller
$earned = $repository->earnedInPeriod(new Collection([$category]), $accounts, $start, $currentEnd);
$sum = bcadd($spent, $earned);
$label = Navigation::periodShow($start, $range);
$chartData[0]['entries'][$label] = bcmul($spent, '-1');
$chartData[1]['entries'][$label] = $earned;
$chartData[2]['entries'][$label] = $sum;
$chartData[0]['entries'][$label] = round(bcmul($spent, '-1'), 12);
$chartData[1]['entries'][$label] = round($earned, 12);
$chartData[2]['entries'][$label] = round($sum, 12);
$start = Navigation::addPeriod($start, $range, 0);
}
@ -113,21 +113,6 @@ class CategoryController extends Controller
}
/**
* @param CategoryRepositoryInterface $repository
* @param Category $category
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function currentPeriod(CategoryRepositoryInterface $repository, Category $category)
{
$start = clone session('start', Carbon::now()->startOfMonth());
$end = session('end', Carbon::now()->endOfMonth());
$data = $this->makePeriodChart($repository, $category, $start, $end);
return Response::json($data);
}
/**
* @param CategoryRepositoryInterface $repository
* @param AccountRepositoryInterface $accountRepository
@ -215,9 +200,9 @@ class CategoryController extends Controller
$spent = $expenses[$category->id]['entries'][$period] ?? '0';
$earned = $income[$category->id]['entries'][$period] ?? '0';
$sum = bcadd($spent, $earned);
$chartData[0]['entries'][$label] = bcmul($spent, '-1');
$chartData[1]['entries'][$label] = $earned;
$chartData[2]['entries'][$label] = $sum;
$chartData[0]['entries'][$label] = round(bcmul($spent, '-1'), 12);
$chartData[1]['entries'][$label] = round($earned, 12);
$chartData[2]['entries'][$label] = round($sum, 12);
}
$data = $this->generator->multiSet($chartData);
@ -290,12 +275,11 @@ class CategoryController extends Controller
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function specificPeriod(CategoryRepositoryInterface $repository, Category $category, $date)
public function specificPeriod(CategoryRepositoryInterface $repository, Category $category, Carbon $date)
{
$carbon = new Carbon($date);
$range = Preferences::get('viewRange', '1M')->data;
$start = Navigation::startOfPeriod($carbon, $range);
$end = Navigation::endOfPeriod($carbon, $range);
$start = Navigation::startOfPeriod($date, $range);
$end = Navigation::endOfPeriod($date, $range);
$data = $this->makePeriodChart($repository, $category, $start, $end);
return Response::json($data);
@ -350,11 +334,11 @@ class CategoryController extends Controller
$spent = $repository->spentInPeriod(new Collection([$category]), $accounts, $start, $start);
$earned = $repository->earnedInPeriod(new Collection([$category]), $accounts, $start, $start);
$sum = bcadd($spent, $earned);
$label = Navigation::periodShow($start, '1D');
$label = trim(Navigation::periodShow($start, '1D'));
$chartData[0]['entries'][$label] = bcmul($spent, '-1');
$chartData[1]['entries'][$label] = $earned;
$chartData[2]['entries'][$label] = $sum;
$chartData[0]['entries'][$label] = round(bcmul($spent, '-1'),12);
$chartData[1]['entries'][$label] = round($earned,12);
$chartData[2]['entries'][$label] = round($sum,12);
$start->addDay();

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
@ -20,6 +20,7 @@ use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Repositories\Account\AccountTaskerInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
use Log;
use Navigation;
use Response;
use Steam;
@ -103,8 +104,9 @@ class ReportController extends Controller
$cache->addProperty($accounts);
$cache->addProperty($end);
if ($cache->has()) {
return Response::json($cache->get()); // @codeCoverageIgnore
//return Response::json($cache->get()); // @codeCoverageIgnore
}
Log::debug('Going to do operations for accounts ', $accounts->pluck('id')->toArray());
$format = Navigation::preferredCarbonLocalizedFormat($start, $end);
$source = $this->getChartData($accounts, $start, $end);
$chartData = [
@ -163,6 +165,8 @@ class ReportController extends Controller
if ($cache->has()) {
return Response::json($cache->get()); // @codeCoverageIgnore
}
$source = $this->getChartData($accounts, $start, $end);
$numbers = [
'sum_earned' => '0',
@ -246,19 +250,41 @@ class ReportController extends Controller
$cache->addProperty($accounts);
$cache->addProperty($end);
if ($cache->has()) {
return $cache->get(); // @codeCoverageIgnore
// return $cache->get(); // @codeCoverageIgnore
}
$tasker = app(AccountTaskerInterface::class);
$currentStart = clone $start;
$spentArray = [];
$earnedArray = [];
/** @var AccountTaskerInterface $tasker */
$tasker = app(AccountTaskerInterface::class);
while ($currentStart <= $end) {
$currentEnd = Navigation::endOfPeriod($currentStart, '1M');
$currentEnd = Navigation::endOfPeriod($currentStart, '1M');
$earned = strval(
array_sum(
array_map(
function ($item) {
return $item['sum'];
}, $tasker->getIncomeReport($currentStart, $currentEnd, $accounts)
)
)
);
$spent = strval(
array_sum(
array_map(
function ($item) {
return $item['sum'];
}, $tasker->getExpenseReport($currentStart, $currentEnd, $accounts)
)
)
);
$label = $currentStart->format('Y-m') . '-01';
$spent = $tasker->amountOutInPeriod($accounts, $accounts, $currentStart, $currentEnd);
$earned = $tasker->amountInInPeriod($accounts, $accounts, $currentStart, $currentEnd);
$spentArray[$label] = bcmul($spent, '-1');
$earnedArray[$label] = $earned;
$currentStart = Navigation::addPeriod($currentStart, '1M', 0);

View File

@ -7,7 +7,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
@ -233,7 +233,7 @@ class TagReportController extends Controller
}
}
if (count($newSet) === 0) {
$newSet = $chartData;
$newSet = $chartData; // @codeCoverageIgnore
}
$data = $this->generator->multiSet($newSet);
$cache->store($data);

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers;

View File

@ -9,7 +9,7 @@
* See the LICENSE file for details.
*/
declare(strict_types = 1);
declare(strict_types=1);
namespace FireflyIII\Http\Controllers;

Some files were not shown because too many files have changed in this diff Show More