mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'develop' of https://github.com/JC5/firefly-iii.git
This commit is contained in:
commit
91b3ca047a
@ -3,6 +3,7 @@ languages:
|
||||
JavaScript: true
|
||||
PHP: true
|
||||
exclude_paths:
|
||||
- "gulpfile.js"
|
||||
- "public/packages/maximebf/php-debugbar/debugbar.js"
|
||||
- "public/packages/maximebf/php-debugbar/widgets.js"
|
||||
- "public/packages/maximebf/php-debugbar/openhandler.js"
|
||||
|
17
.env.example
Normal file → Executable file
17
.env.example
Normal file → Executable file
@ -11,15 +11,22 @@ DB_PASSWORD=secret
|
||||
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
|
||||
DEFAULT_CURRENCY=EUR
|
||||
DEFAULT_LANGUAGE=en_US
|
||||
|
||||
EMAIL_SMTP=
|
||||
EMAIL_DRIVER=smtp
|
||||
EMAIL_USERNAME=
|
||||
EMAIL_PASSWORD=
|
||||
EMAIL_PRETEND=false
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_HOST=mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_FROM=enter_your_email_here
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
SHOW_INCOMPLETE_TRANSLATIONS=false
|
||||
|
||||
|
31
.env.testing
Normal file → Executable file
31
.env.testing
Normal file → Executable file
@ -1,6 +1,7 @@
|
||||
APP_ENV=testing
|
||||
APP_DEBUG=true
|
||||
APP_KEY=SomeRandomString
|
||||
APP_KEY=SomeRandomStringOf32CharsExactly
|
||||
|
||||
|
||||
DB_CONNECTION=sqlite
|
||||
DB_HOST=localhost
|
||||
@ -10,9 +11,27 @@ DB_PASSWORD=secret
|
||||
|
||||
CACHE_DRIVER=array
|
||||
SESSION_DRIVER=array
|
||||
QUEUE_DRIVER=array
|
||||
|
||||
EMAIL_SMTP=
|
||||
EMAIL_USERNAME=
|
||||
EMAIL_PASSWORD=
|
||||
ANALYTICS_ID=ABC
|
||||
EMAIL_PRETEND=true
|
||||
DEFAULT_CURRENCY=EUR
|
||||
DEFAULT_LANGUAGE=en_US
|
||||
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_DRIVER=log
|
||||
MAIL_HOST=mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_FROM=your_address_here@example.com
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
SHOW_INCOMPLETE_TRANSLATIONS=false
|
||||
|
||||
ANALYTICS_ID=abcde
|
||||
RUNCLEANUP=false
|
||||
SITE_OWNER=your_address_here@example.com
|
||||
|
||||
BLOCKED_DOMAINS=
|
2
.gitattributes
vendored
Normal file → Executable file
2
.gitattributes
vendored
Normal file → Executable file
@ -1 +1,3 @@
|
||||
* text=auto
|
||||
*.css linguist-vendored
|
||||
*.less linguist-vendored
|
||||
|
46
.gitignore
vendored
Normal file → Executable file
46
.gitignore
vendored
Normal file → Executable file
@ -1,36 +1,18 @@
|
||||
/bootstrap/compiled.php
|
||||
/vendor
|
||||
composer.phar
|
||||
Thumbs.db
|
||||
.idea/
|
||||
tests/_output/*
|
||||
_ide_helper.php
|
||||
/build/logs
|
||||
index.html*
|
||||
app/storage/firefly-export*
|
||||
.vagrant
|
||||
firefly-iii-import-*.json
|
||||
tests/_output/*
|
||||
testing.sqlite
|
||||
_ide_helper_models.php
|
||||
clean.sqlite
|
||||
tests/acceptance/AcceptanceTester.php
|
||||
tests/functional/FunctionalTester.php
|
||||
tests/unit/UnitTester.php
|
||||
pi.php
|
||||
tests/_data/db.sqlite
|
||||
tests/_data/dump.sql
|
||||
db.sqlite_snapshot
|
||||
c3.php
|
||||
db.sqlite-journal
|
||||
tests/_output/*
|
||||
/node_modules
|
||||
Homestead.yaml
|
||||
Homestead.json
|
||||
.env
|
||||
clover.xml
|
||||
node_modules/
|
||||
addNewLines.php
|
||||
.idea/
|
||||
_ide_helper.php
|
||||
_ide_helper_models.php
|
||||
.phpstorm.meta.php
|
||||
.env.backup
|
||||
.env.local
|
||||
|
||||
tests/_output/*
|
||||
tests/_output/*
|
||||
storage/
|
||||
|
||||
# Eclipse project files
|
||||
.buildpath
|
||||
.project
|
||||
.settings/
|
||||
|
||||
.env.local
|
||||
|
10
.travis.yml
10
.travis.yml
@ -3,16 +3,18 @@ sudo: false
|
||||
|
||||
|
||||
php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7
|
||||
|
||||
install:
|
||||
- composer update
|
||||
- composer install
|
||||
- php artisan env
|
||||
- mv -v .env.testing .env
|
||||
- php artisan env
|
||||
- touch storage/upload/at-1.data
|
||||
- touch storage/upload/at-2.data
|
||||
- touch storage/database/testing.db
|
||||
- php artisan migrate --env=testing
|
||||
- php artisan migrate --seed --env=testing
|
||||
- php artisan migrate --seed
|
||||
|
||||
script:
|
||||
- phpunit
|
||||
|
7
LICENSE
Normal file
7
LICENSE
Normal file
@ -0,0 +1,7 @@
|
||||
Copyright (C) 2016 Sander Dorigo
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
124
README.md
124
README.md
@ -2,129 +2,25 @@
|
||||
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
|
||||
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/JC5/firefly-iii/build-status/master)
|
||||
[](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
|
||||
[](https://codeclimate.com/github/JC5/firefly-iii)
|
||||
[](http://stillmaintained.com/JC5/firefly-iii)
|
||||
|
||||
## About
|
||||
|
||||
"Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared
|
||||
household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money.
|
||||
|
||||
Personal financial management is pretty difficult, and everybody has their own approach to it. Some people
|
||||
make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase
|
||||
their current cashflow. There are tons of ways to save and earn money.
|
||||
|
||||
Personal financial management is pretty difficult, and everybody has their own approach to it. Some people make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase their current cashflow. There are tons of ways to save and earn money.
|
||||
|
||||
Firefly works on the principle that if you know where you're money is going, you can stop it from going there.
|
||||
|
||||
To get to know Firefly, and to see if it fits you, check out these resources:
|
||||
#### Some advantages of using Firefly
|
||||
|
||||
- The screenshots below on this very page.
|
||||
- The featurelist below, also on this very page.
|
||||
- The [full description](https://github.com/JC5/firefly-iii/wiki/full-description), which will tell you how Firefly works,
|
||||
and the philosophy behind it.
|
||||
- Firefly can import any CSV file, so migrating from other systems is easy.
|
||||
- Firefly runs on your own server, so you are fully in control of your data.
|
||||
- If you feel you're missing something you can just ask me and I'll add it!
|
||||
|
||||
#### A quick technical overview
|
||||
|
||||
Firefly is a system you'll have install yourself on webhosting of your choosing. It needs PHP and MySQL. The current version of Firefly III requires PHP 5.6.4 or
|
||||
higher. Soon, this will be PHP 7.0.0 or higher.
|
||||
|
||||
|
||||
#### About the name (should you care)
|
||||
|
||||
It's III, or 3, because [version 2](https://github.com/JC5/Firefly) and version 1 (not online) preceded it. It has been growing steadily ever since.
|
||||
|
||||
## Current features
|
||||
|
||||
- [A double-entry bookkeeping system](https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system);
|
||||
- You can store, edit and remove [withdrawals, deposits and transfers](https://en.wikipedia.org/wiki/Financial_transaction). This allows you full financial management;
|
||||
- You can manage different types of accounts;
|
||||
- [Asset](https://en.wikipedia.org/wiki/Asset) accounts
|
||||
- Shared [asset accounts](https://en.wikipedia.org/wiki/Asset) ([household accounts](https://en.wikipedia.org/wiki/Household))
|
||||
- Saving accounts
|
||||
- Credit cards
|
||||
- It's possible to create, change and manage money using _[budgets](https://en.wikipedia.org/wiki/Envelope_system)_;
|
||||
- Organize transactions using categories;
|
||||
- Save towards a goal using [piggy banks](https://en.wikipedia.org/wiki/Piggy_bank);
|
||||
- Predict and anticipate [bills](https://en.wikipedia.org/wiki/Invoice);
|
||||
- View income / expense [reports](https://en.wikipedia.org/wiki/Financial_statement);
|
||||
- Organize expenses using tags;
|
||||
- Lots of help text in case you don't get it.
|
||||
|
||||
Everything is organised:
|
||||
|
||||
- Clear views that should show you how you're doing;
|
||||
- Easy navigation through your records;
|
||||
- Browse back and forth to see previous months or even years;
|
||||
- Lots of charts because we all love them;
|
||||
- Financial reporting showing you how well you are doing.
|
||||
|
||||
## Screenshots
|
||||
|
||||
_Please note that everything in these screenshots is fictional and may not be realistic._
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Running and installing
|
||||
|
||||
If you're still interested please read [the installation guide](https://github.com/JC5/firefly-iii/wiki/Installation),
|
||||
[the upgrade guide](https://github.com/JC5/firefly-iii/wiki/Upgrade-instructions) (if applicable)
|
||||
and the **[first use guide](https://github.com/JC5/firefly-iii/wiki/First-use)**.
|
||||
|
||||
If you want to try out Firefly III, you can do so on [this dedicated website](https://geld.nder.be/).
|
||||
This site always runs the latest version of Firefly III. If you want to use it, please read the [privacy considerations](https://github.com/JC5/firefly-iii/wiki/Privacy-on-demo-site) for this demo-site. Accounts on the demo sites will stop working after one month. It's a trial.
|
||||
|
||||
## Security
|
||||
|
||||
You should always run Firefly III on a site with TLS enabled (https://). Please note that although some parts of the
|
||||
database are encrypted (transaction descriptions, names, etc.) some parts are _not_ (amounts, dates, etc). If you need
|
||||
more security, you must enable transparent database encryption or a comparable technology. Please remember that this
|
||||
is open source software under active development, and it is in no way guaranteed to be safe or secure.
|
||||
|
||||
## Translations
|
||||
|
||||
Firefly III is currently available in Dutch and English. Support for other languages is being worked on. I could use
|
||||
your help. Checkout [Crowdin](https://crowdin.com/project/firefly-iii) for more information.
|
||||
|
||||
## Credits
|
||||
|
||||
Firefly III uses the following libraries and tools:
|
||||
|
||||
* The AdminLTE template by [Almsaseed Studio](https://almsaeedstudio.com/)
|
||||
* The [Google charts](https://developers.google.com/chart/) library.
|
||||
* [Chart.js](http://www.chartjs.org/)
|
||||
* [Bootstrap](http://getbootstrap.com/)
|
||||
* [Laravel](http://laravel.com/)
|
||||
* [Twig](http://twig.sensiolabs.org/)
|
||||
* For development, some of the excellent tools made by [Barry van den Heuvel](https://github.com/barryvdh)
|
||||
* [Bootstrap sortable](https://github.com/drvic10k/bootstrap-sortable) by [Matúš Brliť](https://github.com/drvic10k).
|
||||
* [Date range picker](https://github.com/dangrossman/bootstrap-daterangepicker/) by [Dan Grossman](https://github.com/dangrossman)
|
||||
* The [real favicon generator](http://realfavicongenerator.net/)
|
||||
* Various other open source components (see [composer.json](https://github.com/JC5/firefly-iii/blob/master/composer.json))
|
||||
|
||||
|
||||
## Current state
|
||||
|
||||
Firefly III is pretty much all grown up. Full test coverage (nerd alert!) is coming. Translations are a work in progress.
|
||||
|
||||
Questions, ideas, bugs or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)!
|
||||
|
||||
If you like this tool, feel free to [donate me some beer money](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2ZMV952UUSCLU&lc=NL&item_name=Development%20of%20Firefly¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted).
|
||||
|
||||
[](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
|
||||
[](https://codeclimate.com/github/JC5/firefly-iii)
|
||||
[](http://stillmaintained.com/JC5/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||

|
||||
Firefly is pretty awesome. [You can read more about Firefly III, and its features, on the Github Pages](https://jc5.github.io/firefly-iii/).
|
||||
|
@ -1,12 +0,0 @@
|
||||
<?php namespace FireflyIII\Commands;
|
||||
/**
|
||||
* Class Command
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Commands
|
||||
*/
|
||||
abstract class Command
|
||||
{
|
||||
|
||||
|
||||
}
|
68
app/Console/Commands/UpgradeFireflyInstructions.php
Normal file
68
app/Console/Commands/UpgradeFireflyInstructions.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Config;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class UpgradeFireflyInstructions
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class UpgradeFireflyInstructions extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:upgrade-instructions';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
//
|
||||
$version = Config::get('firefly.version');
|
||||
$config = Config::get('upgrade.text');
|
||||
$text = isset($config[$version]) ? $config[$version] : null;
|
||||
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
$this->line('');
|
||||
|
||||
if (is_null($text)) {
|
||||
$this->line('Thank you for installing Firefly III, v' . $version);
|
||||
$this->line('If you are upgrading from a previous version,');
|
||||
$this->info('there are no extra upgrade instructions.');
|
||||
$this->line('Firefly III should be ready for use.');
|
||||
} else {
|
||||
$this->line('Thank you for installing Firefly III, v' . $version);
|
||||
$this->line('If you are upgrading from a previous version,');
|
||||
$this->line('please follow these upgrade instructions carefully:');
|
||||
$this->info(wordwrap($text));
|
||||
}
|
||||
|
||||
$this->line('');
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
}
|
||||
}
|
20
app/Console/Kernel.php
Normal file → Executable file
20
app/Console/Kernel.php
Normal file → Executable file
@ -1,17 +1,25 @@
|
||||
<?php namespace FireflyIII\Console;
|
||||
<?php
|
||||
/**
|
||||
* Kernel.php
|
||||
* Copyright (C) 2016 Sander Dorigo
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Console;
|
||||
|
||||
use FireflyIII\Console\Commands\UpgradeFireflyInstructions;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
/**
|
||||
* Class Kernel
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Console
|
||||
*/
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
@ -19,6 +27,7 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected $commands
|
||||
= [
|
||||
UpgradeFireflyInstructions::class,
|
||||
];
|
||||
|
||||
/**
|
||||
@ -26,12 +35,11 @@ class Kernel extends ConsoleKernel
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameters)
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
7
app/Events/Event.php
Normal file → Executable file
7
app/Events/Event.php
Normal file → Executable file
@ -1,14 +1,13 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
/**
|
||||
* Class Event
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
abstract class Event
|
||||
{
|
||||
|
||||
//
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,24 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
<?php
|
||||
/**
|
||||
* TransactionJournalStored.php
|
||||
* Copyright (C) 2016 Sander Dorigo
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class JournalCreated
|
||||
* Class TransactionJournalStored
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalCreated extends Event
|
||||
class TransactionJournalStored extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
@ -4,12 +4,12 @@ use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class JournalSaved
|
||||
* Class TransactionJournalUpdated
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalSaved extends Event
|
||||
class TransactionJournalUpdated extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
51
app/Exceptions/Handler.php
Normal file → Executable file
51
app/Exceptions/Handler.php
Normal file → Executable file
@ -1,18 +1,21 @@
|
||||
<?php namespace FireflyIII\Exceptions;
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Foundation\Validation\ValidationException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
/**
|
||||
* Class Handler
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Exceptions
|
||||
*/
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of the exception types that should not be reported.
|
||||
*
|
||||
@ -20,40 +23,36 @@ class Handler extends ExceptionHandler
|
||||
*/
|
||||
protected $dontReport
|
||||
= [
|
||||
'Symfony\Component\HttpKernel\Exception\HttpException'
|
||||
AuthorizationException::class,
|
||||
HttpException::class,
|
||||
ModelNotFoundException::class,
|
||||
ValidationException::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Render an exception into an HTTP response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $e
|
||||
* @SuppressWarnings(PHPMD.ShortVariable)
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $e)
|
||||
{
|
||||
if ($e instanceof HttpException) {
|
||||
return $this->renderHttpException($e);
|
||||
} else {
|
||||
return parent::render($request, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report or log an exception.
|
||||
*
|
||||
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
|
||||
* @SuppressWarnings(PHPMD.ShortVariable)
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @param Exception $exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function report(Exception $e)
|
||||
public function report(Exception $exception)
|
||||
{
|
||||
parent::report($e);
|
||||
parent::report($exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an exception into an HTTP response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $exception
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $exception)
|
||||
{
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,15 @@ use Illuminate\Support\Collection;
|
||||
interface AccountChartGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
@ -31,13 +40,4 @@ interface AccountChartGenerator
|
||||
* @return array
|
||||
*/
|
||||
public function single(Account $account, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end);
|
||||
}
|
||||
|
@ -62,22 +62,6 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $array
|
||||
* @param $entryId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function isInArray($array, $entryId)
|
||||
{
|
||||
if (isset($array[$entryId])) {
|
||||
return $array[$entryId];
|
||||
}
|
||||
|
||||
return '0';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
@ -89,18 +73,13 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
{
|
||||
// language:
|
||||
$format = trans('config.month_and_day');
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
$data = ['count' => 0, 'labels' => [], 'datasets' => [],];
|
||||
$current = clone $start;
|
||||
while ($current <= $end) {
|
||||
$data['labels'][] = $current->formatLocalized($format);
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$set = [
|
||||
'label' => $account->name,
|
||||
@ -114,10 +93,10 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
];
|
||||
$current = clone $start;
|
||||
$range = Steam::balanceInRange($account, $start, clone $end);
|
||||
$previous = array_values($range)[0];
|
||||
$previous = round(array_values($range)[0], 2);
|
||||
while ($current <= $end) {
|
||||
$format = $current->format('Y-m-d');
|
||||
$balance = isset($range[$format]) ? $range[$format] : $previous;
|
||||
$balance = isset($range[$format]) ? round($range[$format], 2) : $previous;
|
||||
|
||||
$set['data'][] = $balance;
|
||||
$previous = $balance;
|
||||
@ -148,8 +127,8 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => $account->name,
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
$range = Steam::balanceInRange($account, $start, $end);
|
||||
@ -184,4 +163,19 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
||||
return array_unique($ids);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $array
|
||||
* @param $entryId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function isInArray($array, $entryId)
|
||||
{
|
||||
if (isset($array[$entryId])) {
|
||||
return $array[$entryId];
|
||||
}
|
||||
|
||||
return '0';
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class ChartJsBillChartGenerator implements BillChartGenerator
|
||||
'color' => 'rgba(0, 141, 76, 0.7)',
|
||||
'highlight' => 'rgba(0, 141, 76, 0.9)',
|
||||
'label' => trans('firefly.paid'),
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
return $data;
|
||||
|
@ -106,6 +106,40 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYear(Collection $entries)
|
||||
{
|
||||
// dataset:
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
// get labels from one of the budgets (assuming there's at least one):
|
||||
$first = $entries->first();
|
||||
$keys = array_keys($first['budgeted']);
|
||||
foreach ($keys as $year) {
|
||||
$data['labels'][] = strval($year);
|
||||
}
|
||||
|
||||
// then, loop all entries and create datasets:
|
||||
foreach ($entries as $entry) {
|
||||
$name = $entry['name'];
|
||||
$spent = $entry['spent'];
|
||||
$budgeted = $entry['budgeted'];
|
||||
$data['datasets'][] = ['label' => 'Spent on ' . $name, 'data' => array_values($spent)];
|
||||
$data['datasets'][] = ['label' => 'Budgeted for ' . $name, 'data' => array_values($budgeted)];
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $entries
|
||||
@ -140,37 +174,4 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function multiYear(Collection $entries)
|
||||
{
|
||||
// dataset:
|
||||
$data = [
|
||||
'count' => 0,
|
||||
'labels' => [],
|
||||
'datasets' => [],
|
||||
];
|
||||
// get labels from one of the budgets (assuming there's at least one):
|
||||
$first = $entries->first();
|
||||
foreach ($first['budgeted'] as $year => $noInterest) {
|
||||
$data['labels'][] = strval($year);
|
||||
}
|
||||
|
||||
// then, loop all entries and create datasets:
|
||||
foreach ($entries as $entry) {
|
||||
$name = $entry['name'];
|
||||
$spent = $entry['spent'];
|
||||
$budgeted = $entry['budgeted'];
|
||||
$data['datasets'][] = ['label' => 'Spent on ' . $name, 'data' => array_values($spent)];
|
||||
$data['datasets'][] = ['label' => 'Budgeted for ' . $name, 'data' => array_values($budgeted)];
|
||||
}
|
||||
$data['count'] = count($data['datasets']);
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -28,12 +28,12 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []
|
||||
'data' => [],
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.earned'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@ -95,8 +95,8 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.spent'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
foreach ($entries as $entry) {
|
||||
@ -124,7 +124,8 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
|
||||
];
|
||||
// get labels from one of the categories (assuming there's at least one):
|
||||
$first = $entries->first();
|
||||
foreach ($first['spent'] as $year => $noInterest) {
|
||||
$keys = array_keys($first['spent']);
|
||||
foreach ($keys as $year) {
|
||||
$data['labels'][] = strval($year);
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,8 @@ class ChartJsPiggyBankChartGenerator implements PiggyBankChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => 'Diff',
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
$sum = '0';
|
||||
|
@ -27,12 +27,12 @@ class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
'data' => [],
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@ -60,12 +60,12 @@ class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
'data' => [],
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
$data['datasets'][0]['data'][] = round($income, 2);
|
||||
@ -92,12 +92,12 @@ class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
'data' => [],
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@ -126,12 +126,12 @@ class ChartJsReportChartGenerator implements ReportChartGenerator
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => trans('firefly.income'),
|
||||
'data' => []
|
||||
'data' => [],
|
||||
],
|
||||
[
|
||||
'label' => trans('firefly.expenses'),
|
||||
'data' => []
|
||||
]
|
||||
'data' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
$data['datasets'][0]['data'][] = round($income, 2);
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Events\JournalCreated;
|
||||
use FireflyIII\Events\TransactionJournalStored;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
@ -26,13 +26,13 @@ class ConnectJournalToPiggyBank
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event when journal is saved.
|
||||
* Connect a new transaction journal to any related piggy banks.
|
||||
*
|
||||
* @param JournalCreated $event
|
||||
* @param TransactionJournalStored $event
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function handle(JournalCreated $event)
|
||||
public function handle(TransactionJournalStored $event)
|
||||
{
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $event->journal;
|
||||
@ -42,12 +42,12 @@ class ConnectJournalToPiggyBank
|
||||
$piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
|
||||
|
||||
if (is_null($piggyBank)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
// update piggy bank rep for date of transaction journal.
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
if (is_null($repetition)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bcscale(2);
|
||||
|
||||
|
79
app/Handlers/Events/FireRulesForStore.php
Normal file
79
app/Handlers/Events/FireRulesForStore.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* FireRulesForStore.php
|
||||
* Copyright (C) 2016 Sander Dorigo
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
|
||||
use FireflyIII\Events\TransactionJournalStored;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Rules\Processor;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class FireRulesForStore
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class FireRulesForStore
|
||||
{
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect a new transaction journal to any related piggy banks.
|
||||
*
|
||||
* @param TransactionJournalStored $event
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function handle(TransactionJournalStored $event)
|
||||
{
|
||||
// get all the user's rule groups, with the rules, order by 'order'.
|
||||
/** @var User $user */
|
||||
$user = Auth::user();
|
||||
$groups = $user->ruleGroups()->where('rule_groups.active', 1)->orderBy('order', 'ASC')->get();
|
||||
//
|
||||
/** @var RuleGroup $group */
|
||||
foreach ($groups as $group) {
|
||||
Log::debug('Now processing group "' . $group->title . '".');
|
||||
$rules = $group->rules()
|
||||
->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
|
||||
->where('rule_triggers.trigger_type', 'user_action')
|
||||
->where('rule_triggers.trigger_value', 'store-journal')
|
||||
->where('rules.active', 1)
|
||||
->get(['rules.*']);
|
||||
/** @var Rule $rule */
|
||||
foreach ($rules as $rule) {
|
||||
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
|
||||
$processor = new Processor($rule, $event->journal);
|
||||
|
||||
// get some return out of this?
|
||||
$processor->handle();
|
||||
|
||||
if ($rule->stop_processing) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// echo 'Done processing rules. See log.';
|
||||
// exit;
|
||||
}
|
||||
}
|
74
app/Handlers/Events/FireRulesForUpdate.php
Normal file
74
app/Handlers/Events/FireRulesForUpdate.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* FireRulesForUpdate.php
|
||||
* Copyright (C) 2016 Sander Dorigo
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Events\TransactionJournalUpdated;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Rules\Processor;
|
||||
use FireflyIII\User;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class FireRulesForUpdate
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class FireRulesForUpdate
|
||||
{
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param TransactionJournalUpdated $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(TransactionJournalUpdated $event)
|
||||
{
|
||||
// get all the user's rule groups, with the rules, order by 'order'.
|
||||
/** @var User $user */
|
||||
$user = Auth::user();
|
||||
$groups = $user->ruleGroups()->where('rule_groups.active', 1)->orderBy('order', 'ASC')->get();
|
||||
//
|
||||
/** @var RuleGroup $group */
|
||||
foreach ($groups as $group) {
|
||||
Log::debug('Now processing group "' . $group->title . '".');
|
||||
$rules = $group->rules()
|
||||
->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
|
||||
->where('rule_triggers.trigger_type', 'user_action')
|
||||
->where('rule_triggers.trigger_value', 'update-journal')
|
||||
->where('rules.active', 1)
|
||||
->get(['rules.*']);
|
||||
/** @var Rule $rule */
|
||||
foreach ($rules as $rule) {
|
||||
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
|
||||
$processor = new Processor($rule, $event->journal);
|
||||
|
||||
// get some return out of this?
|
||||
$processor->handle();
|
||||
|
||||
if ($rule->stop_processing) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<?php namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
use FireflyIII\Events\TransactionJournalUpdated;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
@ -24,11 +24,11 @@ class RescanJournal
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param JournalSaved $event
|
||||
* @param TransactionJournalUpdated $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(JournalSaved $event)
|
||||
public function handle(TransactionJournalUpdated $event)
|
||||
{
|
||||
$journal = $event->journal;
|
||||
|
||||
|
61
app/Handlers/Events/ScanForBillsAfterStore.php
Normal file
61
app/Handlers/Events/ScanForBillsAfterStore.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* RescanJournalAfterStore.php
|
||||
* Copyright (C) 2016 Sander Dorigo
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\TransactionJournalStored;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class RescanJournal
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class ScanForBillsAfterStore
|
||||
{
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan a transaction journal for possible links to bills, right after storing.
|
||||
*
|
||||
* @param TransactionJournalStored $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(TransactionJournalStored $event)
|
||||
{
|
||||
$journal = $event->journal;
|
||||
|
||||
Log::debug('Triggered saved event for journal #' . $journal->id . ' (' . $journal->description . ')');
|
||||
|
||||
/** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
|
||||
$list = $journal->user->bills()->where('active', 1)->where('automatch', 1)->get();
|
||||
|
||||
Log::debug('Found ' . $list->count() . ' bills to check.');
|
||||
|
||||
/** @var \FireflyIII\Models\Bill $bill */
|
||||
foreach ($list as $bill) {
|
||||
Log::debug('Now calling bill #' . $bill->id . ' (' . $bill->name . ')');
|
||||
$repository->scan($bill, $journal);
|
||||
}
|
||||
|
||||
Log::debug('Done!');
|
||||
}
|
||||
|
||||
}
|
61
app/Handlers/Events/ScanForBillsAfterUpdate.php
Normal file
61
app/Handlers/Events/ScanForBillsAfterUpdate.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* ScanForBillsAfterUpdate.php
|
||||
* Copyright (C) 2016 Sander Dorigo
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\TransactionJournalUpdated;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class RescanJournal
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class ScanForBillsAfterUpdate
|
||||
{
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan a transaction journal for possibly related bills after it has been updated.
|
||||
*
|
||||
* @param TransactionJournalUpdated $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(TransactionJournalUpdated $event)
|
||||
{
|
||||
$journal = $event->journal;
|
||||
|
||||
Log::debug('Triggered saved event for journal #' . $journal->id . ' (' . $journal->description . ')');
|
||||
|
||||
/** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
|
||||
$list = $journal->user->bills()->where('active', 1)->where('automatch', 1)->get();
|
||||
|
||||
Log::debug('Found ' . $list->count() . ' bills to check.');
|
||||
|
||||
/** @var \FireflyIII\Models\Bill $bill */
|
||||
foreach ($list as $bill) {
|
||||
Log::debug('Now calling bill #' . $bill->id . ' (' . $bill->name . ')');
|
||||
$repository->scan($bill, $journal);
|
||||
}
|
||||
|
||||
Log::debug('Done!');
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<?php namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
use FireflyIII\Events\TransactionJournalUpdated;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
|
||||
@ -25,11 +25,11 @@ class UpdateJournalConnection
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param JournalSaved $event
|
||||
* @param TransactionJournalUpdated $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(JournalSaved $event)
|
||||
public function handle(TransactionJournalUpdated $event)
|
||||
{
|
||||
$journal = $event->journal;
|
||||
|
||||
|
@ -19,14 +19,14 @@ use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
class AttachmentHelper implements AttachmentHelperInterface
|
||||
{
|
||||
|
||||
/** @var int */
|
||||
protected $maxUploadSize;
|
||||
/** @var array */
|
||||
protected $allowedMimes;
|
||||
/** @var MessageBag */
|
||||
public $errors;
|
||||
/** @var MessageBag */
|
||||
public $messages;
|
||||
/** @var array */
|
||||
protected $allowedMimes;
|
||||
/** @var int */
|
||||
protected $maxUploadSize;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -51,6 +51,22 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Model $model
|
||||
*
|
||||
@ -98,27 +114,6 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateUpload(UploadedFile $file, Model $model)
|
||||
{
|
||||
if (!$this->validMime($file)) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->validSize($file)) {
|
||||
return false;
|
||||
}
|
||||
if ($this->hasFile($file, $model)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UploadedFile $file
|
||||
* @param Model $model
|
||||
@ -205,19 +200,24 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
* @param UploadedFile $file
|
||||
* @param Model $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getErrors()
|
||||
protected function validateUpload(UploadedFile $file, Model $model)
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
if (!$this->validMime($file)) {
|
||||
return false;
|
||||
}
|
||||
if (!$this->validSize($file)) {
|
||||
return false;
|
||||
}
|
||||
if ($this->hasFile($file, $model)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return $this->messages;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,11 +15,11 @@ interface AttachmentHelperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Model $model
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return bool
|
||||
* @return mixed
|
||||
*/
|
||||
public function saveAttachmentsForModel(Model $model);
|
||||
public function getAttachmentLocation(Attachment $attachment);
|
||||
|
||||
/**
|
||||
* @return MessageBag
|
||||
@ -32,10 +32,10 @@ interface AttachmentHelperInterface
|
||||
public function getMessages();
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
* @param Model $model
|
||||
*
|
||||
* @return mixed
|
||||
* @return bool
|
||||
*/
|
||||
public function getAttachmentLocation(Attachment $attachment);
|
||||
public function saveAttachmentsForModel(Model $model);
|
||||
|
||||
}
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class Amount
|
||||
*
|
||||
@ -13,7 +11,7 @@ class Amount extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
* @return string|int
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
|
28
app/Helpers/Csv/Converter/AmountComma.php
Normal file
28
app/Helpers/Csv/Converter/AmountComma.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
/**
|
||||
* Class AmountComma
|
||||
*
|
||||
* Parses the input as the amount with a comma as decimal separator
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
class AmountComma extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return float|int
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
$value = str_replace(',', '.', $this->value);
|
||||
|
||||
if (is_numeric($value)) {
|
||||
return floatval($value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -18,8 +18,6 @@ class BasicConverter
|
||||
/** @var array */
|
||||
protected $mapped;
|
||||
/** @var string */
|
||||
protected $role;
|
||||
/** @var string */
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
@ -86,22 +84,6 @@ class BasicConverter
|
||||
$this->mapped = $mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRole()
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $role
|
||||
*/
|
||||
public function setRole($role)
|
||||
{
|
||||
$this->role = $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@ use Auth;
|
||||
use FireflyIII\Models\Budget;
|
||||
|
||||
/**
|
||||
* Class AccountId
|
||||
* Class BudgetId
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
|
@ -24,7 +24,7 @@ class CategoryName extends BasicConverter implements ConverterInterface
|
||||
$category = Category::firstOrCreateEncrypted(
|
||||
[
|
||||
'name' => $this->value,
|
||||
'user_id' => Auth::user()->id
|
||||
'user_id' => Auth::user()->id,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -36,11 +36,6 @@ interface ConverterInterface
|
||||
*/
|
||||
public function setMapped($mapped);
|
||||
|
||||
/**
|
||||
* @param string $role
|
||||
*/
|
||||
public function setRole($role);
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
|
@ -13,7 +13,7 @@ class CurrencyCode extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed|static
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ class CurrencyId extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed|static
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ class CurrencyName extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed|static
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ class CurrencySymbol extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed|static
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ class Date extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return static
|
||||
* @return Carbon
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function convert()
|
||||
|
@ -12,7 +12,7 @@ class Description extends BasicConverter implements ConverterInterface
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class Amount
|
||||
*
|
||||
@ -13,7 +11,7 @@ class Ignore extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Account|null
|
||||
* @return null
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
|
@ -6,7 +6,7 @@ use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class OpposingName
|
||||
* Class OpposingAccountId
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
|
@ -6,7 +6,7 @@ use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class OpposingName
|
||||
* Class OpposingAccountName
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Converter
|
||||
*/
|
||||
|
@ -13,7 +13,7 @@ class RabobankDebetCredit extends BasicConverter implements ConverterInterface
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @return int
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Tag;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
@ -16,7 +15,7 @@ class TagsComma extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Bill
|
||||
* @return Collection
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
|
@ -3,7 +3,6 @@
|
||||
namespace FireflyIII\Helpers\Csv\Converter;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Tag;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
@ -16,7 +15,7 @@ class TagsSpace extends BasicConverter implements ConverterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Bill
|
||||
* @return Collection
|
||||
*/
|
||||
public function convert()
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv;
|
||||
|
||||
use Crypt;
|
||||
@ -16,14 +15,16 @@ class Data
|
||||
|
||||
/** @var string */
|
||||
protected $csvFileContent;
|
||||
|
||||
/** @var string */
|
||||
protected $csvFileLocation;
|
||||
/** @var string */
|
||||
protected $dateFormat;
|
||||
/** @var string */
|
||||
protected $delimiter;
|
||||
/** @var bool */
|
||||
protected $hasHeaders;
|
||||
|
||||
/** @var int */
|
||||
protected $importAccount = 0;
|
||||
/** @var array */
|
||||
protected $map = [];
|
||||
/** @var array */
|
||||
@ -32,15 +33,10 @@ class Data
|
||||
protected $reader;
|
||||
/** @var array */
|
||||
protected $roles = [];
|
||||
|
||||
/** @var array */
|
||||
protected $specifix = [];
|
||||
|
||||
/** @var int */
|
||||
protected $importAccount = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@ -52,6 +48,234 @@ class Data
|
||||
$this->sessionMapped();
|
||||
$this->sessionSpecifix();
|
||||
$this->sessionImportAccount();
|
||||
$this->sessionDelimiter();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCsvFileContent()
|
||||
{
|
||||
return $this->csvFileContent;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $csvFileContent
|
||||
*/
|
||||
public function setCsvFileContent($csvFileContent)
|
||||
{
|
||||
$this->csvFileContent = $csvFileContent;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCsvFileLocation()
|
||||
{
|
||||
return $this->csvFileLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $csvFileLocation
|
||||
*/
|
||||
public function setCsvFileLocation($csvFileLocation)
|
||||
{
|
||||
Session::put('csv-file', $csvFileLocation);
|
||||
$this->csvFileLocation = $csvFileLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDateFormat()
|
||||
{
|
||||
return $this->dateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $dateFormat
|
||||
*/
|
||||
public function setDateFormat($dateFormat)
|
||||
{
|
||||
Session::put('csv-date-format', $dateFormat);
|
||||
$this->dateFormat = $dateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDelimiter()
|
||||
{
|
||||
return $this->delimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $delimiter
|
||||
*/
|
||||
public function setDelimiter($delimiter)
|
||||
{
|
||||
Session::put('csv-delimiter', $delimiter);
|
||||
$this->delimiter = $delimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
return $this->map;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $map
|
||||
*/
|
||||
public function setMap(array $map)
|
||||
{
|
||||
Session::put('csv-map', $map);
|
||||
$this->map = $map;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMapped()
|
||||
{
|
||||
return $this->mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $mapped
|
||||
*/
|
||||
public function setMapped(array $mapped)
|
||||
{
|
||||
Session::put('csv-mapped', $mapped);
|
||||
$this->mapped = $mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Reader
|
||||
*/
|
||||
public function getReader()
|
||||
{
|
||||
if (strlen($this->csvFileContent) === 0) {
|
||||
$this->loadCsvFile();
|
||||
}
|
||||
|
||||
if (is_null($this->reader)) {
|
||||
$this->reader = Reader::createFromString($this->getCsvFileContent());
|
||||
$this->reader->setDelimiter($this->delimiter);
|
||||
}
|
||||
|
||||
return $this->reader;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRoles()
|
||||
{
|
||||
return $this->roles;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $roles
|
||||
*/
|
||||
public function setRoles(array $roles)
|
||||
{
|
||||
Session::put('csv-roles', $roles);
|
||||
$this->roles = $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSpecifix()
|
||||
{
|
||||
return is_array($this->specifix) ? $this->specifix : [];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $specifix
|
||||
*/
|
||||
public function setSpecifix(array $specifix)
|
||||
{
|
||||
Session::put('csv-specifix', $specifix);
|
||||
$this->specifix = $specifix;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasHeaders()
|
||||
{
|
||||
return $this->hasHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bool $hasHeaders
|
||||
*/
|
||||
public function setHasHeaders($hasHeaders)
|
||||
{
|
||||
Session::put('csv-has-headers', $hasHeaders);
|
||||
$this->hasHeaders = $hasHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param int $importAccount
|
||||
*/
|
||||
public function setImportAccount($importAccount)
|
||||
{
|
||||
Session::put('csv-import-account', $importAccount);
|
||||
$this->importAccount = $importAccount;
|
||||
}
|
||||
|
||||
protected function loadCsvFile()
|
||||
{
|
||||
$file = $this->getCsvFileLocation();
|
||||
$content = file_get_contents($file);
|
||||
$contentDecrypted = Crypt::decrypt($content);
|
||||
$this->setCsvFileContent($contentDecrypted);
|
||||
}
|
||||
|
||||
protected function sessionCsvFileLocation()
|
||||
{
|
||||
if (Session::has('csv-file')) {
|
||||
$this->csvFileLocation = (string)Session::get('csv-file');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionDateFormat()
|
||||
{
|
||||
if (Session::has('csv-date-format')) {
|
||||
$this->dateFormat = (string)Session::get('csv-date-format');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionDelimiter()
|
||||
{
|
||||
if (Session::has('csv-delimiter')) {
|
||||
$this->delimiter = Session::get('csv-delimiter');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionHasHeaders()
|
||||
@ -68,20 +292,6 @@ class Data
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionDateFormat()
|
||||
{
|
||||
if (Session::has('csv-date-format')) {
|
||||
$this->dateFormat = (string)Session::get('csv-date-format');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionCsvFileLocation()
|
||||
{
|
||||
if (Session::has('csv-file')) {
|
||||
$this->csvFileLocation = (string)Session::get('csv-file');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionMap()
|
||||
{
|
||||
if (Session::has('csv-map')) {
|
||||
@ -89,13 +299,6 @@ class Data
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionRoles()
|
||||
{
|
||||
if (Session::has('csv-roles')) {
|
||||
$this->roles = (array)Session::get('csv-roles');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionMapped()
|
||||
{
|
||||
if (Session::has('csv-mapped')) {
|
||||
@ -103,181 +306,17 @@ class Data
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionRoles()
|
||||
{
|
||||
if (Session::has('csv-roles')) {
|
||||
$this->roles = (array)Session::get('csv-roles');
|
||||
}
|
||||
}
|
||||
|
||||
protected function sessionSpecifix()
|
||||
{
|
||||
if (Session::has('csv-specifix')) {
|
||||
$this->specifix = (array)Session::get('csv-specifix');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDateFormat()
|
||||
{
|
||||
return $this->dateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $dateFormat
|
||||
*/
|
||||
public function setDateFormat($dateFormat)
|
||||
{
|
||||
Session::put('csv-date-format', $dateFormat);
|
||||
$this->dateFormat = $dateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $importAccount
|
||||
*/
|
||||
public function setImportAccount($importAccount)
|
||||
{
|
||||
Session::put('csv-import-account', $importAccount);
|
||||
$this->importAccount = $importAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasHeaders()
|
||||
{
|
||||
return $this->hasHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hasHeaders
|
||||
*/
|
||||
public function setHasHeaders($hasHeaders)
|
||||
{
|
||||
Session::put('csv-has-headers', $hasHeaders);
|
||||
$this->hasHeaders = $hasHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
return $this->map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $map
|
||||
*/
|
||||
public function setMap(array $map)
|
||||
{
|
||||
Session::put('csv-map', $map);
|
||||
$this->map = $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMapped()
|
||||
{
|
||||
return $this->mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $mapped
|
||||
*/
|
||||
public function setMapped(array $mapped)
|
||||
{
|
||||
Session::put('csv-mapped', $mapped);
|
||||
$this->mapped = $mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Reader
|
||||
*/
|
||||
public function getReader()
|
||||
{
|
||||
|
||||
if (strlen($this->csvFileContent) === 0) {
|
||||
$this->loadCsvFile();
|
||||
}
|
||||
|
||||
if (is_null($this->reader)) {
|
||||
$this->reader = Reader::createFromString($this->getCsvFileContent());
|
||||
}
|
||||
|
||||
return $this->reader;
|
||||
}
|
||||
|
||||
protected function loadCsvFile()
|
||||
{
|
||||
$file = $this->getCsvFileLocation();
|
||||
$content = file_get_contents($file);
|
||||
$contentDecrypted = Crypt::decrypt($content);
|
||||
$this->setCsvFileContent($contentDecrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCsvFileLocation()
|
||||
{
|
||||
return $this->csvFileLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $csvFileLocation
|
||||
*/
|
||||
public function setCsvFileLocation($csvFileLocation)
|
||||
{
|
||||
Session::put('csv-file', $csvFileLocation);
|
||||
$this->csvFileLocation = $csvFileLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCsvFileContent()
|
||||
{
|
||||
return $this->csvFileContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $csvFileContent
|
||||
*/
|
||||
public function setCsvFileContent($csvFileContent)
|
||||
{
|
||||
$this->csvFileContent = $csvFileContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getRoles()
|
||||
{
|
||||
return $this->roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $roles
|
||||
*/
|
||||
public function setRoles(array $roles)
|
||||
{
|
||||
Session::put('csv-roles', $roles);
|
||||
$this->roles = $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSpecifix()
|
||||
{
|
||||
return is_array($this->specifix) ? $this->specifix : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $specifix
|
||||
*/
|
||||
public function setSpecifix($specifix)
|
||||
{
|
||||
Session::put('csv-specifix', $specifix);
|
||||
$this->specifix = $specifix;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ class Importer
|
||||
protected $importRow;
|
||||
/** @var int */
|
||||
protected $imported = 0;
|
||||
/** @var Collection */
|
||||
protected $journals;
|
||||
/** @var array */
|
||||
protected $map;
|
||||
/** @var array */
|
||||
@ -45,9 +47,6 @@ class Importer
|
||||
/** @var array */
|
||||
protected $specifix = [];
|
||||
|
||||
/** @var Collection */
|
||||
protected $journals;
|
||||
|
||||
/**
|
||||
* Used by CsvController.
|
||||
*
|
||||
@ -68,6 +67,14 @@ class Importer
|
||||
return $this->imported;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournals()
|
||||
{
|
||||
return $this->journals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by CsvController
|
||||
*
|
||||
@ -79,14 +86,13 @@ class Importer
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
* @return array
|
||||
*/
|
||||
public function getJournals()
|
||||
public function getSpecifix()
|
||||
{
|
||||
return $this->journals;
|
||||
return is_array($this->specifix) ? $this->specifix : [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws FireflyException
|
||||
*/
|
||||
@ -118,136 +124,11 @@ class Importer
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
*
|
||||
* @return bool
|
||||
* @param Data $data
|
||||
*/
|
||||
protected function parseRow($index)
|
||||
public function setData($data)
|
||||
{
|
||||
return (($this->data->hasHeaders() && $index >= 1) || !$this->data->hasHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return string|bool
|
||||
*/
|
||||
protected function importRow($row)
|
||||
{
|
||||
|
||||
$data = $this->getFiller(); // These fields are necessary to create a new transaction journal. Some are optional
|
||||
foreach ($row as $index => $value) {
|
||||
$role = isset($this->roles[$index]) ? $this->roles[$index] : '_ignore';
|
||||
$class = Config::get('csv.roles.' . $role . '.converter');
|
||||
$field = Config::get('csv.roles.' . $role . '.field');
|
||||
|
||||
Log::debug('Column #' . $index . ' (role: ' . $role . ') : converter ' . $class . ' stores its data into field ' . $field . ':');
|
||||
|
||||
/** @var ConverterInterface $converter */
|
||||
$converter = app('FireflyIII\Helpers\Csv\Converter\\' . $class);
|
||||
$converter->setData($data); // the complete array so far.
|
||||
$converter->setField($field);
|
||||
$converter->setIndex($index);
|
||||
$converter->setMapped($this->mapped);
|
||||
$converter->setValue($value);
|
||||
$converter->setRole($role);
|
||||
$data[$field] = $converter->convert();
|
||||
}
|
||||
// move to class vars.
|
||||
$this->importData = $data;
|
||||
$this->importRow = $row;
|
||||
unset($data, $row);
|
||||
// post processing and validating.
|
||||
$this->postProcess();
|
||||
$result = $this->validateData();
|
||||
|
||||
if (!($result === true)) {
|
||||
return $result; // return error.
|
||||
}
|
||||
$journal = $this->createTransactionJournal();
|
||||
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getFiller()
|
||||
{
|
||||
$filler = [];
|
||||
foreach (Config::get('csv.roles') as $role) {
|
||||
if (isset($role['field'])) {
|
||||
$fieldName = $role['field'];
|
||||
$filler[$fieldName] = null;
|
||||
}
|
||||
}
|
||||
// some extra's:
|
||||
$filler['bill-id'] = null;
|
||||
$filler['opposing-account-object'] = null;
|
||||
$filler['asset-account-object'] = null;
|
||||
$filler['amount-modifier'] = '1';
|
||||
|
||||
return $filler;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Row denotes the original data.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function postProcess()
|
||||
{
|
||||
// do bank specific fixes (must be enabled but now all of them.
|
||||
|
||||
foreach ($this->getSpecifix() as $className) {
|
||||
/** @var SpecifixInterface $specifix */
|
||||
$specifix = app('FireflyIII\Helpers\Csv\Specifix\\' . $className);
|
||||
$specifix->setData($this->importData);
|
||||
$specifix->setRow($this->importRow);
|
||||
Log::debug('Now post-process specifix named ' . $className . ':');
|
||||
$this->importData = $specifix->fix();
|
||||
}
|
||||
|
||||
|
||||
$set = Config::get('csv.post_processors');
|
||||
foreach ($set as $className) {
|
||||
/** @var PostProcessorInterface $postProcessor */
|
||||
$postProcessor = app('FireflyIII\Helpers\Csv\PostProcessing\\' . $className);
|
||||
$postProcessor->setData($this->importData);
|
||||
Log::debug('Now post-process processor named ' . $className . ':');
|
||||
$this->importData = $postProcessor->process();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSpecifix()
|
||||
{
|
||||
return is_array($this->specifix) ? $this->specifix : [];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function validateData()
|
||||
{
|
||||
if (is_null($this->importData['date']) && is_null($this->importData['date-rent'])) {
|
||||
return 'No date value for this row.';
|
||||
}
|
||||
if (is_null($this->importData['opposing-account-object'])) {
|
||||
return 'Opposing account is null';
|
||||
}
|
||||
|
||||
if (!($this->importData['asset-account-object'] instanceof Account)) {
|
||||
return 'No asset account to import into.';
|
||||
}
|
||||
|
||||
return true;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -309,6 +190,28 @@ class Importer
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getFiller()
|
||||
{
|
||||
$filler = [];
|
||||
foreach (Config::get('csv.roles') as $role) {
|
||||
if (isset($role['field'])) {
|
||||
$fieldName = $role['field'];
|
||||
$filler[$fieldName] = null;
|
||||
}
|
||||
}
|
||||
// some extra's:
|
||||
$filler['bill-id'] = null;
|
||||
$filler['opposing-account-object'] = null;
|
||||
$filler['asset-account-object'] = null;
|
||||
$filler['amount-modifier'] = '1';
|
||||
|
||||
return $filler;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TransactionType
|
||||
*/
|
||||
@ -326,6 +229,92 @@ class Importer
|
||||
return $transactionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
*
|
||||
* @throws FireflyException
|
||||
* @return string|bool
|
||||
*/
|
||||
protected function importRow($row)
|
||||
{
|
||||
|
||||
$data = $this->getFiller(); // These fields are necessary to create a new transaction journal. Some are optional
|
||||
foreach ($row as $index => $value) {
|
||||
$role = isset($this->roles[$index]) ? $this->roles[$index] : '_ignore';
|
||||
$class = Config::get('csv.roles.' . $role . '.converter');
|
||||
$field = Config::get('csv.roles.' . $role . '.field');
|
||||
|
||||
Log::debug('Column #' . $index . ' (role: ' . $role . ') : converter ' . $class . ' stores its data into field ' . $field . ':');
|
||||
|
||||
// here would be the place where preprocessors would fire.
|
||||
|
||||
/** @var ConverterInterface $converter */
|
||||
$converter = app('FireflyIII\Helpers\Csv\Converter\\' . $class);
|
||||
$converter->setData($data); // the complete array so far.
|
||||
$converter->setField($field);
|
||||
$converter->setIndex($index);
|
||||
$converter->setMapped($this->mapped);
|
||||
$converter->setValue($value);
|
||||
$data[$field] = $converter->convert();
|
||||
}
|
||||
// move to class vars.
|
||||
$this->importData = $data;
|
||||
$this->importRow = $row;
|
||||
unset($data, $row);
|
||||
// post processing and validating.
|
||||
$this->postProcess();
|
||||
$result = $this->validateData();
|
||||
|
||||
if (!($result === true)) {
|
||||
return $result; // return error.
|
||||
}
|
||||
$journal = $this->createTransactionJournal();
|
||||
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function parseRow($index)
|
||||
{
|
||||
return (($this->data->hasHeaders() && $index >= 1) || !$this->data->hasHeaders());
|
||||
}
|
||||
|
||||
/**
|
||||
* Row denotes the original data.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function postProcess()
|
||||
{
|
||||
// do bank specific fixes (must be enabled but now all of them.
|
||||
|
||||
foreach ($this->getSpecifix() as $className) {
|
||||
/** @var SpecifixInterface $specifix */
|
||||
$specifix = app('FireflyIII\Helpers\Csv\Specifix\\' . $className);
|
||||
if ($specifix->getProcessorType() == SpecifixInterface::POST_PROCESSOR) {
|
||||
$specifix->setData($this->importData);
|
||||
$specifix->setRow($this->importRow);
|
||||
Log::debug('Now post-process specifix named ' . $className . ':');
|
||||
$this->importData = $specifix->fix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$set = Config::get('csv.post_processors');
|
||||
foreach ($set as $className) {
|
||||
/** @var PostProcessorInterface $postProcessor */
|
||||
$postProcessor = app('FireflyIII\Helpers\Csv\PostProcessing\\' . $className);
|
||||
$postProcessor->setData($this->importData);
|
||||
Log::debug('Now post-process processor named ' . $className . ':');
|
||||
$this->importData = $postProcessor->process();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*/
|
||||
@ -361,11 +350,23 @@ class Importer
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Data $data
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function setData($data)
|
||||
protected function validateData()
|
||||
{
|
||||
$this->data = $data;
|
||||
if (is_null($this->importData['date']) && is_null($this->importData['date-rent'])) {
|
||||
return 'No date value for this row.';
|
||||
}
|
||||
if (is_null($this->importData['opposing-account-object'])) {
|
||||
return 'Opposing account is null';
|
||||
}
|
||||
|
||||
if (!($this->importData['asset-account-object'] instanceof Account)) {
|
||||
return 'No asset account to import into.';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,4 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 05/07/15
|
||||
* Time: 19:20
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\PostProcessing;
|
||||
|
||||
|
185
app/Helpers/Csv/Specifix/AbnAmroDescription.php
Normal file
185
app/Helpers/Csv/Specifix/AbnAmroDescription.php
Normal file
@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Specifix;
|
||||
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Parses the description from txt files for ABN AMRO bank accounts.
|
||||
*
|
||||
* Based on the logic as described in the following Gist:
|
||||
* https://gist.github.com/vDorst/68d555a6a90f62fec004
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Specifix
|
||||
*/
|
||||
class AbnAmroDescription extends Specifix implements SpecifixInterface
|
||||
{
|
||||
/** @var array */
|
||||
protected $data;
|
||||
|
||||
/** @var array */
|
||||
protected $row;
|
||||
|
||||
/**
|
||||
* AbnAmroDescription constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->setProcessorType(self::POST_PROCESSOR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function fix()
|
||||
{
|
||||
// Try to parse the description in known formats.
|
||||
$parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription();
|
||||
|
||||
// If the description could not be parsed, specify an unknown opposing
|
||||
// account, as an opposing account is required
|
||||
if (!$parsed) {
|
||||
$this->data['opposing-account-name'] = trans('firefly.unknown');
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
*/
|
||||
public function setRow($row)
|
||||
{
|
||||
$this->row = $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current description with costs from ABN AMRO itself
|
||||
*
|
||||
* @return boolean true if the description is GEA/BEA-format, false otherwise
|
||||
*/
|
||||
protected function parseABNAMRODescription()
|
||||
{
|
||||
// See if the current description is formatted in ABN AMRO format
|
||||
if (preg_match('/ABN AMRO.{24} (.*)/', $this->data['description'], $matches)) {
|
||||
Log::debug('AbnAmroSpecifix: Description is structured as costs from ABN AMRO itself.');
|
||||
|
||||
$this->data['opposing-account-name'] = "ABN AMRO";
|
||||
$this->data['description'] = $matches[1];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current description in GEA/BEA format
|
||||
*
|
||||
* @return boolean true if the description is GEA/BEAformat, false otherwise
|
||||
*/
|
||||
protected function parseGEABEADescription()
|
||||
{
|
||||
// See if the current description is formatted in GEA/BEA format
|
||||
if (preg_match('/([BG]EA) +(NR:[a-zA-Z:0-9]+) +([0-9.\/]+) +([^,]*)/', $this->data['description'], $matches)) {
|
||||
Log::debug('AbnAmroSpecifix: Description is structured as GEA or BEA format.');
|
||||
|
||||
// description and opposing account will be the same.
|
||||
$this->data['opposing-account-name'] = $matches[4];
|
||||
$this->data['description'] = $matches[4];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current description in SEPA format
|
||||
*
|
||||
* @return boolean true if the description is SEPA format, false otherwise
|
||||
*/
|
||||
protected function parseSepaDescription()
|
||||
{
|
||||
// See if the current description is formatted as a SEPA plain description
|
||||
if (preg_match('/^SEPA(.{28})/', $this->data['description'], $matches)) {
|
||||
Log::debug('AbnAmroSpecifix: Description is structured as SEPA plain description.');
|
||||
|
||||
// SEPA plain descriptions contain several key-value pairs, split by a colon
|
||||
preg_match_all('/([A-Za-z]+(?=:\s)):\s([A-Za-z 0-9._#-]+(?=\s))/', $this->data['description'], $matches, PREG_SET_ORDER);
|
||||
|
||||
foreach ($matches as $match) {
|
||||
$key = $match[1];
|
||||
$value = trim($match[2]);
|
||||
|
||||
switch (strtoupper($key)) {
|
||||
case 'OMSCHRIJVING':
|
||||
$this->data['description'] = $value;
|
||||
break;
|
||||
case 'NAAM':
|
||||
$this->data['opposing-account-name'] = $value;
|
||||
break;
|
||||
case 'IBAN':
|
||||
$this->data['opposing-account-iban'] = $value;
|
||||
break;
|
||||
default:
|
||||
// Ignore the rest
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the current description in TRTP format
|
||||
*
|
||||
* @return boolean true if the description is TRTP format, false otherwise
|
||||
*/
|
||||
protected function parseTRTPDescription()
|
||||
{
|
||||
// See if the current description is formatted in TRTP format
|
||||
if (preg_match_all('!\/([A-Z]{3,4})\/([^/]*)!', $this->data['description'], $matches, PREG_SET_ORDER)) {
|
||||
Log::debug('AbnAmroSpecifix: Description is structured as TRTP format.');
|
||||
|
||||
foreach ($matches as $match) {
|
||||
$key = $match[1];
|
||||
$value = trim($match[2]);
|
||||
|
||||
switch (strtoupper($key)) {
|
||||
// is not being used.
|
||||
// case 'TRTP':
|
||||
// $type = $value;
|
||||
// break;
|
||||
case 'NAME':
|
||||
$this->data['opposing-account-name'] = $value;
|
||||
break;
|
||||
case 'REMI':
|
||||
$this->data['description'] = $value;
|
||||
break;
|
||||
case 'IBAN':
|
||||
$this->data['opposing-account-iban'] = $value;
|
||||
break;
|
||||
default:
|
||||
// Ignore the rest
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -7,7 +7,7 @@ namespace FireflyIII\Helpers\Csv\Specifix;
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Specifix
|
||||
*/
|
||||
class Dummy
|
||||
class Dummy extends Specifix implements SpecifixInterface
|
||||
{
|
||||
/** @var array */
|
||||
protected $data;
|
||||
@ -15,6 +15,13 @@ class Dummy
|
||||
/** @var array */
|
||||
protected $row;
|
||||
|
||||
/**
|
||||
* Dummy constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->setProcessorType(self::POST_PROCESSOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
|
@ -9,7 +9,7 @@ use Log;
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Specifix
|
||||
*/
|
||||
class RabobankDescription
|
||||
class RabobankDescription extends Specifix implements SpecifixInterface
|
||||
{
|
||||
/** @var array */
|
||||
protected $data;
|
||||
@ -17,6 +17,14 @@ class RabobankDescription
|
||||
/** @var array */
|
||||
protected $row;
|
||||
|
||||
/**
|
||||
* RabobankDescription constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->setProcessorType(self::POST_PROCESSOR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
|
44
app/Helpers/Csv/Specifix/Specifix.php
Normal file
44
app/Helpers/Csv/Specifix/Specifix.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Specifix.php
|
||||
* Copyright (C) 2016 Sander Dorigo
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Helpers\Csv\Specifix;
|
||||
|
||||
/**
|
||||
* Class Specifix
|
||||
*
|
||||
* @package FireflyIII\Helpers\Csv\Specifix
|
||||
*/
|
||||
class Specifix
|
||||
{
|
||||
|
||||
/** @var int */
|
||||
protected $processorType;
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getProcessorType()
|
||||
{
|
||||
return $this->processorType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $processorType
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setProcessorType($processorType)
|
||||
{
|
||||
$this->processorType = $processorType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -8,16 +8,30 @@ namespace FireflyIII\Helpers\Csv\Specifix;
|
||||
*/
|
||||
interface SpecifixInterface
|
||||
{
|
||||
const PRE_PROCESSOR = 1;
|
||||
const POST_PROCESSOR = 2;
|
||||
/**
|
||||
* Implement bank and locale related fixes.
|
||||
*/
|
||||
public function fix();
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getProcessorType();
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData($data);
|
||||
|
||||
/**
|
||||
* @param int $processorType
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setProcessorType($processorType);
|
||||
|
||||
/**
|
||||
* @param array $row
|
||||
*/
|
||||
|
@ -63,7 +63,8 @@ class Wizard implements WizardInterface
|
||||
|
||||
|
||||
if (is_array($map)) {
|
||||
foreach ($map as $index => $field) {
|
||||
$keys = array_keys($map);
|
||||
foreach ($keys as $index) {
|
||||
if (isset($roles[$index])) {
|
||||
$name = $roles[$index];
|
||||
if ($configRoles[$name]['mappable']) {
|
||||
@ -167,17 +168,6 @@ class Wizard implements WizardInterface
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hasHeaders
|
||||
* @param int $index
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function useRow($hasHeaders, $index)
|
||||
{
|
||||
return ($hasHeaders && $index > 1) || !$hasHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
*
|
||||
@ -191,4 +181,15 @@ class Wizard implements WizardInterface
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $hasHeaders
|
||||
* @param int $index
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function useRow($hasHeaders, $index)
|
||||
{
|
||||
return ($hasHeaders && $index > 1) || !$hasHeaders;
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,12 @@ use FireflyIII\Helpers\Collection\Income;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget as BudgetModel;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@ -32,81 +35,27 @@ use Illuminate\Support\Collection;
|
||||
class ReportHelper implements ReportHelperInterface
|
||||
{
|
||||
|
||||
/** @var BudgetRepositoryInterface */
|
||||
protected $budgetRepository;
|
||||
/** @var ReportQueryInterface */
|
||||
protected $query;
|
||||
/** @var TagRepositoryInterface */
|
||||
protected $tagRepository;
|
||||
|
||||
/**
|
||||
* ReportHelper constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param ReportQueryInterface $query
|
||||
*
|
||||
* @param ReportQueryInterface $query
|
||||
* @param BudgetRepositoryInterface $budgetRepository
|
||||
* @param TagRepositoryInterface $tagRepository
|
||||
*/
|
||||
public function __construct(ReportQueryInterface $query)
|
||||
public function __construct(ReportQueryInterface $query, BudgetRepositoryInterface $budgetRepository, TagRepositoryInterface $tagRepository)
|
||||
{
|
||||
$this->query = $query;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return CategoryCollection
|
||||
*/
|
||||
public function getCategoryReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$object = new CategoryCollection;
|
||||
|
||||
/**
|
||||
* GET CATEGORIES:
|
||||
*/
|
||||
/** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
|
||||
|
||||
$set = $repository->spentForAccountsPerMonth($accounts, $start, $end);
|
||||
foreach ($set as $category) {
|
||||
$object->addCategory($category);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfMonths(Carbon $date)
|
||||
{
|
||||
|
||||
$start = clone $date;
|
||||
$end = Carbon::now();
|
||||
$months = [];
|
||||
while ($start <= $end) {
|
||||
$year = $start->year;
|
||||
|
||||
if (!isset($months[$year])) {
|
||||
$months[$year] = [
|
||||
'start' => Carbon::createFromDate($year, 1, 1)->format('Y-m-d'),
|
||||
'end' => Carbon::createFromDate($year, 12, 31)->format('Y-m-d'),
|
||||
'months' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$currentEnd = clone $start;
|
||||
$currentEnd->endOfMonth();
|
||||
$months[$year]['months'][] = [
|
||||
'formatted' => $start->formatLocalized('%B %Y'),
|
||||
'start' => $start->format('Y-m-d'),
|
||||
'end' => $currentEnd->format('Y-m-d'),
|
||||
'month' => $start->month,
|
||||
'year' => $year,
|
||||
];
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
return $months;
|
||||
$this->query = $query;
|
||||
$this->budgetRepository = $budgetRepository;
|
||||
$this->tagRepository = $tagRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -198,47 +147,86 @@ class ReportHelper implements ReportHelperInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a full report on the users incomes during the period for the given accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Income
|
||||
* @return Balance
|
||||
*/
|
||||
public function getIncomeReport($start, $end, Collection $accounts)
|
||||
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$object = new Income;
|
||||
$set = $this->query->income($accounts, $start, $end);
|
||||
$balance = new Balance;
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$object->addToTotal($entry->journalAmount);
|
||||
$object->addOrCreateIncome($entry);
|
||||
// build a balance header:
|
||||
$header = new BalanceHeader;
|
||||
$budgets = $this->budgetRepository->getBudgetsAndLimitsInRange($start, $end);
|
||||
$spentData = $this->budgetRepository->spentPerBudgetPerAccount($budgets, $accounts, $start, $end);
|
||||
foreach ($accounts as $account) {
|
||||
$header->addAccount($account);
|
||||
}
|
||||
|
||||
return $object;
|
||||
/** @var BudgetModel $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
$balance->addBalanceLine($this->createBalanceLine($budget, $accounts, $spentData));
|
||||
}
|
||||
|
||||
$balance->addBalanceLine($this->createEmptyBalanceLine($accounts, $spentData));
|
||||
$balance->addBalanceLine($this->createTagsBalanceLine($accounts, $start, $end));
|
||||
$balance->addBalanceLine($this->createDifferenceBalanceLine($accounts, $spentData, $start, $end));
|
||||
|
||||
$balance->setBalanceHeader($header);
|
||||
|
||||
return $balance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a full report on the users expenses during the period for a list of accounts.
|
||||
* This method generates a full report for the given period on all
|
||||
* the users bills and their payments.
|
||||
*
|
||||
* Excludes bills which have not had a payment on the mentioned accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Expense
|
||||
* @return BillCollection
|
||||
*/
|
||||
public function getExpenseReport($start, $end, Collection $accounts)
|
||||
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$object = new Expense;
|
||||
$set = $this->query->expense($accounts, $start, $end);
|
||||
/** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
|
||||
$bills = $repository->getBillsForAccounts($accounts);
|
||||
$journals = $repository->getAllJournalsInRange($bills, $start, $end);
|
||||
$collection = new BillCollection;
|
||||
|
||||
/** @var Bill $bill */
|
||||
foreach ($bills as $bill) {
|
||||
$billLine = new BillLine;
|
||||
$billLine->setBill($bill);
|
||||
$billLine->setActive(intval($bill->active) == 1);
|
||||
$billLine->setMin($bill->amount_min);
|
||||
$billLine->setMax($bill->amount_max);
|
||||
|
||||
// is hit in period?
|
||||
bcscale(2);
|
||||
|
||||
$entry = $journals->filter(
|
||||
function (TransactionJournal $journal) use ($bill) {
|
||||
return $journal->bill_id == $bill->id;
|
||||
}
|
||||
);
|
||||
if (!is_null($entry->first())) {
|
||||
$billLine->setAmount($entry->first()->journalAmount);
|
||||
$billLine->setHit(true);
|
||||
} else {
|
||||
$billLine->setHit(false);
|
||||
}
|
||||
|
||||
$collection->addBill($billLine);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$object->addToTotal($entry->journalAmount); // can be positive, if it's a transfer
|
||||
$object->addOrCreateExpense($entry);
|
||||
}
|
||||
|
||||
return $object;
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -325,163 +313,105 @@ class ReportHelper implements ReportHelperInterface
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Balance
|
||||
* @return CategoryCollection
|
||||
*/
|
||||
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
public function getCategoryReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
/** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
|
||||
$object = new CategoryCollection;
|
||||
|
||||
/** @var \FireflyIII\Repositories\Tag\TagRepositoryInterface $tagRepository */
|
||||
$tagRepository = app('FireflyIII\Repositories\Tag\TagRepositoryInterface');
|
||||
/**
|
||||
* GET CATEGORIES:
|
||||
*/
|
||||
/** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
|
||||
|
||||
$balance = new Balance;
|
||||
|
||||
// build a balance header:
|
||||
$header = new BalanceHeader;
|
||||
$budgets = $repository->getBudgetsAndLimitsInRange($start, $end);
|
||||
$spentData = $repository->spentPerBudgetPerAccount($budgets, $accounts, $start, $end);
|
||||
foreach ($accounts as $account) {
|
||||
$header->addAccount($account);
|
||||
$set = $repository->spentForAccountsPerMonth($accounts, $start, $end);
|
||||
foreach ($set as $category) {
|
||||
$object->addCategory($category);
|
||||
}
|
||||
|
||||
/** @var BudgetModel $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
$line = new BalanceLine;
|
||||
$line->setBudget($budget);
|
||||
|
||||
// loop accounts:
|
||||
foreach ($accounts as $account) {
|
||||
$balanceEntry = new BalanceEntry;
|
||||
$balanceEntry->setAccount($account);
|
||||
|
||||
// get spent:
|
||||
$entry = $spentData->filter(
|
||||
function (TransactionJournal $model) use ($budget, $account) {
|
||||
return $model->account_id == $account->id && $model->budget_id == $budget->id;
|
||||
}
|
||||
);
|
||||
$spent = 0;
|
||||
if (!is_null($entry->first())) {
|
||||
$spent = $entry->first()->spent;
|
||||
}
|
||||
$balanceEntry->setSpent($spent);
|
||||
$line->addBalanceEntry($balanceEntry);
|
||||
}
|
||||
// add line to balance:
|
||||
$balance->addBalanceLine($line);
|
||||
}
|
||||
|
||||
// then a new line for without budget.
|
||||
// and one for the tags:
|
||||
// and one for "left unbalanced".
|
||||
$empty = new BalanceLine;
|
||||
$tags = new BalanceLine;
|
||||
$diffLine = new BalanceLine;
|
||||
$tagsLeft = $tagRepository->allCoveredByBalancingActs($accounts, $start, $end);
|
||||
|
||||
$tags->setRole(BalanceLine::ROLE_TAGROLE);
|
||||
$diffLine->setRole(BalanceLine::ROLE_DIFFROLE);
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$entry = $spentData->filter(
|
||||
function (TransactionJournal $model) use ($account) {
|
||||
return $model->account_id == $account->id && is_null($model->budget_id);
|
||||
}
|
||||
);
|
||||
$spent = 0;
|
||||
if (!is_null($entry->first())) {
|
||||
$spent = $entry->first()->spent;
|
||||
}
|
||||
$leftEntry = $tagsLeft->filter(
|
||||
function (Tag $tag) use ($account) {
|
||||
return $tag->account_id == $account->id;
|
||||
}
|
||||
);
|
||||
$left = 0;
|
||||
if (!is_null($leftEntry->first())) {
|
||||
$left = $leftEntry->first()->sum;
|
||||
}
|
||||
bcscale(2);
|
||||
$diff = bcadd($spent, $left);
|
||||
|
||||
// budget
|
||||
$budgetEntry = new BalanceEntry;
|
||||
$budgetEntry->setAccount($account);
|
||||
$budgetEntry->setSpent($spent);
|
||||
$empty->addBalanceEntry($budgetEntry);
|
||||
|
||||
// balanced by tags
|
||||
$tagEntry = new BalanceEntry;
|
||||
$tagEntry->setAccount($account);
|
||||
$tagEntry->setLeft($left);
|
||||
$tags->addBalanceEntry($tagEntry);
|
||||
|
||||
// difference:
|
||||
$diffEntry = new BalanceEntry;
|
||||
$diffEntry->setAccount($account);
|
||||
$diffEntry->setSpent($diff);
|
||||
$diffLine->addBalanceEntry($diffEntry);
|
||||
|
||||
}
|
||||
|
||||
$balance->addBalanceLine($empty);
|
||||
$balance->addBalanceLine($tags);
|
||||
$balance->addBalanceLine($diffLine);
|
||||
|
||||
$balance->setBalanceHeader($header);
|
||||
|
||||
return $balance;
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method generates a full report for the given period on all
|
||||
* the users bills and their payments.
|
||||
*
|
||||
* Excludes bills which have not had a payment on the mentioned accounts.
|
||||
* Get a full report on the users expenses during the period for a list of accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return BillCollection
|
||||
* @return Expense
|
||||
*/
|
||||
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
public function getExpenseReport($start, $end, Collection $accounts)
|
||||
{
|
||||
/** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
|
||||
$bills = $repository->getBillsForAccounts($accounts);
|
||||
$journals = $repository->getAllJournalsInRange($bills, $start, $end);
|
||||
$collection = new BillCollection;
|
||||
|
||||
/** @var Bill $bill */
|
||||
foreach ($bills as $bill) {
|
||||
$billLine = new BillLine;
|
||||
$billLine->setBill($bill);
|
||||
$billLine->setActive(intval($bill->active) == 1);
|
||||
$billLine->setMin($bill->amount_min);
|
||||
$billLine->setMax($bill->amount_max);
|
||||
|
||||
// is hit in period?
|
||||
bcscale(2);
|
||||
|
||||
$entry = $journals->filter(
|
||||
function (TransactionJournal $journal) use ($bill) {
|
||||
return $journal->bill_id == $bill->id;
|
||||
}
|
||||
);
|
||||
if (!is_null($entry->first())) {
|
||||
$billLine->setAmount($entry->first()->journalAmount);
|
||||
$billLine->setHit(true);
|
||||
} else {
|
||||
$billLine->setHit(false);
|
||||
}
|
||||
|
||||
$collection->addBill($billLine);
|
||||
$object = new Expense;
|
||||
$set = $this->query->expense($accounts, $start, $end);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$object->addToTotal($entry->journalAmount); // can be positive, if it's a transfer
|
||||
$object->addOrCreateExpense($entry);
|
||||
}
|
||||
|
||||
return $collection;
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a full report on the users incomes during the period for the given accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Income
|
||||
*/
|
||||
public function getIncomeReport($start, $end, Collection $accounts)
|
||||
{
|
||||
$object = new Income;
|
||||
$set = $this->query->income($accounts, $start, $end);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$object->addToTotal($entry->journalAmount);
|
||||
$object->addOrCreateIncome($entry);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfMonths(Carbon $date)
|
||||
{
|
||||
|
||||
$start = clone $date;
|
||||
$end = Carbon::now();
|
||||
$months = [];
|
||||
while ($start <= $end) {
|
||||
$year = $start->year;
|
||||
|
||||
if (!isset($months[$year])) {
|
||||
$months[$year] = [
|
||||
'start' => Carbon::createFromDate($year, 1, 1)->format('Y-m-d'),
|
||||
'end' => Carbon::createFromDate($year, 12, 31)->format('Y-m-d'),
|
||||
'months' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$currentEnd = clone $start;
|
||||
$currentEnd->endOfMonth();
|
||||
$months[$year]['months'][] = [
|
||||
'formatted' => $start->formatLocalized('%B %Y'),
|
||||
'start' => $start->format('Y-m-d'),
|
||||
'end' => $currentEnd->format('Y-m-d'),
|
||||
'month' => $start->month,
|
||||
'year' => $year,
|
||||
];
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
return $months;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -511,4 +441,157 @@ class ReportHelper implements ReportHelperInterface
|
||||
|
||||
return $sum;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Collection $accounts
|
||||
* @param Collection $spentData
|
||||
*
|
||||
* @return BalanceLine
|
||||
*/
|
||||
private function createBalanceLine(BudgetModel $budget, Collection $accounts, Collection $spentData)
|
||||
{
|
||||
$line = new BalanceLine;
|
||||
$line->setBudget($budget);
|
||||
|
||||
// loop accounts:
|
||||
foreach ($accounts as $account) {
|
||||
$balanceEntry = new BalanceEntry;
|
||||
$balanceEntry->setAccount($account);
|
||||
|
||||
// get spent:
|
||||
$entry = $spentData->filter(
|
||||
function (TransactionJournal $model) use ($budget, $account) {
|
||||
return $model->account_id == $account->id && $model->budget_id == $budget->id;
|
||||
}
|
||||
);
|
||||
$spent = 0;
|
||||
if (!is_null($entry->first())) {
|
||||
$spent = $entry->first()->spent;
|
||||
}
|
||||
$balanceEntry->setSpent($spent);
|
||||
$line->addBalanceEntry($balanceEntry);
|
||||
}
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $spentData
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||
*
|
||||
* @return BalanceLine
|
||||
*/
|
||||
private function createDifferenceBalanceLine(Collection $accounts, Collection $spentData, Carbon $start, Carbon $end)
|
||||
{
|
||||
$diff = new BalanceLine;
|
||||
$tagsLeft = $this->tagRepository->allCoveredByBalancingActs($accounts, $start, $end);
|
||||
|
||||
$diff->setRole(BalanceLine::ROLE_DIFFROLE);
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$entry = $spentData->filter(
|
||||
function (TransactionJournal $model) use ($account) {
|
||||
return $model->account_id == $account->id && is_null($model->budget_id);
|
||||
}
|
||||
);
|
||||
$spent = 0;
|
||||
if (!is_null($entry->first())) {
|
||||
$spent = $entry->first()->spent;
|
||||
}
|
||||
$leftEntry = $tagsLeft->filter(
|
||||
function (Tag $tag) use ($account) {
|
||||
return $tag->account_id == $account->id;
|
||||
}
|
||||
);
|
||||
$left = 0;
|
||||
if (!is_null($leftEntry->first())) {
|
||||
$left = $leftEntry->first()->sum;
|
||||
}
|
||||
bcscale(2);
|
||||
$diffValue = bcadd($spent, $left);
|
||||
|
||||
// difference:
|
||||
$diffEntry = new BalanceEntry;
|
||||
$diffEntry->setAccount($account);
|
||||
$diffEntry->setSpent($diffValue);
|
||||
$diff->addBalanceEntry($diffEntry);
|
||||
|
||||
}
|
||||
|
||||
return $diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $spentData
|
||||
*
|
||||
* @return BalanceLine
|
||||
*/
|
||||
private function createEmptyBalanceLine(Collection $accounts, Collection $spentData)
|
||||
{
|
||||
$empty = new BalanceLine;
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$entry = $spentData->filter(
|
||||
function (TransactionJournal $model) use ($account) {
|
||||
return $model->account_id == $account->id && is_null($model->budget_id);
|
||||
}
|
||||
);
|
||||
$spent = 0;
|
||||
if (!is_null($entry->first())) {
|
||||
$spent = $entry->first()->spent;
|
||||
}
|
||||
|
||||
// budget
|
||||
$budgetEntry = new BalanceEntry;
|
||||
$budgetEntry->setAccount($account);
|
||||
$budgetEntry->setSpent($spent);
|
||||
$empty->addBalanceEntry($budgetEntry);
|
||||
|
||||
}
|
||||
|
||||
return $empty;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return BalanceLine
|
||||
*/
|
||||
private function createTagsBalanceLine(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
$tags = new BalanceLine;
|
||||
$tagsLeft = $this->tagRepository->allCoveredByBalancingActs($accounts, $start, $end);
|
||||
|
||||
$tags->setRole(BalanceLine::ROLE_TAGROLE);
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$leftEntry = $tagsLeft->filter(
|
||||
function (Tag $tag) use ($account) {
|
||||
return $tag->account_id == $account->id;
|
||||
}
|
||||
);
|
||||
$left = 0;
|
||||
if (!is_null($leftEntry->first())) {
|
||||
$left = $leftEntry->first()->sum;
|
||||
}
|
||||
bcscale(2);
|
||||
|
||||
// balanced by tags
|
||||
$tagEntry = new BalanceEntry;
|
||||
$tagEntry->setAccount($account);
|
||||
$tagEntry->setLeft($left);
|
||||
$tags->addBalanceEntry($tagEntry);
|
||||
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,15 @@ interface ReportHelperInterface
|
||||
*/
|
||||
public function getAccountReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Balance
|
||||
*/
|
||||
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* This method generates a full report for the given period on all
|
||||
* the users bills and their payments.
|
||||
@ -46,15 +55,6 @@ interface ReportHelperInterface
|
||||
*/
|
||||
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Balance
|
||||
*/
|
||||
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
|
@ -17,51 +17,6 @@ use Illuminate\Support\Collection;
|
||||
class ReportQuery implements ReportQueryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
||||
* grouped by month like so: "2015-01" => '123.45'
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function spentPerMonth(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
$query = Auth::user()->transactionjournals()
|
||||
->leftJoin(
|
||||
'transactions AS t_from', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 't_from.transaction_journal_id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions AS t_to', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 't_to.transaction_journal_id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->whereIn('t_from.account_id', $ids)
|
||||
->whereNotIn('t_to.account_id', $ids)
|
||||
->after($start)
|
||||
->before($end)
|
||||
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
||||
->groupBy('dateFormatted')
|
||||
->get(
|
||||
[
|
||||
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
|
||||
DB::Raw('SUM(`t_from`.`amount`) AS `sum`')
|
||||
]
|
||||
);
|
||||
$array = [];
|
||||
foreach ($query as $result) {
|
||||
$array[$result->dateFormatted] = $result->sum;
|
||||
}
|
||||
|
||||
return $array;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
||||
* grouped by month like so: "2015-01" => '123.45'
|
||||
@ -95,7 +50,7 @@ class ReportQuery implements ReportQueryInterface
|
||||
->get(
|
||||
[
|
||||
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
|
||||
DB::Raw('SUM(`t_to`.`amount`) AS `sum`')
|
||||
DB::Raw('SUM(`t_to`.`amount`) AS `sum`'),
|
||||
]
|
||||
);
|
||||
$array = [];
|
||||
@ -106,6 +61,41 @@ class ReportQuery implements ReportQueryInterface
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns all the "out" transaction journals for the given account and given period. The amount
|
||||
* is stored in "journalAmount".
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function expense(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
$set = Auth::user()->transactionjournals()
|
||||
->leftJoin(
|
||||
'transactions as t_from', function (JoinClause $join) {
|
||||
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions as t_to', function (JoinClause $join) {
|
||||
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 't_to.account_id', '=', 'accounts.id')
|
||||
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
||||
->before($end)
|
||||
->after($start)
|
||||
->whereIn('t_from.account_id', $ids)
|
||||
->whereNotIn('t_to.account_id', $ids)
|
||||
->get(['transaction_journals.*', 't_from.amount as journalAmount', 'accounts.id as account_id', 'accounts.name as account_name']);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns all the "in" transaction journals for the given account and given period. The amount
|
||||
* is stored in "journalAmount".
|
||||
@ -142,37 +132,47 @@ class ReportQuery implements ReportQueryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns all the "out" transaction journals for the given account and given period. The amount
|
||||
* is stored in "journalAmount".
|
||||
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
||||
* grouped by month like so: "2015-01" => '123.45'
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
* @return array
|
||||
*/
|
||||
public function expense(Collection $accounts, Carbon $start, Carbon $end)
|
||||
public function spentPerMonth(Collection $accounts, Carbon $start, Carbon $end)
|
||||
{
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
$set = Auth::user()->transactionjournals()
|
||||
->leftJoin(
|
||||
'transactions as t_from', function (JoinClause $join) {
|
||||
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions as t_to', function (JoinClause $join) {
|
||||
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 't_to.account_id', '=', 'accounts.id')
|
||||
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
||||
->before($end)
|
||||
->after($start)
|
||||
->whereIn('t_from.account_id', $ids)
|
||||
->whereNotIn('t_to.account_id', $ids)
|
||||
->get(['transaction_journals.*', 't_from.amount as journalAmount', 'accounts.id as account_id', 'accounts.name as account_name']);
|
||||
$ids = $accounts->pluck('id')->toArray();
|
||||
$query = Auth::user()->transactionjournals()
|
||||
->leftJoin(
|
||||
'transactions AS t_from', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 't_from.transaction_journal_id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions AS t_to', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 't_to.transaction_journal_id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->whereIn('t_from.account_id', $ids)
|
||||
->whereNotIn('t_to.account_id', $ids)
|
||||
->after($start)
|
||||
->before($end)
|
||||
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
||||
->groupBy('dateFormatted')
|
||||
->get(
|
||||
[
|
||||
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
|
||||
DB::Raw('SUM(`t_from`.`amount`) AS `sum`'),
|
||||
]
|
||||
);
|
||||
$array = [];
|
||||
foreach ($query as $result) {
|
||||
$array[$result->dateFormatted] = $result->sum;
|
||||
}
|
||||
|
||||
return $array;
|
||||
|
||||
return $set;
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ class AccountController extends Controller
|
||||
'ccMonthlyPaymentDate' => $account->getMeta('ccMonthlyPaymentDate'),
|
||||
'openingBalanceDate' => $openingBalance ? $openingBalance->date->format('Y-m-d') : null,
|
||||
'openingBalance' => $openingBalanceAmount,
|
||||
'virtualBalance' => round($account->virtual_balance, 2)
|
||||
'virtualBalance' => round($account->virtual_balance, 2),
|
||||
];
|
||||
Session::flash('preFilled', $preFilled);
|
||||
Session::flash('gaEventCategory', 'accounts');
|
||||
@ -251,12 +251,10 @@ class AccountController extends Controller
|
||||
'virtualBalance' => round($request->input('virtualBalance'), 2),
|
||||
'openingBalance' => round($request->input('openingBalance'), 2),
|
||||
'openingBalanceDate' => new Carbon((string)$request->input('openingBalanceDate')),
|
||||
'openingBalanceCurrency' => intval($request->input('balance_currency_id')),
|
||||
'openingBalanceCurrency' => intval($request->input('amount_currency_id_openingBalance')),
|
||||
'ccType' => $request->input('ccType'),
|
||||
'ccMonthlyPaymentDate' => $request->input('ccMonthlyPaymentDate'),
|
||||
];
|
||||
|
||||
|
||||
$repository->update($account, $accountData);
|
||||
|
||||
Session::flash('success', 'Account "' . $account->name . '" updated.');
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
|
||||
use Crypt;
|
||||
use File;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
@ -11,6 +10,7 @@ use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Request;
|
||||
use Response;
|
||||
use Session;
|
||||
use URL;
|
||||
@ -34,26 +34,6 @@ class AttachmentController extends Controller
|
||||
View::share('title', trans('firefly.attachments'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function edit(Attachment $attachment)
|
||||
{
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
$subTitle = trans('firefly.edit_attachment', ['name' => $attachment->filename]);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (Session::get('attachments.edit.fromUpdate') !== true) {
|
||||
Session::put('attachments.edit.url', URL::previous());
|
||||
}
|
||||
Session::forget('attachments.edit.fromUpdate');
|
||||
|
||||
return view('attachments.edit', compact('attachment', 'subTitleIcon', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
@ -101,23 +81,42 @@ class AttachmentController extends Controller
|
||||
|
||||
$quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
|
||||
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename=' . $quoted);
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Connection: Keep-Alive');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . $attachment->size);
|
||||
Request::header('Content-Description: File Transfer');
|
||||
Request::header('Content-Type: application/octet-stream');
|
||||
Request::header('Content-Disposition: attachment; filename=' . $quoted);
|
||||
Request::header('Content-Transfer-Encoding: binary');
|
||||
Request::header('Connection: Keep-Alive');
|
||||
Request::header('Expires: 0');
|
||||
Request::header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
Request::header('Pragma: public');
|
||||
Request::header('Content-Length: ' . $attachment->size);
|
||||
|
||||
echo Crypt::decrypt(file_get_contents($file));
|
||||
return Crypt::decrypt(file_get_contents($file));
|
||||
|
||||
} else {
|
||||
abort(404);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function edit(Attachment $attachment)
|
||||
{
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
$subTitle = trans('firefly.edit_attachment', ['name' => $attachment->filename]);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (Session::get('attachments.edit.fromUpdate') !== true) {
|
||||
Session::put('attachments.edit.url', URL::previous());
|
||||
}
|
||||
Session::forget('attachments.edit.fromUpdate');
|
||||
|
||||
return view('attachments.edit', compact('attachment', 'subTitleIcon', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attachment $attachment
|
||||
*
|
||||
|
174
app/Http/Controllers/Auth/AuthController.php
Normal file → Executable file
174
app/Http/Controllers/Auth/AuthController.php
Normal file → Executable file
@ -1,7 +1,8 @@
|
||||
<?php namespace FireflyIII\Http\Controllers\Auth;
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Auth;
|
||||
|
||||
use Auth;
|
||||
use Config;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Role;
|
||||
use FireflyIII\User;
|
||||
@ -9,13 +10,14 @@ use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
|
||||
use Illuminate\Foundation\Auth\ThrottlesLogins;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Mail\Message;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Log;
|
||||
use Mail;
|
||||
use Request as Rq;
|
||||
use Session;
|
||||
use Twig;
|
||||
use Validator;
|
||||
|
||||
|
||||
/**
|
||||
* Class AuthController
|
||||
*
|
||||
@ -26,27 +28,20 @@ class AuthController extends Controller
|
||||
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
|
||||
|
||||
/**
|
||||
* Log the user out of the application.
|
||||
* Where to redirect users after login / registration.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @var string
|
||||
*/
|
||||
public function getLogout()
|
||||
{
|
||||
Auth::logout();
|
||||
|
||||
return redirect('/auth/login');
|
||||
}
|
||||
protected $redirectTo = '/home';
|
||||
|
||||
/**
|
||||
* Show the application registration form.
|
||||
* Create a new authentication controller instance.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function getRegister()
|
||||
public function __construct()
|
||||
{
|
||||
$host = Rq::getHttpHost();
|
||||
|
||||
return view('auth.register', compact('host'));
|
||||
$this->middleware('guest', ['except' => 'logout']);
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,7 +51,7 @@ class AuthController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function postLogin(Request $request)
|
||||
public function login(Request $request)
|
||||
{
|
||||
$this->validate($request, [$this->loginUsername() => 'required', 'password' => 'required',]);
|
||||
$throttles = $this->isUsingThrottlesLoginsTrait();
|
||||
@ -68,16 +63,19 @@ class AuthController extends Controller
|
||||
$credentials = $this->getCredentials($request);
|
||||
$credentials['blocked'] = 0; // most not be blocked.
|
||||
|
||||
if (Auth::attempt($credentials, $request->has('remember'))) {
|
||||
if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
|
||||
|
||||
return $this->handleUserWasAuthenticated($request, $throttles);
|
||||
}
|
||||
|
||||
$message = $this->getFailedLoginMessage();
|
||||
// check if user is blocked:
|
||||
$message = '';
|
||||
/** @var User $foundUser */
|
||||
$foundUser = User::where('email', $credentials['email'])->where('blocked', 1)->first();
|
||||
if (!is_null($foundUser)) {
|
||||
// if it exists, show message:
|
||||
$code = $foundUser->blocked_code;
|
||||
|
||||
if (strlen($code) == 0) {
|
||||
$code = 'general_blocked';
|
||||
}
|
||||
@ -88,47 +86,17 @@ class AuthController extends Controller
|
||||
$this->incrementLoginAttempts($request);
|
||||
}
|
||||
|
||||
return redirect($this->loginPath())
|
||||
->withInput($request->only($this->loginUsername(), 'remember'))
|
||||
->withErrors([$this->loginUsername() => $message,]);
|
||||
}
|
||||
|
||||
|
||||
public $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new authentication controller instance.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware('guest', ['except' => 'getLogout']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application login form.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return \Illuminate\Http\Response
|
||||
*
|
||||
*/
|
||||
public function getLogin()
|
||||
{
|
||||
return Twig::render('auth.login');
|
||||
return $this->sendFailedLoginResponse($request, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a registration request for the application.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function postRegister(Request $request)
|
||||
public function register(Request $request)
|
||||
{
|
||||
$validator = $this->validator($request->all());
|
||||
|
||||
@ -136,10 +104,7 @@ class AuthController extends Controller
|
||||
$this->throwValidationException(
|
||||
$request, $validator
|
||||
);
|
||||
// @codeCoverageIgnoreStart
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
|
||||
$data = $request->all();
|
||||
$data['password'] = bcrypt($data['password']);
|
||||
@ -152,7 +117,8 @@ class AuthController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
Auth::login($this->create($data));
|
||||
|
||||
Auth::login($this->create($request->all()));
|
||||
|
||||
// get the email address
|
||||
if (Auth::user() instanceof User) {
|
||||
@ -187,8 +153,37 @@ class AuthController extends Controller
|
||||
// @codeCoverageIgnoreStart
|
||||
abort(500, 'Not a user!');
|
||||
|
||||
return redirect('/');
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
return redirect($this->redirectPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application registration form.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function showRegistrationForm()
|
||||
{
|
||||
$host = Rq::getHttpHost();
|
||||
|
||||
return view('auth.register', compact('host'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
protected function create(array $data)
|
||||
{
|
||||
return User::create(
|
||||
[
|
||||
'email' => $data['email'],
|
||||
'password' => bcrypt($data['password']),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,7 +191,7 @@ class AuthController extends Controller
|
||||
*/
|
||||
protected function getBlockedDomains()
|
||||
{
|
||||
$set = Config::get('mail.blocked_domains');
|
||||
$set = explode(',', env('BLOCKED_DOMAINS', ''));
|
||||
$domains = [];
|
||||
foreach ($set as $entry) {
|
||||
$domain = trim($entry);
|
||||
@ -208,6 +203,24 @@ class AuthController extends Controller
|
||||
return $domains;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the failed login message.
|
||||
*
|
||||
* @param $message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getFailedLoginMessage($message)
|
||||
{
|
||||
if (strlen($message) > 0) {
|
||||
return $message;
|
||||
}
|
||||
|
||||
return Lang::has('auth.failed')
|
||||
? Lang::get('auth.failed')
|
||||
: 'These credentials do not match our records.';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $email
|
||||
*
|
||||
@ -225,6 +238,26 @@ class AuthController extends Controller
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the failed login response instance.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @param $message
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
protected function sendFailedLoginResponse(Request $request, $message)
|
||||
{
|
||||
return redirect()->back()
|
||||
->withInput($request->only($this->loginUsername(), 'remember'))
|
||||
->withErrors(
|
||||
[
|
||||
$this->loginUsername() => $this->getFailedLoginMessage($message),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
@ -232,7 +265,7 @@ class AuthController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
public function validator(array $data)
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make(
|
||||
$data, [
|
||||
@ -241,21 +274,4 @@ class AuthController extends Controller
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function create(array $data)
|
||||
{
|
||||
return User::create(
|
||||
[
|
||||
'email' => $data['email'],
|
||||
'password' => $data['password'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
23
app/Http/Controllers/Auth/PasswordController.php
Normal file → Executable file
23
app/Http/Controllers/Auth/PasswordController.php
Normal file → Executable file
@ -1,4 +1,6 @@
|
||||
<?php namespace FireflyIII\Http\Controllers\Auth;
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Auth;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\User;
|
||||
@ -7,15 +9,14 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Mail\Message;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
|
||||
|
||||
/**
|
||||
* Class PasswordController
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Http\Controllers\Auth
|
||||
*/
|
||||
class PasswordController extends Controller
|
||||
{
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
@ -29,14 +30,9 @@ class PasswordController extends Controller
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
|
||||
protected $redirectPath = '/';
|
||||
|
||||
/**
|
||||
* Create a new password controller instance.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@ -52,7 +48,7 @@ class PasswordController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function postEmail(Request $request)
|
||||
public function sendResetLinkEmail(Request $request)
|
||||
{
|
||||
$this->validate($request, ['email' => 'required|email']);
|
||||
|
||||
@ -70,16 +66,13 @@ class PasswordController extends Controller
|
||||
|
||||
switch ($response) {
|
||||
case Password::RESET_LINK_SENT:
|
||||
return redirect()->back()->with('status', trans($response));
|
||||
return $this->getSendResetLinkEmailSuccessResponse($response);
|
||||
|
||||
case Password::INVALID_USER:
|
||||
case 'passwords.blocked':
|
||||
return redirect()->back()->withErrors(['email' => trans($response)]);
|
||||
|
||||
default:
|
||||
return $this->getSendResetLinkEmailFailureResponse($response);
|
||||
}
|
||||
abort(404);
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -144,33 +144,6 @@ class CategoryController extends Controller
|
||||
return view('categories.noCategory', compact('list', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @param $date
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showWithDate(SCRI $repository, Category $category, $date)
|
||||
{
|
||||
$carbon = new Carbon($date);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod($carbon, $range);
|
||||
$end = Navigation::endOfPeriod($carbon, $range);
|
||||
$subTitle = $category->name;
|
||||
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page'));
|
||||
|
||||
$set = $repository->getJournalsInRange($category, $page, $start, $end);
|
||||
$count = $repository->countJournalsInRange($category, $start, $end);
|
||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
$journals->setPath('categories/show/' . $category->id . '/' . $date);
|
||||
|
||||
return view('categories.show_with_date', compact('category', 'journals', 'hideCategory', 'subTitle', 'carbon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
@ -232,6 +205,33 @@ class CategoryController extends Controller
|
||||
return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @param $date
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showWithDate(SCRI $repository, Category $category, $date)
|
||||
{
|
||||
$carbon = new Carbon($date);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod($carbon, $range);
|
||||
$end = Navigation::endOfPeriod($carbon, $range);
|
||||
$subTitle = $category->name;
|
||||
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page'));
|
||||
|
||||
$set = $repository->getJournalsInRange($category, $page, $start, $end);
|
||||
$count = $repository->countJournalsInRange($category, $start, $end);
|
||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
$journals->setPath('categories/show/' . $category->id . '/' . $date);
|
||||
|
||||
return view('categories.show_with_date', compact('category', 'journals', 'hideCategory', 'subTitle', 'carbon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryFormRequest $request
|
||||
* @param SCRI $repository
|
||||
|
@ -46,6 +46,8 @@ class BudgetController extends Controller
|
||||
* @param Collection $accounts
|
||||
* @param Collection $budgets
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveParameterList) // need all parameters
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function multiYear(BudgetRepositoryInterface $repository, $reportType, Carbon $start, Carbon $end, Collection $accounts, Collection $budgets)
|
||||
|
@ -43,6 +43,8 @@ class CategoryController extends Controller
|
||||
* @param SCRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function all(SCRI $repository, Category $category)
|
||||
@ -53,8 +55,6 @@ class CategoryController extends Controller
|
||||
$start = Navigation::startOfPeriod($start, $range);
|
||||
$end = new Carbon;
|
||||
$entries = new Collection;
|
||||
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($start);
|
||||
@ -67,29 +67,21 @@ class CategoryController extends Controller
|
||||
$spentArray = $repository->spentPerDay($category, $start, $end);
|
||||
$earnedArray = $repository->earnedPerDay($category, $start, $end);
|
||||
|
||||
|
||||
while ($start <= $end) {
|
||||
$currentEnd = Navigation::endOfPeriod($start, $range);
|
||||
|
||||
// get the sum from $spentArray and $earnedArray:
|
||||
$spent = $this->getSumOfRange($start, $currentEnd, $spentArray);
|
||||
$earned = $this->getSumOfRange($start, $currentEnd, $earnedArray);
|
||||
|
||||
$date = Navigation::periodShow($start, $range);
|
||||
$spent = $this->getSumOfRange($start, $currentEnd, $spentArray);
|
||||
$earned = $this->getSumOfRange($start, $currentEnd, $earnedArray);
|
||||
$date = Navigation::periodShow($start, $range);
|
||||
$entries->push([clone $start, $date, $spent, $earned]);
|
||||
$start = Navigation::addPeriod($start, $range, 0);
|
||||
}
|
||||
// limit the set to the last 40:
|
||||
$entries = $entries->reverse();
|
||||
$entries = $entries->slice(0, 48);
|
||||
$entries = $entries->reverse();
|
||||
|
||||
$data = $this->generator->all($entries);
|
||||
$data = $this->generator->all($entries);
|
||||
$cache->store($data);
|
||||
|
||||
return Response::json($data);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -121,12 +113,12 @@ class CategoryController extends Controller
|
||||
$outside = $repository->sumSpentNoCategory(new Collection, $start, $end);
|
||||
|
||||
// this is a "fake" entry for the "no category" entry.
|
||||
$entry = new stdClass();
|
||||
$entry->name = trans('firefly.no_category');
|
||||
$entry = new stdClass();
|
||||
$entry->name = trans('firefly.no_category');
|
||||
$entry->spent = $outside;
|
||||
$set->push($entry);
|
||||
|
||||
$set = $set->sortBy('spent');
|
||||
$set = $set->sortBy('spent');
|
||||
$data = $this->generator->frontpage($set);
|
||||
$cache->store($data);
|
||||
|
||||
@ -161,23 +153,8 @@ class CategoryController extends Controller
|
||||
return Response::json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
* category
|
||||
* year:
|
||||
* spent: x
|
||||
* earned: x
|
||||
* year
|
||||
* spent: x
|
||||
* earned: x
|
||||
*/
|
||||
$entries = new Collection;
|
||||
// go by category, not by year.
|
||||
|
||||
// given a set of categories and accounts, it should not be difficult to get
|
||||
// the exact array of data we need.
|
||||
|
||||
// then get the data for "no category".
|
||||
$set = $repository->listMultiYear($categories, $accounts, $start, $end);
|
||||
$set = $repository->listMultiYear($categories, $accounts, $start, $end);
|
||||
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
@ -336,6 +313,10 @@ class CategoryController extends Controller
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveParameterList) // cant avoid it.
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's exactly 5.
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) // it's long but ok.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function earnedInPeriod(CRI $repository, $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
@ -360,18 +341,15 @@ class CategoryController extends Controller
|
||||
$entries = new Collection;
|
||||
|
||||
while ($start < $end) { // filter the set:
|
||||
$row = [clone $start];
|
||||
// get possibly relevant entries from the big $set
|
||||
$currentSet = $set->filter(
|
||||
$row = [clone $start];
|
||||
$currentSet = $set->filter( // get possibly relevant entries from the big $set
|
||||
function (Category $category) use ($start) {
|
||||
return $category->dateFormatted == $start->format("Y-m");
|
||||
}
|
||||
);
|
||||
// check for each category if its in the current set.
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
// if its in there, use the value.
|
||||
$entry = $currentSet->filter(
|
||||
foreach ($categories as $category) { // check for each category if its in the current set.
|
||||
$entry = $currentSet->filter( // if its in there, use the value.
|
||||
function (Category $cat) use ($category) {
|
||||
return ($cat->id == $category->id);
|
||||
}
|
||||
@ -382,7 +360,6 @@ class CategoryController extends Controller
|
||||
$row[] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$entries->push($row);
|
||||
$start->addMonth();
|
||||
}
|
||||
@ -403,6 +380,9 @@ class CategoryController extends Controller
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveParameterList) // need all parameters
|
||||
* @SuppressWarnings(PHPMD.ExcessuveMethodLength) // need the length
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function spentInPeriod(CRI $repository, $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
@ -427,18 +407,15 @@ class CategoryController extends Controller
|
||||
$entries = new Collection;
|
||||
|
||||
while ($start < $end) { // filter the set:
|
||||
$row = [clone $start];
|
||||
// get possibly relevant entries from the big $set
|
||||
$currentSet = $set->filter(
|
||||
$row = [clone $start];
|
||||
$currentSet = $set->filter(// get possibly relevant entries from the big $set
|
||||
function (Category $category) use ($start) {
|
||||
return $category->dateFormatted == $start->format("Y-m");
|
||||
}
|
||||
);
|
||||
// check for each category if its in the current set.
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
// if its in there, use the value.
|
||||
$entry = $currentSet->filter(
|
||||
foreach ($categories as $category) {// check for each category if its in the current set.
|
||||
$entry = $currentSet->filter(// if its in there, use the value.
|
||||
function (Category $cat) use ($category) {
|
||||
return ($cat->id == $category->id);
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ class ReportController extends Controller
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveParameterList) // cant avoid it.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function yearInOut(ReportQueryInterface $query, $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
|
37
app/Http/Controllers/Controller.php
Normal file → Executable file
37
app/Http/Controllers/Controller.php
Normal file → Executable file
@ -1,10 +1,15 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use App;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use NumberFormatter;
|
||||
use Preferences;
|
||||
use View;
|
||||
|
||||
@ -13,18 +18,17 @@ use View;
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
abstract class Controller extends BaseController
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
use DispatchesJobs, ValidatesRequests;
|
||||
|
||||
/** @var string */
|
||||
/** @var string|\Symfony\Component\Translation\TranslatorInterface */
|
||||
protected $monthAndDayFormat;
|
||||
/** @var string */
|
||||
/** @var string|\Symfony\Component\Translation\TranslatorInterface */
|
||||
protected $monthFormat;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* Controller constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@ -39,10 +43,25 @@ abstract class Controller extends BaseController
|
||||
$this->monthFormat = trans('config.month');
|
||||
$this->monthAndDayFormat = trans('config.month_and_day');
|
||||
|
||||
App::setLocale($lang);
|
||||
Carbon::setLocale(substr($lang, 0, 2));
|
||||
$locale = explode(',', trans('config.locale'));
|
||||
$locale = array_map('trim', $locale);
|
||||
|
||||
setlocale(LC_TIME, $locale);
|
||||
setlocale(LC_MONETARY, $locale);
|
||||
|
||||
// change localeconv to a new array:
|
||||
$numberFormatter = numfmt_create($lang, NumberFormatter::CURRENCY);
|
||||
$localeconv = [
|
||||
'mon_decimal_point' => $numberFormatter->getSymbol($numberFormatter->getAttribute(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL)),
|
||||
'mon_thousands_sep' => $numberFormatter->getSymbol($numberFormatter->getAttribute(NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL)),
|
||||
'frac_digits' => $numberFormatter->getAttribute(NumberFormatter::MAX_FRACTION_DIGITS),
|
||||
];
|
||||
View::share('monthFormat', $this->monthFormat);
|
||||
View::share('monthAndDayFormat', $this->monthAndDayFormat);
|
||||
View::share('language', $lang);
|
||||
View::share('localeconv', localeconv());
|
||||
View::share('localeconv', $localeconv);
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,4 +92,6 @@ abstract class Controller extends BaseController
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ use Illuminate\Http\Request;
|
||||
use Input;
|
||||
use Log;
|
||||
use Preferences;
|
||||
use Request as RequestFacade;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
@ -30,7 +31,7 @@ class CsvController extends Controller
|
||||
protected $wizard;
|
||||
|
||||
/**
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@ -57,8 +58,9 @@ class CsvController extends Controller
|
||||
public function columnRoles()
|
||||
{
|
||||
|
||||
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-import-account'];
|
||||
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-import-account', 'csv-specifix', 'csv-delimiter'];
|
||||
if (!$this->wizard->sessionHasValues($fields)) {
|
||||
Log::error('Could not recover upload.');
|
||||
Session::flash('warning', 'Could not recover upload.');
|
||||
|
||||
return redirect(route('csv.index'));
|
||||
@ -79,9 +81,9 @@ class CsvController extends Controller
|
||||
if ($this->data->hasHeaders()) {
|
||||
$headers = $firstRow;
|
||||
}
|
||||
|
||||
foreach (Config::get('csv.roles') as $name => $role) {
|
||||
$availableRoles[$name] = trans('firefly.csv_column_' . $name);//$role['name'];
|
||||
$keys = array_keys(Config::get('csv.roles'));
|
||||
foreach ($keys as $name) {
|
||||
$availableRoles[$name] = trans('firefly.csv_column_' . $name);
|
||||
}
|
||||
ksort($availableRoles);
|
||||
|
||||
@ -97,7 +99,7 @@ class CsvController extends Controller
|
||||
*/
|
||||
public function downloadConfig()
|
||||
{
|
||||
$fields = ['csv-date-format', 'csv-has-headers'];
|
||||
$fields = ['csv-date-format', 'csv-has-headers', 'csv-delimiter'];
|
||||
if (!$this->wizard->sessionHasValues($fields)) {
|
||||
Session::flash('warning', 'Could not recover upload.');
|
||||
|
||||
@ -105,7 +107,7 @@ class CsvController extends Controller
|
||||
}
|
||||
$data = [
|
||||
'date-format' => Session::get('csv-date-format'),
|
||||
'has-headers' => Session::get('csv-has-headers')
|
||||
'has-headers' => Session::get('csv-has-headers'),
|
||||
];
|
||||
if (Session::has('csv-map')) {
|
||||
$data['map'] = Session::get('csv-map');
|
||||
@ -122,13 +124,18 @@ class CsvController extends Controller
|
||||
}
|
||||
|
||||
$result = json_encode($data, JSON_PRETTY_PRINT);
|
||||
$name = 'csv-configuration-' . date('Y-m-d') . '.json';
|
||||
$name = sprintf('"%s"', addcslashes('csv-configuration-' . date('Y-m-d') . '.json', '"\\'));
|
||||
|
||||
header('Content-disposition: attachment; filename=' . $name);
|
||||
header('Content-type: application/json');
|
||||
echo $result;
|
||||
RequestFacade::header('Content-disposition: attachment; filename=' . $name);
|
||||
RequestFacade::header('Content-Type: application/json');
|
||||
RequestFacade::header('Content-Description: File Transfer');
|
||||
RequestFacade::header('Connection: Keep-Alive');
|
||||
RequestFacade::header('Expires: 0');
|
||||
RequestFacade::header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
RequestFacade::header('Pragma: public');
|
||||
RequestFacade::header('Content-Length: ' . strlen($result));
|
||||
|
||||
return '';
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,6 +143,13 @@ class CsvController extends Controller
|
||||
*/
|
||||
public function downloadConfigPage()
|
||||
{
|
||||
$fields = ['csv-date-format', 'csv-has-headers', 'csv-delimiter'];
|
||||
if (!$this->wizard->sessionHasValues($fields)) {
|
||||
Session::flash('warning', 'Could not recover upload.');
|
||||
|
||||
return redirect(route('csv.index'));
|
||||
}
|
||||
|
||||
$subTitle = trans('firefly.csv_download_config_title');
|
||||
|
||||
return view('csv.download-config', compact('subTitle'));
|
||||
@ -162,6 +176,7 @@ class CsvController extends Controller
|
||||
Session::forget('csv-roles');
|
||||
Session::forget('csv-mapped');
|
||||
Session::forget('csv-specifix');
|
||||
Session::forget('csv-delimiter');
|
||||
|
||||
// get list of supported specifix
|
||||
$specifix = [];
|
||||
@ -169,6 +184,13 @@ class CsvController extends Controller
|
||||
$specifix[$entry] = trans('firefly.csv_specifix_' . $entry);
|
||||
}
|
||||
|
||||
// get a list of delimiters:
|
||||
$delimiters = [
|
||||
',' => trans('form.csv_comma'),
|
||||
';' => trans('form.csv_semicolon'),
|
||||
'tab' => trans('form.csv_tab'),
|
||||
];
|
||||
|
||||
// get a list of asset accounts:
|
||||
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Asset account', 'Default account']));
|
||||
|
||||
@ -176,7 +198,7 @@ class CsvController extends Controller
|
||||
$uploadPossible = is_writable(storage_path('upload'));
|
||||
$path = storage_path('upload');
|
||||
|
||||
return view('csv.index', compact('subTitle', 'uploadPossible', 'path', 'specifix', 'accounts'));
|
||||
return view('csv.index', compact('subTitle', 'uploadPossible', 'path', 'specifix', 'accounts', 'delimiters'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,7 +210,7 @@ class CsvController extends Controller
|
||||
*/
|
||||
public function initialParse()
|
||||
{
|
||||
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers'];
|
||||
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-delimiter'];
|
||||
if (!$this->wizard->sessionHasValues($fields)) {
|
||||
Session::flash('warning', 'Could not recover upload.');
|
||||
|
||||
@ -238,7 +260,7 @@ class CsvController extends Controller
|
||||
{
|
||||
|
||||
// Make sure all fields we need are accounted for.
|
||||
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-map', 'csv-roles'];
|
||||
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-map', 'csv-roles', 'csv-delimiter'];
|
||||
if (!$this->wizard->sessionHasValues($fields)) {
|
||||
Session::flash('warning', 'Could not recover upload.');
|
||||
|
||||
@ -258,6 +280,8 @@ class CsvController extends Controller
|
||||
try {
|
||||
$options = $this->wizard->showOptions($this->data->getMap());
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
|
||||
return view('error', ['message' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
@ -286,7 +310,7 @@ class CsvController extends Controller
|
||||
/*
|
||||
* Make sure all fields we need are accounted for.
|
||||
*/
|
||||
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-map', 'csv-roles', 'csv-mapped'];
|
||||
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-map', 'csv-roles', 'csv-mapped', 'csv-delimiter'];
|
||||
if (!$this->wizard->sessionHasValues($fields)) {
|
||||
Session::flash('warning', 'Could not recover upload.');
|
||||
|
||||
@ -323,6 +347,8 @@ class CsvController extends Controller
|
||||
*
|
||||
* STEP SIX
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity) it's 6, but it's allright.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function saveMapping()
|
||||
@ -330,7 +356,7 @@ class CsvController extends Controller
|
||||
/*
|
||||
* Make sure all fields we need are accounted for.
|
||||
*/
|
||||
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-map', 'csv-roles'];
|
||||
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers', 'csv-map', 'csv-roles', 'csv-delimiter'];
|
||||
if (!$this->wizard->sessionHasValues($fields)) {
|
||||
Session::flash('warning', 'Could not recover upload.');
|
||||
|
||||
@ -367,6 +393,9 @@ class CsvController extends Controller
|
||||
*
|
||||
* STEP TWO
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) // need the length.
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // its exactly 5, its ok
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
@ -383,11 +412,19 @@ class CsvController extends Controller
|
||||
$settings = [];
|
||||
$settings['date-format'] = Input::get('date_format');
|
||||
$settings['has-headers'] = intval(Input::get('has_headers')) === 1;
|
||||
$settings['specifix'] = Input::get('specifix');
|
||||
$settings['specifix'] = is_array(Input::get('specifix')) ? Input::get('specifix') : [];
|
||||
$settings['import-account'] = intval(Input::get('csv_import_account'));
|
||||
$settings['map'] = [];
|
||||
$settings['mapped'] = [];
|
||||
$settings['roles'] = [];
|
||||
$settings['delimiter'] = Input::get('csv_delimiter', ',');
|
||||
|
||||
// A tab character cannot be used itself as option value in HTML
|
||||
// See http://stackoverflow.com/questions/6064135/valid-characters-in-option-value
|
||||
if ($settings['delimiter'] == 'tab') {
|
||||
$settings['delimiter'] = "\t";
|
||||
}
|
||||
|
||||
$settings['map'] = [];
|
||||
$settings['mapped'] = [];
|
||||
$settings['roles'] = [];
|
||||
|
||||
if ($request->hasFile('csv_config')) { // Process config file if present.
|
||||
$data = file_get_contents($request->file('csv_config')->getRealPath());
|
||||
@ -405,6 +442,7 @@ class CsvController extends Controller
|
||||
$this->data->setRoles($settings['roles']);
|
||||
$this->data->setSpecifix($settings['specifix']);
|
||||
$this->data->setImportAccount($settings['import-account']);
|
||||
$this->data->setDelimiter($settings['delimiter']);
|
||||
|
||||
return redirect(route('csv.column-roles'));
|
||||
|
||||
|
@ -6,6 +6,7 @@ use FireflyIII\Http\Requests\CurrencyFormRequest;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use Input;
|
||||
use Log;
|
||||
use Preferences;
|
||||
use Session;
|
||||
use URL;
|
||||
@ -60,7 +61,7 @@ class CurrencyController extends Controller
|
||||
Preferences::set('currencyPreference', $currency->code);
|
||||
Preferences::mark();
|
||||
|
||||
Session::flash('success', $currency->name . ' is now the default currency.');
|
||||
Session::flash('success', trans('firefly.new_default_currency', ['name' => $currency->name]));
|
||||
Cache::forget('FFCURRENCYSYMBOL');
|
||||
Cache::forget('FFCURRENCYCODE');
|
||||
|
||||
@ -78,7 +79,7 @@ class CurrencyController extends Controller
|
||||
{
|
||||
|
||||
if ($repository->countJournals($currency) > 0) {
|
||||
Session::flash('error', 'Cannot delete ' . e($currency->name) . ' because there are still transactions attached to it.');
|
||||
Session::flash('error', trans('firefly.cannot_delete_currency', ['name' => $currency->name]));
|
||||
|
||||
return redirect(route('currency.index'));
|
||||
}
|
||||
@ -103,12 +104,12 @@ class CurrencyController extends Controller
|
||||
public function destroy(CurrencyRepositoryInterface $repository, TransactionCurrency $currency)
|
||||
{
|
||||
if ($repository->countJournals($currency) > 0) {
|
||||
Session::flash('error', 'Cannot destroy ' . e($currency->name) . ' because there are still transactions attached to it.');
|
||||
Session::flash('error', trans('firefly.cannot_delete_currency', ['name' => $currency->name]));
|
||||
|
||||
return redirect(route('currency.index'));
|
||||
}
|
||||
|
||||
Session::flash('success', 'Currency "' . e($currency->name) . '" deleted');
|
||||
Session::flash('success', trans('firefly.deleted_currency', ['name' => $currency->name]));
|
||||
if (Auth::user()->hasRole('owner')) {
|
||||
$currency->delete();
|
||||
}
|
||||
@ -151,7 +152,7 @@ class CurrencyController extends Controller
|
||||
|
||||
|
||||
if (!Auth::user()->hasRole('owner')) {
|
||||
Session::flash('warning', 'Please ask ' . env('SITE_OWNER') . ' to add, remove or edit currencies.');
|
||||
Session::flash('warning', trans('firefly.ask_site_owner', ['owner' => env('SITE_OWNER')]));
|
||||
}
|
||||
|
||||
|
||||
@ -170,8 +171,9 @@ class CurrencyController extends Controller
|
||||
$data = $request->getCurrencyData();
|
||||
if (Auth::user()->hasRole('owner')) {
|
||||
$currency = $repository->store($data);
|
||||
Session::flash('success', 'Currency "' . $currency->name . '" created');
|
||||
|
||||
Session::flash('success', trans('firefly.created_currency', ['name' => $currency->name]));
|
||||
} else {
|
||||
Log::error('User ' . Auth::user()->id . ' is not admin, but tried to store a currency.');
|
||||
}
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
@ -199,7 +201,7 @@ class CurrencyController extends Controller
|
||||
if (Auth::user()->hasRole('owner')) {
|
||||
$currency = $repository->update($currency, $data);
|
||||
}
|
||||
Session::flash('success', 'Currency "' . e($currency->name) . '" updated.');
|
||||
Session::flash('success', trans('firefly.updated_currency', ['name' => $currency->name]));
|
||||
Preferences::mark();
|
||||
|
||||
|
||||
|
@ -11,6 +11,13 @@ use Response;
|
||||
*/
|
||||
class HelpController extends Controller
|
||||
{
|
||||
/**
|
||||
* HelpController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param HelpInterface $help
|
||||
|
@ -6,6 +6,7 @@ use Config;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use Input;
|
||||
use Log;
|
||||
use Preferences;
|
||||
use Session;
|
||||
use Steam;
|
||||
@ -17,6 +18,13 @@ use Steam;
|
||||
*/
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* HomeController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function dateRange()
|
||||
{
|
||||
@ -68,6 +76,7 @@ class HomeController extends Controller
|
||||
*/
|
||||
public function index(ARI $repository)
|
||||
{
|
||||
Log::debug('You are at index.');
|
||||
$types = Config::get('firefly.accountTypesByIdentifier.asset');
|
||||
$count = $repository->countAccounts($types);
|
||||
bcscale(2);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
@ -9,6 +10,7 @@ use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
@ -20,43 +22,31 @@ use Session;
|
||||
*/
|
||||
class JsonController extends Controller
|
||||
{
|
||||
/**
|
||||
* JsonController constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function endTour()
|
||||
public function action()
|
||||
{
|
||||
Preferences::set('tour', false);
|
||||
|
||||
return Response::json('true');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function tour()
|
||||
{
|
||||
$pref = Preferences::get('tour', true);
|
||||
if (!$pref) {
|
||||
abort(404);
|
||||
$count = intval(Input::get('count')) > 0 ? intval(Input::get('count')) : 1;
|
||||
$keys = array_keys(Config::get('firefly.rule-actions'));
|
||||
$actions = [];
|
||||
foreach ($keys as $key) {
|
||||
$actions[$key] = trans('firefly.rule_action_' . $key . '_choice');
|
||||
}
|
||||
$headers = ['main-content', 'sidebar-toggle', 'account-menu', 'budget-menu', 'report-menu', 'transaction-menu', 'option-menu', 'main-content-end'];
|
||||
$steps = [];
|
||||
foreach ($headers as $header) {
|
||||
$steps[] = [
|
||||
'element' => '#' . $header,
|
||||
'title' => trans('help.' . $header . '-title'),
|
||||
'content' => trans('help.' . $header . '-text'),
|
||||
];
|
||||
}
|
||||
$steps[0]['orphan'] = true;// orphan and backdrop for first element.
|
||||
$steps[0]['backdrop'] = true;
|
||||
$steps[1]['placement'] = 'left';// sidebar position left:
|
||||
$steps[7]['orphan'] = true; // final in the center again.
|
||||
$steps[7]['backdrop'] = true;
|
||||
$template = view('json.tour')->render();
|
||||
$view = view('rules.partials.action', compact('actions', 'count'))->render();
|
||||
|
||||
return Response::json(['steps' => $steps, 'template' => $template]);
|
||||
|
||||
return Response::json(['html' => $view]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,6 +178,16 @@ class JsonController extends Controller
|
||||
return Response::json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function endTour()
|
||||
{
|
||||
Preferences::set('tour', false);
|
||||
|
||||
return Response::json('true');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON list of all beneficiaries.
|
||||
*
|
||||
@ -243,6 +243,34 @@ class JsonController extends Controller
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function tour()
|
||||
{
|
||||
$pref = Preferences::get('tour', true);
|
||||
if (!$pref) {
|
||||
abort(404);
|
||||
}
|
||||
$headers = ['main-content', 'sidebar-toggle', 'account-menu', 'budget-menu', 'report-menu', 'transaction-menu', 'option-menu', 'main-content-end'];
|
||||
$steps = [];
|
||||
foreach ($headers as $header) {
|
||||
$steps[] = [
|
||||
'element' => '#' . $header,
|
||||
'title' => trans('help.' . $header . '-title'),
|
||||
'content' => trans('help.' . $header . '-text'),
|
||||
];
|
||||
}
|
||||
$steps[0]['orphan'] = true;// orphan and backdrop for first element.
|
||||
$steps[0]['backdrop'] = true;
|
||||
$steps[1]['placement'] = 'left';// sidebar position left:
|
||||
$steps[7]['orphan'] = true; // final in the center again.
|
||||
$steps[7]['backdrop'] = true;
|
||||
$template = view('json.tour')->render();
|
||||
|
||||
return Response::json(['steps' => $steps, 'template' => $template]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param JournalRepositoryInterface $repository
|
||||
* @param $what
|
||||
@ -267,4 +295,24 @@ class JsonController extends Controller
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function trigger()
|
||||
{
|
||||
$count = intval(Input::get('count')) > 0 ? intval(Input::get('count')) : 1;
|
||||
$keys = array_keys(Config::get('firefly.rule-triggers'));
|
||||
$triggers = [];
|
||||
foreach ($keys as $key) {
|
||||
if ($key != 'user_action') {
|
||||
$triggers[$key] = trans('firefly.rule_trigger_' . $key . '_choice');
|
||||
}
|
||||
}
|
||||
|
||||
$view = view('rules.partials.trigger', compact('triggers', 'count'))->render();
|
||||
|
||||
|
||||
return Response::json(['html' => $view]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,13 @@ use View;
|
||||
*/
|
||||
class NewUserController extends Controller
|
||||
{
|
||||
/**
|
||||
* NewUserController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -10,6 +10,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Log;
|
||||
use Preferences;
|
||||
use Session;
|
||||
use Steam;
|
||||
@ -156,7 +157,7 @@ class PiggyBankController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ARI $repository
|
||||
* @param ARI $repository
|
||||
* @param PiggyBankRepositoryInterface $piggyRepository
|
||||
*
|
||||
* @return View
|
||||
@ -186,7 +187,7 @@ class PiggyBankController extends Controller
|
||||
'leftForPiggyBanks' => $repository->leftOnAccount($account, $end),
|
||||
'sumOfSaved' => $piggyBank->savedSoFar,
|
||||
'sumOfTargets' => round($piggyBank->targetamount, 2),
|
||||
'leftToSave' => $piggyBank->leftToSave
|
||||
'leftToSave' => $piggyBank->leftToSave,
|
||||
];
|
||||
} else {
|
||||
$accounts[$account->id]['sumOfSaved'] = bcadd($accounts[$account->id]['sumOfSaved'], $piggyBank->savedSoFar);
|
||||
@ -244,6 +245,7 @@ class PiggyBankController extends Controller
|
||||
Session::flash('success', 'Added ' . Amount::format($amount, false) . ' to "' . e($piggyBank->name) . '".');
|
||||
Preferences::mark();
|
||||
} else {
|
||||
Log::error('Cannot add ' . $amount . ' because max amount is ' . $maxAmount . ' (left on account is ' . $leftOnAccount . ')');
|
||||
Session::flash('error', 'Could not add ' . Amount::format($amount, false) . ' to "' . e($piggyBank->name) . '".');
|
||||
}
|
||||
|
||||
@ -322,6 +324,7 @@ class PiggyBankController extends Controller
|
||||
'targetamount' => round($request->get('targetamount'), 2),
|
||||
'remind_me' => false,
|
||||
'reminder_skip' => 0,
|
||||
'order' => $repository->getMaxOrder() + 1,
|
||||
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
||||
];
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\DeleteAccountFormRequest;
|
||||
use FireflyIII\Http\Requests\ProfileFormRequest;
|
||||
use FireflyIII\User;
|
||||
@ -15,6 +14,13 @@ use Session;
|
||||
*/
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
/**
|
||||
* ProfileController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
@ -74,23 +80,6 @@ class ProfileController extends Controller
|
||||
return redirect(route('profile'));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $old
|
||||
* @param string $new1
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
protected function validatePassword($old, $new1)
|
||||
{
|
||||
if ($new1 == $old) {
|
||||
return trans('firefly.should_change');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DeleteAccountFormRequest $request
|
||||
*
|
||||
@ -119,12 +108,29 @@ class ProfileController extends Controller
|
||||
'email' => $email,
|
||||
'password' => 'deleted',
|
||||
'blocked' => 1,
|
||||
'blocked_code' => 'deleted'
|
||||
'blocked_code' => 'deleted',
|
||||
]
|
||||
);
|
||||
|
||||
return redirect(route('index'));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $old
|
||||
* @param string $new1
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
protected function validatePassword($old, $new1)
|
||||
{
|
||||
if ($new1 == $old) {
|
||||
return trans('firefly.should_change');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use View;
|
||||
class ReportController extends Controller
|
||||
{
|
||||
|
||||
|
||||
/** @var ReportHelperInterface */
|
||||
protected $helper;
|
||||
|
||||
@ -34,83 +35,6 @@ class ReportController extends Controller
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return View
|
||||
* @internal param ReportHelperInterface $helper
|
||||
*/
|
||||
public function index(ARI $repository)
|
||||
{
|
||||
$start = Session::get('first');
|
||||
$months = $this->helper->listOfMonths($start);
|
||||
$startOfMonth = clone Session::get('start');
|
||||
$endOfMonth = clone Session::get('start');
|
||||
$startOfYear = clone Session::get('start');
|
||||
$endOfYear = clone Session::get('start');
|
||||
$startOfMonth->startOfMonth();
|
||||
$endOfMonth->endOfMonth();
|
||||
$startOfYear->startOfYear();
|
||||
$endOfYear->endOfYear();
|
||||
|
||||
// does the user have shared accounts?
|
||||
$accounts = $repository->getAccounts(['Default account', 'Asset account']);
|
||||
// get id's for quick links:
|
||||
$accountIds = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountIds [] = $account->id;
|
||||
}
|
||||
$accountList = join(',', $accountIds);
|
||||
|
||||
|
||||
return view(
|
||||
'reports.index', compact(
|
||||
'months', 'accounts', 'start', 'accountList',
|
||||
'startOfMonth', 'endOfMonth', 'startOfYear', 'endOfYear'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function defaultYear($reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$incomeTopLength = 8;
|
||||
$expenseTopLength = 8;
|
||||
|
||||
$accountReport = $this->helper->getAccountReport($start, $end, $accounts);
|
||||
$incomes = $this->helper->getIncomeReport($start, $end, $accounts);
|
||||
$expenses = $this->helper->getExpenseReport($start, $end, $accounts);
|
||||
|
||||
Session::flash('gaEventCategory', 'report');
|
||||
Session::flash('gaEventAction', 'year');
|
||||
Session::flash('gaEventLabel', $start->format('Y'));
|
||||
|
||||
// and some id's, joined:
|
||||
$accountIds = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountIds[] = $account->id;
|
||||
}
|
||||
$accountIds = join(',', $accountIds);
|
||||
|
||||
return view(
|
||||
'reports.default.year',
|
||||
compact(
|
||||
'start', 'accountReport', 'incomes', 'reportType', 'accountIds', 'end',
|
||||
'expenses', 'incomeTopLength', 'expenseTopLength'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
@ -189,6 +113,73 @@ class ReportController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function defaultYear($reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$incomeTopLength = 8;
|
||||
$expenseTopLength = 8;
|
||||
|
||||
$accountReport = $this->helper->getAccountReport($start, $end, $accounts);
|
||||
$incomes = $this->helper->getIncomeReport($start, $end, $accounts);
|
||||
$expenses = $this->helper->getExpenseReport($start, $end, $accounts);
|
||||
|
||||
Session::flash('gaEventCategory', 'report');
|
||||
Session::flash('gaEventAction', 'year');
|
||||
Session::flash('gaEventLabel', $start->format('Y'));
|
||||
|
||||
// and some id's, joined:
|
||||
$accountIds = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountIds[] = $account->id;
|
||||
}
|
||||
$accountIds = join(',', $accountIds);
|
||||
|
||||
return view(
|
||||
'reports.default.year',
|
||||
compact(
|
||||
'start', 'accountReport', 'incomes', 'reportType', 'accountIds', 'end',
|
||||
'expenses', 'incomeTopLength', 'expenseTopLength'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return View
|
||||
* @internal param ReportHelperInterface $helper
|
||||
*/
|
||||
public function index(ARI $repository)
|
||||
{
|
||||
$start = Session::get('first');
|
||||
$months = $this->helper->listOfMonths($start);
|
||||
|
||||
// does the user have shared accounts?
|
||||
$accounts = $repository->getAccounts(['Default account', 'Asset account']);
|
||||
// get id's for quick links:
|
||||
$accountIds = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountIds [] = $account->id;
|
||||
}
|
||||
$accountList = join(',', $accountIds);
|
||||
|
||||
|
||||
return view(
|
||||
'reports.index', compact(
|
||||
'months', 'accounts', 'start', 'accountList'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
|
493
app/Http/Controllers/RuleController.php
Normal file
493
app/Http/Controllers/RuleController.php
Normal file
@ -0,0 +1,493 @@
|
||||
<?php
|
||||
/**
|
||||
* RuleController.php
|
||||
* Copyright (C) 2016 Sander Dorigo
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Http\Requests\RuleFormRequest;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
use URL;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class RuleController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class RuleController extends Controller
|
||||
{
|
||||
/**
|
||||
* RuleController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
View::share('title', trans('firefly.rules'));
|
||||
View::share('mainTitleIcon', 'fa-random');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function create(RuleGroup $ruleGroup)
|
||||
{
|
||||
// count for possible present previous entered triggers/actions.
|
||||
$triggerCount = 0;
|
||||
$actionCount = 0;
|
||||
|
||||
// collection of those triggers/actions.
|
||||
$oldTriggers = [];
|
||||
$oldActions = [];
|
||||
|
||||
// has old input?
|
||||
if (Input::old()) {
|
||||
// process old triggers.
|
||||
$oldTriggers = $this->getPreviousTriggers();
|
||||
$triggerCount = count($oldTriggers);
|
||||
|
||||
// process old actions
|
||||
$oldActions = $this->getPreviousActions();
|
||||
$actionCount = count($oldActions);
|
||||
}
|
||||
|
||||
$subTitleIcon = 'fa-clone';
|
||||
$subTitle = trans('firefly.make_new_rule', ['title' => $ruleGroup->title]);
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (Session::get('rules.rule.create.fromStore') !== true) {
|
||||
Session::put('rules.rule.create.url', URL::previous());
|
||||
}
|
||||
Session::forget('rules.rule.create.fromStore');
|
||||
Session::flash('gaEventCategory', 'rules');
|
||||
Session::flash('gaEventAction', 'create-rule');
|
||||
|
||||
return view(
|
||||
'rules.rule.create', compact('subTitleIcon', 'oldTriggers', 'oldActions', 'triggerCount', 'actionCount', 'ruleGroup', 'subTitle')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return View
|
||||
* @internal param RuleRepositoryInterface $repository
|
||||
*/
|
||||
public function delete(Rule $rule)
|
||||
{
|
||||
$subTitle = trans('firefly.delete_rule', ['title' => $rule->title]);
|
||||
|
||||
// put previous url in session
|
||||
Session::put('rules.rule.delete.url', URL::previous());
|
||||
Session::flash('gaEventCategory', 'rules');
|
||||
Session::flash('gaEventAction', 'delete-rule');
|
||||
|
||||
return view('rules.rule.delete', compact('rule', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
* @param RuleRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(RuleRepositoryInterface $repository, Rule $rule)
|
||||
{
|
||||
|
||||
$title = $rule->title;
|
||||
$repository->destroy($rule);
|
||||
|
||||
Session::flash('success', trans('firefly.deleted_rule', ['title' => $title]));
|
||||
Preferences::mark();
|
||||
|
||||
|
||||
return redirect(Session::get('rules.rule.delete.url'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleRepositoryInterface $repository
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function down(RuleRepositoryInterface $repository, Rule $rule)
|
||||
{
|
||||
$repository->moveDown($rule);
|
||||
|
||||
return redirect(route('rules.index'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function edit(Rule $rule)
|
||||
{
|
||||
// has old input?
|
||||
if (Input::old()) {
|
||||
$oldTriggers = $this->getPreviousTriggers();
|
||||
$triggerCount = count($oldTriggers);
|
||||
$oldActions = $this->getPreviousActions();
|
||||
$actionCount = count($oldActions);
|
||||
} else {
|
||||
$oldTriggers = $this->getCurrentTriggers($rule);
|
||||
$triggerCount = count($oldTriggers);
|
||||
$oldActions = $this->getCurrentActions($rule);
|
||||
$actionCount = count($oldActions);
|
||||
}
|
||||
|
||||
// get rule trigger for update / store-journal:
|
||||
$primaryTrigger = $rule->ruleTriggers()->where('trigger_type', 'user_action')->first()->trigger_value;
|
||||
$subTitle = trans('firefly.edit_rule', ['title' => $rule->title]);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (Session::get('rules.rule.edit.fromUpdate') !== true) {
|
||||
Session::put('rules.rule.edit.url', URL::previous());
|
||||
}
|
||||
Session::forget('rules.rule.edit.fromUpdate');
|
||||
Session::flash('gaEventCategory', 'rules');
|
||||
Session::flash('gaEventAction', 'edit-rule');
|
||||
|
||||
return view('rules.rule.edit', compact('rule', 'subTitle', 'primaryTrigger', 'oldTriggers', 'oldActions', 'triggerCount', 'actionCount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->createDefaultRuleGroup();
|
||||
$this->createDefaultRule();
|
||||
|
||||
|
||||
$ruleGroups = Auth::user()
|
||||
->ruleGroups()
|
||||
->orderBy('active', 'DESC')
|
||||
->orderBy('order', 'ASC')
|
||||
->with(
|
||||
[
|
||||
'rules' => function ($query) {
|
||||
$query->orderBy('active', 'DESC');
|
||||
$query->orderBy('order', 'ASC');
|
||||
|
||||
},
|
||||
'rules.ruleTriggers' => function ($query) {
|
||||
$query->orderBy('order', 'ASC');
|
||||
},
|
||||
'rules.ruleActions' => function ($query) {
|
||||
$query->orderBy('order', 'ASC');
|
||||
},
|
||||
]
|
||||
)->get();
|
||||
|
||||
return view('rules.index', compact('ruleGroups'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleRepositoryInterface $repository
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function reorderRuleActions(RuleRepositoryInterface $repository, Rule $rule)
|
||||
{
|
||||
$ids = Input::get('actions');
|
||||
if (is_array($ids)) {
|
||||
$repository->reorderRuleActions($rule, $ids);
|
||||
}
|
||||
|
||||
return Response::json(true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleRepositoryInterface $repository
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function reorderRuleTriggers(RuleRepositoryInterface $repository, Rule $rule)
|
||||
{
|
||||
$ids = Input::get('triggers');
|
||||
if (is_array($ids)) {
|
||||
$repository->reorderRuleTriggers($rule, $ids);
|
||||
}
|
||||
|
||||
return Response::json(true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleFormRequest $request
|
||||
* @param RuleRepositoryInterface $repository
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function store(RuleFormRequest $request, RuleRepositoryInterface $repository, RuleGroup $ruleGroup)
|
||||
{
|
||||
|
||||
|
||||
// process the rule itself:
|
||||
$data = [
|
||||
'rule_group_id' => $ruleGroup->id,
|
||||
'title' => $request->get('title'),
|
||||
'trigger' => $request->get('trigger'),
|
||||
'description' => $request->get('description'),
|
||||
'rule-triggers' => $request->get('rule-trigger'),
|
||||
'rule-trigger-values' => $request->get('rule-trigger-value'),
|
||||
'rule-trigger-stop' => $request->get('rule-trigger-stop'),
|
||||
'rule-actions' => $request->get('rule-action'),
|
||||
'rule-action-values' => $request->get('rule-action-value'),
|
||||
'rule-action-stop' => $request->get('rule-action-stop'),
|
||||
'stop_processing' => $request->get('stop_processing'),
|
||||
];
|
||||
|
||||
$rule = $repository->store($data);
|
||||
Session::flash('success', trans('firefly.stored_new_rule', ['title' => $rule->title]));
|
||||
Preferences::mark();
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
// set value so create routine will not overwrite URL:
|
||||
Session::put('rules.rule.create.fromStore', true);
|
||||
|
||||
return redirect(route('rules.rule.create', [$request->input('what')]))->withInput();
|
||||
}
|
||||
|
||||
// redirect to previous URL.
|
||||
return redirect(Session::get('rules.rule.create.url'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleRepositoryInterface $repository
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function up(RuleRepositoryInterface $repository, Rule $rule)
|
||||
{
|
||||
$repository->moveUp($rule);
|
||||
|
||||
return redirect(route('rules.index'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleRepositoryInterface $repository
|
||||
* @param RuleFormRequest $request
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function update(RuleRepositoryInterface $repository, RuleFormRequest $request, Rule $rule)
|
||||
{
|
||||
|
||||
// process the rule itself:
|
||||
$data = [
|
||||
'title' => $request->get('title'),
|
||||
'active' => intval($request->get('active')) == 1,
|
||||
'trigger' => $request->get('trigger'),
|
||||
'description' => $request->get('description'),
|
||||
'rule-triggers' => $request->get('rule-trigger'),
|
||||
'rule-trigger-values' => $request->get('rule-trigger-value'),
|
||||
'rule-trigger-stop' => $request->get('rule-trigger-stop'),
|
||||
'rule-actions' => $request->get('rule-action'),
|
||||
'rule-action-values' => $request->get('rule-action-value'),
|
||||
'rule-action-stop' => $request->get('rule-action-stop'),
|
||||
'stop_processing' => intval($request->get('stop_processing')) == 1,
|
||||
];
|
||||
$repository->update($rule, $data);
|
||||
|
||||
Session::flash('success', trans('firefly.updated_rule', ['title' => $rule->title]));
|
||||
Preferences::mark();
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
// set value so edit routine will not overwrite URL:
|
||||
Session::put('rules.rule.edit.fromUpdate', true);
|
||||
|
||||
return redirect(route('rules.rule.edit', [$rule->id]))->withInput(['return_to_edit' => 1]);
|
||||
}
|
||||
|
||||
// redirect to previous URL.
|
||||
return redirect(Session::get('rules.rule.edit.url'));
|
||||
}
|
||||
|
||||
private function createDefaultRule()
|
||||
{
|
||||
/** @var RuleRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\Rule\RuleRepositoryInterface');
|
||||
|
||||
if ($repository->count() === 0) {
|
||||
$data = [
|
||||
'rule_group_id' => $repository->getFirstRuleGroup()->id,
|
||||
'stop_processing' => 0,
|
||||
'title' => trans('firefly.default_rule_name'),
|
||||
'description' => trans('firefly.default_rule_description'),
|
||||
'trigger' => 'store-journal',
|
||||
'rule-trigger-values' => [
|
||||
trans('firefly.default_rule_trigger_description'),
|
||||
trans('firefly.default_rule_trigger_from_account'),
|
||||
],
|
||||
'rule-action-values' => [
|
||||
trans('firefly.default_rule_action_prepend'),
|
||||
trans('firefly.default_rule_action_set_category'),
|
||||
],
|
||||
|
||||
'rule-triggers' => ['description_is', 'from_account_is'],
|
||||
'rule-actions' => ['prepend_description', 'set_category'],
|
||||
];
|
||||
|
||||
$repository->store($data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function createDefaultRuleGroup()
|
||||
{
|
||||
|
||||
/** @var RuleGroupRepositoryInterface $repository */
|
||||
$repository = app('FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface');
|
||||
|
||||
if ($repository->count() === 0) {
|
||||
$data = [
|
||||
'user' => Auth::user()->id,
|
||||
'title' => trans('firefly.default_rule_group_name'),
|
||||
'description' => trans('firefly.default_rule_group_description'),
|
||||
];
|
||||
|
||||
$repository->store($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getCurrentActions(Rule $rule)
|
||||
{
|
||||
$index = 0;
|
||||
$actions = [];
|
||||
|
||||
/** @var RuleAction $entry */
|
||||
foreach ($rule->ruleActions as $entry) {
|
||||
$count = ($index + 1);
|
||||
$actions[] = view(
|
||||
'rules.partials.action',
|
||||
[
|
||||
'oldTrigger' => $entry->action_type,
|
||||
'oldValue' => $entry->action_value,
|
||||
'oldChecked' => $entry->stop_processing,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
$index++;
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getCurrentTriggers(Rule $rule)
|
||||
{
|
||||
$index = 0;
|
||||
$triggers = [];
|
||||
|
||||
/** @var RuleTrigger $entry */
|
||||
foreach ($rule->ruleTriggers as $entry) {
|
||||
if ($entry->trigger_type != 'user_action') {
|
||||
$count = ($index + 1);
|
||||
$triggers[] = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => $entry->trigger_type,
|
||||
'oldValue' => $entry->trigger_value,
|
||||
'oldChecked' => $entry->stop_processing,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
|
||||
return $triggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getPreviousActions()
|
||||
{
|
||||
$newIndex = 0;
|
||||
$actions = [];
|
||||
foreach (Input::old('rule-action') as $index => $entry) {
|
||||
$count = ($newIndex + 1);
|
||||
$checked = isset(Input::old('rule-action-stop')[$index]) ? true : false;
|
||||
$actions[] = view(
|
||||
'rules.partials.action',
|
||||
[
|
||||
'oldTrigger' => $entry,
|
||||
'oldValue' => Input::old('rule-action-value')[$index],
|
||||
'oldChecked' => $checked,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
$newIndex++;
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getPreviousTriggers()
|
||||
{
|
||||
$newIndex = 0;
|
||||
$triggers = [];
|
||||
foreach (Input::old('rule-trigger') as $index => $entry) {
|
||||
$count = ($newIndex + 1);
|
||||
$oldChecked = isset(Input::old('rule-trigger-stop')[$index]) ? true : false;
|
||||
$triggers[] = view(
|
||||
'rules.partials.trigger',
|
||||
[
|
||||
'oldTrigger' => $entry,
|
||||
'oldValue' => Input::old('rule-trigger-value')[$index],
|
||||
'oldChecked' => $oldChecked,
|
||||
'count' => $count,
|
||||
]
|
||||
)->render();
|
||||
$newIndex++;
|
||||
}
|
||||
|
||||
return $triggers;
|
||||
}
|
||||
|
||||
|
||||
}
|
207
app/Http/Controllers/RuleGroupController.php
Normal file
207
app/Http/Controllers/RuleGroupController.php
Normal file
@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Http\Requests\RuleGroupFormRequest;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Session;
|
||||
use URL;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class RuleGroupController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class RuleGroupController extends Controller
|
||||
{
|
||||
/**
|
||||
* RuleGroupController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
View::share('title', trans('firefly.rules'));
|
||||
View::share('mainTitleIcon', 'fa-random');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$subTitleIcon = 'fa-clone';
|
||||
$subTitle = trans('firefly.make_new_rule_group');
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (Session::get('rules.rule-group.create.fromStore') !== true) {
|
||||
Session::put('rules.rule-group.create.url', URL::previous());
|
||||
}
|
||||
Session::forget('rules.rule-group.create.fromStore');
|
||||
Session::flash('gaEventCategory', 'rules');
|
||||
Session::flash('gaEventAction', 'create-rule-group');
|
||||
|
||||
return view('rules.rule-group.create', compact('subTitleIcon', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleGroupRepositoryInterface $repository
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function delete(RuleGroupRepositoryInterface $repository, RuleGroup $ruleGroup)
|
||||
{
|
||||
$subTitle = trans('firefly.delete_rule_group', ['title' => $ruleGroup->title]);
|
||||
|
||||
$ruleGroupList = Expandedform::makeSelectList($repository->get(), true);
|
||||
unset($ruleGroupList[$ruleGroup->id]);
|
||||
|
||||
// put previous url in session
|
||||
Session::put('rules.rule-group.delete.url', URL::previous());
|
||||
Session::flash('gaEventCategory', 'rules');
|
||||
Session::flash('gaEventAction', 'delete-rule-group');
|
||||
|
||||
return view('rules.rule-group.delete', compact('ruleGroup', 'subTitle', 'ruleGroupList'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleGroupRepositoryInterface $repository
|
||||
*
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(RuleGroupRepositoryInterface $repository, RuleGroup $ruleGroup)
|
||||
{
|
||||
|
||||
$title = $ruleGroup->title;
|
||||
$moveTo = Auth::user()->ruleGroups()->find(intval(Input::get('move_rules_before_delete')));
|
||||
|
||||
$repository->destroy($ruleGroup, $moveTo);
|
||||
|
||||
|
||||
Session::flash('success', trans('firefly.deleted_rule_group', ['title' => $title]));
|
||||
Preferences::mark();
|
||||
|
||||
|
||||
return redirect(Session::get('rules.rule-group.delete.url'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleGroupRepositoryInterface $repository
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function down(RuleGroupRepositoryInterface $repository, RuleGroup $ruleGroup)
|
||||
{
|
||||
$repository->moveDown($ruleGroup);
|
||||
|
||||
return redirect(route('rules.index'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function edit(RuleGroup $ruleGroup)
|
||||
{
|
||||
$subTitle = trans('firefly.edit_rule_group', ['title' => $ruleGroup->title]);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (Session::get('rules.rule-group.edit.fromUpdate') !== true) {
|
||||
Session::put('rules.rule-group.edit.url', URL::previous());
|
||||
}
|
||||
Session::forget('rules.rule-group.edit.fromUpdate');
|
||||
Session::flash('gaEventCategory', 'rules');
|
||||
Session::flash('gaEventAction', 'edit-rule-group');
|
||||
|
||||
return view('rules.rule-group.edit', compact('ruleGroup', 'subTitle'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleGroupFormRequest $request
|
||||
* @param RuleGroupRepositoryInterface $repository
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function store(RuleGroupFormRequest $request, RuleGroupRepositoryInterface $repository)
|
||||
{
|
||||
$data = [
|
||||
'title' => $request->input('title'),
|
||||
'description' => $request->input('description'),
|
||||
'user' => Auth::user()->id,
|
||||
];
|
||||
|
||||
$ruleGroup = $repository->store($data);
|
||||
|
||||
Session::flash('success', trans('firefly.created_new_rule_group', ['title' => $ruleGroup->title]));
|
||||
Preferences::mark();
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
// set value so create routine will not overwrite URL:
|
||||
Session::put('rules.rule-group.create.fromStore', true);
|
||||
|
||||
return redirect(route('rules.rule-group.create'))->withInput();
|
||||
}
|
||||
|
||||
// redirect to previous URL.
|
||||
return redirect(Session::get('rules.rule-group.create.url'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleGroupRepositoryInterface $repository
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function up(RuleGroupRepositoryInterface $repository, RuleGroup $ruleGroup)
|
||||
{
|
||||
$repository->moveUp($ruleGroup);
|
||||
|
||||
return redirect(route('rules.index'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RuleGroupFormRequest $request
|
||||
* @param RuleGroupRepositoryInterface $repository
|
||||
* @param RuleGroup $ruleGroup
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function update(RuleGroupFormRequest $request, RuleGroupRepositoryInterface $repository, RuleGroup $ruleGroup)
|
||||
{
|
||||
$data = [
|
||||
'title' => $request->input('title'),
|
||||
'description' => $request->input('description'),
|
||||
'active' => intval($request->input('active')) == 1,
|
||||
];
|
||||
|
||||
$repository->update($ruleGroup, $data);
|
||||
|
||||
Session::flash('success', trans('firefly.updated_rule_group', ['title' => $ruleGroup->title]));
|
||||
Preferences::mark();
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
// set value so edit routine will not overwrite URL:
|
||||
Session::put('rules.rule-group.edit.fromUpdate', true);
|
||||
|
||||
return redirect(route('rules.rule-group.edit', [$ruleGroup->id]))->withInput(['return_to_edit' => 1]);
|
||||
}
|
||||
|
||||
// redirect to previous URL.
|
||||
return redirect(Session::get('rules.rule-group.edit.url'));
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -10,6 +10,14 @@ use Input;
|
||||
*/
|
||||
class SearchController extends Controller
|
||||
{
|
||||
/**
|
||||
* SearchController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Results always come in the form of an array [results, count, fullCount]
|
||||
*
|
||||
|
@ -60,7 +60,7 @@ class TagController extends Controller
|
||||
$subTitleIcon = 'fa-tag';
|
||||
|
||||
$preFilled = [
|
||||
'tagMode' => 'nothing'
|
||||
'tagMode' => 'nothing',
|
||||
];
|
||||
if (!Input::old('tagMode')) {
|
||||
Session::flash('preFilled', $preFilled);
|
||||
|
@ -5,8 +5,8 @@ use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Events\JournalCreated;
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
use FireflyIII\Events\TransactionJournalStored;
|
||||
use FireflyIII\Events\TransactionJournalUpdated;
|
||||
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
|
||||
use FireflyIII\Http\Requests\JournalFormRequest;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
@ -18,6 +18,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Log;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
@ -57,9 +58,7 @@ class TransactionController extends Controller
|
||||
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account']));
|
||||
$budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get());
|
||||
$budgets[0] = trans('form.noBudget');
|
||||
|
||||
// piggy bank list:
|
||||
$piggyBanks = Auth::user()->piggyBanks()->orderBy('order', 'ASC')->get();
|
||||
$piggyBanks = Auth::user()->piggyBanks()->orderBy('order', 'ASC')->get();
|
||||
/** @var PiggyBank $piggy */
|
||||
foreach ($piggyBanks as $piggy) {
|
||||
$piggy->name = $piggy->name . ' (' . Amount::format($piggy->currentRelevantRep()->currentamount, false) . ')';
|
||||
@ -160,7 +159,7 @@ class TransactionController extends Controller
|
||||
'date' => $journal->date->format('Y-m-d'),
|
||||
'category' => '',
|
||||
'budget_id' => 0,
|
||||
'piggy_bank_id' => 0
|
||||
'piggy_bank_id' => 0,
|
||||
];
|
||||
// get tags:
|
||||
$preFilled['tags'] = join(',', $journal->tags->pluck('tag')->toArray());
|
||||
@ -294,7 +293,6 @@ class TransactionController extends Controller
|
||||
*/
|
||||
public function store(JournalFormRequest $request, JournalRepositoryInterface $repository, AttachmentHelperInterface $att)
|
||||
{
|
||||
|
||||
$journalData = $request->getJournalData();
|
||||
|
||||
// if not withdrawal, unset budgetid.
|
||||
@ -304,7 +302,6 @@ class TransactionController extends Controller
|
||||
|
||||
$journal = $repository->store($journalData);
|
||||
|
||||
// save attachments:
|
||||
$att->saveAttachmentsForModel($journal);
|
||||
|
||||
// flash errors
|
||||
@ -315,13 +312,9 @@ class TransactionController extends Controller
|
||||
if (count($att->getMessages()->get('attachments')) > 0) {
|
||||
Session::flash('info', $att->getMessages()->get('attachments'));
|
||||
}
|
||||
Log::debug('Before event. From account name is: ' . $journal->source_account->name);
|
||||
|
||||
// rescan journal, UpdateJournalConnection
|
||||
event(new JournalSaved($journal));
|
||||
|
||||
if ($journal->isTransfer() && intval($request->get('piggy_bank_id')) > 0) {
|
||||
event(new JournalCreated($journal, intval($request->get('piggy_bank_id'))));
|
||||
}
|
||||
event(new TransactionJournalStored($journal, intval($request->get('piggy_bank_id'))));
|
||||
|
||||
Session::flash('success', 'New transaction "' . $journal->description . '" stored!');
|
||||
Preferences::mark();
|
||||
@ -350,10 +343,6 @@ class TransactionController extends Controller
|
||||
public function update(JournalFormRequest $request, JournalRepositoryInterface $repository, AttachmentHelperInterface $att, TransactionJournal $journal)
|
||||
{
|
||||
|
||||
if ($journal->isOpeningBalance()) {
|
||||
return view('error')->with('message', 'Cannot edit this transaction. Edit the account instead!');
|
||||
}
|
||||
|
||||
$journalData = $request->getJournalData();
|
||||
$repository->update($journal, $journalData);
|
||||
|
||||
@ -369,7 +358,7 @@ class TransactionController extends Controller
|
||||
Session::flash('info', $att->getMessages()->get('attachments'));
|
||||
}
|
||||
|
||||
event(new JournalSaved($journal));
|
||||
event(new TransactionJournalUpdated($journal));
|
||||
// update, get events by date and sort DESC
|
||||
|
||||
Session::flash('success', 'Transaction "' . e($journalData['description']) . '" updated.');
|
||||
|
78
app/Http/Kernel.php
Normal file → Executable file
78
app/Http/Kernel.php
Normal file → Executable file
@ -1,6 +1,20 @@
|
||||
<?php namespace FireflyIII\Http;
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http;
|
||||
|
||||
use FireflyIII\Http\Middleware\Authenticate;
|
||||
use FireflyIII\Http\Middleware\Binder;
|
||||
use FireflyIII\Http\Middleware\EncryptCookies;
|
||||
use FireflyIII\Http\Middleware\Range;
|
||||
use FireflyIII\Http\Middleware\RedirectIfAuthenticated;
|
||||
use FireflyIII\Http\Middleware\VerifyCsrfToken;
|
||||
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
|
||||
/**
|
||||
* Class Kernel
|
||||
@ -9,35 +23,69 @@ use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
*/
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middleware
|
||||
= [
|
||||
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
|
||||
'Illuminate\Cookie\Middleware\EncryptCookies',
|
||||
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
|
||||
'Illuminate\Session\Middleware\StartSession',
|
||||
'Illuminate\View\Middleware\ShareErrorsFromSession',
|
||||
'FireflyIII\Http\Middleware\ReplaceTestVars',
|
||||
'FireflyIII\Http\Middleware\VerifyCsrfToken',
|
||||
CheckForMaintenanceMode::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middlewareGroups
|
||||
= [
|
||||
'web' => [
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
StartSession::class,
|
||||
ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
],
|
||||
'web-auth' => [
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
StartSession::class,
|
||||
ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
Authenticate::class,
|
||||
],
|
||||
'web-auth-range' => [
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
StartSession::class,
|
||||
ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
Authenticate::class,
|
||||
Range::class,
|
||||
Binder::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:60,1',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware
|
||||
= [
|
||||
'auth' => 'FireflyIII\Http\Middleware\Authenticate',
|
||||
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
|
||||
'guest' => 'FireflyIII\Http\Middleware\RedirectIfAuthenticated',
|
||||
'range' => 'FireflyIII\Http\Middleware\Range',
|
||||
|
||||
'auth' => Authenticate::class,
|
||||
'auth.basic' => AuthenticateWithBasicAuth::class,
|
||||
'guest' => RedirectIfAuthenticated::class,
|
||||
'throttle' => ThrottleRequests::class,
|
||||
'range' => Range::class,
|
||||
];
|
||||
|
||||
}
|
||||
|
59
app/Http/Middleware/Authenticate.php
Normal file → Executable file
59
app/Http/Middleware/Authenticate.php
Normal file → Executable file
@ -1,78 +1,37 @@
|
||||
<?php namespace FireflyIII\Http\Middleware;
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use App;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\Request;
|
||||
use Preferences;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
/**
|
||||
* Class Authenticate
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class Authenticate
|
||||
{
|
||||
|
||||
/**
|
||||
* The Guard implementation.
|
||||
*
|
||||
* @var Guard
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Create a new filter instance.
|
||||
*
|
||||
* @param Guard $auth
|
||||
*
|
||||
*/
|
||||
public function __construct(Guard $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $guard
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
{
|
||||
|
||||
if ($this->auth->guest()) {
|
||||
if (Auth::guard($guard)->guest()) {
|
||||
if ($request->ajax()) {
|
||||
return response('Unauthorized.', 401);
|
||||
} else {
|
||||
return redirect()->guest('auth/login');
|
||||
|
||||
return redirect()->guest('login');
|
||||
}
|
||||
}
|
||||
/** @var User $user */
|
||||
$user = $this->auth->user();
|
||||
if ($user instanceof User && intval($user->blocked) == 1) {
|
||||
Auth::logout();
|
||||
|
||||
return redirect()->route('index');
|
||||
}
|
||||
|
||||
// if logged in, set user language:
|
||||
$pref = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'));
|
||||
App::setLocale($pref->data);
|
||||
Carbon::setLocale(substr($pref->data, 0, 2));
|
||||
$locale = explode(',', trans('config.locale'));
|
||||
$locale = array_map('trim', $locale);
|
||||
|
||||
setlocale(LC_TIME, $locale);
|
||||
setlocale(LC_MONETARY, $locale);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
||||
|
60
app/Http/Middleware/Binder.php
Normal file
60
app/Http/Middleware/Binder.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use FireflyIII\Support\Domain;
|
||||
|
||||
/**
|
||||
* Class Binder
|
||||
*
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class Binder
|
||||
{
|
||||
protected $binders = [];
|
||||
|
||||
/**
|
||||
* Binder constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->binders = Domain::getBindables();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
foreach ($request->route()->parameters() as $key => $value) {
|
||||
if (isset($this->binders[$key])) {
|
||||
$boundObject = $this->performBinding($key, $value, $request->route());
|
||||
$request->route()->setParameter($key, $boundObject);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
||||
//return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param $value
|
||||
* @param $route
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function performBinding($key, $value, $route)
|
||||
{
|
||||
$class = $this->binders[$key];
|
||||
|
||||
return $class::routeBinder($value, $route);
|
||||
}
|
||||
}
|
23
app/Http/Middleware/EncryptCookies.php
Executable file
23
app/Http/Middleware/EncryptCookies.php
Executable file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as BaseEncrypter;
|
||||
|
||||
/**
|
||||
* Class EncryptCookies
|
||||
*
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class EncryptCookies extends BaseEncrypter
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except
|
||||
= [
|
||||
//
|
||||
];
|
||||
}
|
@ -6,12 +6,13 @@ namespace FireflyIII\Http\Middleware;
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Navigation;
|
||||
use Preferences;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
|
||||
/**
|
||||
* Class SessionFilter
|
||||
*
|
||||
@ -41,14 +42,15 @@ class Range
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $theNext
|
||||
* @param Closure $theNext
|
||||
* @param string|null $guard
|
||||
*
|
||||
* @return mixed
|
||||
* @internal param Closure $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $theNext)
|
||||
public function handle($request, Closure $theNext, $guard = null)
|
||||
{
|
||||
if ($this->auth->check()) {
|
||||
|
||||
if (!Auth::guard($guard)->guest()) {
|
||||
// ignore preference. set the range to be the current month:
|
||||
if (!Session::has('start') && !Session::has('end')) {
|
||||
|
||||
@ -71,6 +73,10 @@ class Range
|
||||
Session::put('first', Carbon::now()->startOfYear());
|
||||
}
|
||||
}
|
||||
|
||||
// check "sum of everything".
|
||||
|
||||
|
||||
$current = Carbon::now()->formatLocalized('%B %Y');
|
||||
$next = Carbon::now()->endOfMonth()->addDay()->formatLocalized('%B %Y');
|
||||
$prev = Carbon::now()->startOfMonth()->subDay()->formatLocalized('%B %Y');
|
||||
|
37
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file → Executable file
37
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file → Executable file
@ -1,52 +1,33 @@
|
||||
<?php namespace FireflyIII\Http\Middleware;
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
/**
|
||||
* Class RedirectIfAuthenticated
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
|
||||
/**
|
||||
* The Guard implementation.
|
||||
*
|
||||
* @var Guard
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Create a new filter instance.
|
||||
*
|
||||
* @param Guard $auth
|
||||
*
|
||||
*/
|
||||
public function __construct(Guard $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $guard
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
{
|
||||
if ($this->auth->check()) {
|
||||
return new RedirectResponse(url('/'));
|
||||
if (Auth::guard($guard)->check()) {
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ReplaceTestVars
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class ReplaceTestVars
|
||||
{
|
||||
/**
|
||||
* The application implementation.
|
||||
*
|
||||
* @var Application
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* Create a new filter instance.
|
||||
*
|
||||
* @param Application $app
|
||||
*
|
||||
*/
|
||||
public function __construct(Application $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ('testing' === $this->app->environment() && $request->has('_token')) {
|
||||
$input = $request->all();
|
||||
$input['_token'] = $request->session()->token();
|
||||
// we need to update _token value to make sure we get the POST / PUT tests passed.
|
||||
Log::debug('Input token replaced (' . $input['_token'] . ').');
|
||||
$request->replace($input);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
@ -1,27 +1,22 @@
|
||||
<?php namespace FireflyIII\Http\Middleware;
|
||||
<?php
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
|
||||
|
||||
/**
|
||||
* Class VerifyCsrfToken
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class VerifyCsrfToken extends BaseVerifier
|
||||
{
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
* @var array
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
return parent::handle($request, $next);
|
||||
}
|
||||
protected $except
|
||||
= [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ class AccountFormRequest extends Request
|
||||
'ccMonthlyPaymentDate' => 'date',
|
||||
'amount_currency_id_openingBalance' => 'exists:transaction_currencies,id',
|
||||
'amount_currency_id_virtualBalance' => 'exists:transaction_currencies,id',
|
||||
'what' => 'in:' . $types
|
||||
'what' => 'in:' . $types,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class BudgetFormRequest extends Request
|
||||
|
||||
return [
|
||||
'name' => $nameRule,
|
||||
'active' => 'numeric|between:0,1'
|
||||
'active' => 'numeric|between:0,1',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
7
app/Http/Requests/Request.php
Normal file → Executable file
7
app/Http/Requests/Request.php
Normal file → Executable file
@ -1,16 +1,15 @@
|
||||
<?php namespace FireflyIII\Http\Requests;
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
/**
|
||||
* Class Request
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
abstract class Request extends FormRequest
|
||||
{
|
||||
|
||||
//
|
||||
|
||||
}
|
||||
|
68
app/Http/Requests/RuleFormRequest.php
Normal file
68
app/Http/Requests/RuleFormRequest.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* RuleFormRequest.php
|
||||
* Copyright (C) 2016 Sander Dorigo
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use Config;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class RuleFormRequest
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class RuleFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$validTriggers = array_keys(Config::get('firefly.rule-triggers'));
|
||||
$validActions = array_keys(Config::get('firefly.rule-actions'));
|
||||
|
||||
// some actions require text:
|
||||
$contextActions = join(',', Config::get('firefly.rule-actions-text'));
|
||||
|
||||
$titleRule = 'required|between:1,100|uniqueObjectForUser:rule_groups,title';
|
||||
if (RuleGroup::find(Input::get('id'))) {
|
||||
$titleRule = 'required|between:1,100|uniqueObjectForUser:rule_groups,title,' . intval(Input::get('id'));
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'title' => $titleRule,
|
||||
'description' => 'between:1,5000',
|
||||
'stop_processing' => 'boolean',
|
||||
'rule_group_id' => 'required|belongsToUser:rule_groups',
|
||||
'trigger' => 'required|in:store-journal,update-journal',
|
||||
'rule-trigger.*' => 'required|in:' . join(',', $validTriggers),
|
||||
'rule-trigger-value.*' => 'required|min:1|ruleTriggerValue',
|
||||
'rule-action.*' => 'required|in:' . join(',', $validActions),
|
||||
];
|
||||
// since Laravel does not support this stuff yet, here's a trick.
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$rules['rule-action-value.' . $i] = 'required_if:rule-action.' . $i . ',' . $contextActions . '|ruleActionValue';
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
49
app/Http/Requests/RuleGroupFormRequest.php
Normal file
49
app/Http/Requests/RuleGroupFormRequest.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* RuleGroupFormRequest.php
|
||||
* Copyright (C) 2016 Sander Dorigo
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class RuleGroupFormRequest
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class RuleGroupFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$titleRule = 'required|between:1,100|uniqueObjectForUser:rule_groups,title';
|
||||
if (RuleGroup::find(Input::get('id'))) {
|
||||
$titleRule = 'required|between:1,100|uniqueObjectForUser:rule_groups,title,' . intval(Input::get('id'));
|
||||
}
|
||||
|
||||
return [
|
||||
'title' => $titleRule,
|
||||
'description' => 'between:1,5000',
|
||||
];
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ class TagFormRequest extends Request
|
||||
'latitude' => 'numeric|min:-90|max:90',
|
||||
'longitude' => 'numeric|min:-90|max:90',
|
||||
'zoomLevel' => 'numeric|min:0|max:80',
|
||||
'tagMode' => 'required|in:nothing,balancingAct,advancePayment'
|
||||
'tagMode' => 'required|in:nothing,balancingAct,advancePayment',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -361,6 +361,16 @@ Breadcrumbs::register(
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Rules
|
||||
*/
|
||||
Breadcrumbs::register(
|
||||
'rules.index', function (BreadCrumbGenerator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push(trans('firefly.rules'), route('rules.index'));
|
||||
}
|
||||
);
|
||||
|
||||
// search
|
||||
Breadcrumbs::register(
|
||||
'search', function (BreadCrumbGenerator $breadcrumbs, $query) {
|
||||
|
@ -1,280 +1,33 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
// auth routes, i think
|
||||
Route::group(
|
||||
['middleware' => 'web'], function () {
|
||||
|
||||
// Authentication Routes...
|
||||
Route::get('/login', 'Auth\AuthController@showLoginForm');
|
||||
Route::post('/login', 'Auth\AuthController@login');
|
||||
Route::get('/logout', 'Auth\AuthController@logout');
|
||||
|
||||
// Registration Routes...
|
||||
Route::get('/register', ['uses' => 'Auth\AuthController@showRegistrationForm', 'as' => 'register']);
|
||||
Route::post('/register', 'Auth\AuthController@register');
|
||||
|
||||
Route::get('/password/reset', 'Auth\PasswordController@getReset');
|
||||
|
||||
// Password Reset Routes...
|
||||
Route::get('/password/reset/{token?}', 'Auth\PasswordController@showResetForm');
|
||||
Route::post('/password/email', 'Auth\PasswordController@sendResetLinkEmail');
|
||||
Route::post('/password/reset', 'Auth\PasswordController@reset');
|
||||
|
||||
|
||||
// models
|
||||
Route::bind(
|
||||
'account',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.editable', 1)
|
||||
->where('accounts.id', $value)
|
||||
->where('user_id', Auth::user()->id)
|
||||
->first(['accounts.*']);
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
// accounts
|
||||
Route::bind(
|
||||
'accountList',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
$ids = explode(',', $value);
|
||||
/** @var \Illuminate\Support\Collection $object */
|
||||
$object = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.editable', 1)
|
||||
->whereIn('accounts.id', $ids)
|
||||
->where('user_id', Auth::user()->id)
|
||||
->get(['accounts.*']);
|
||||
if ($object->count() > 0) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
// budget list
|
||||
Route::bind(
|
||||
'budgetList',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
$ids = explode(',', $value);
|
||||
/** @var \Illuminate\Support\Collection $object */
|
||||
$object = Budget::where('active', 1)
|
||||
->whereIn('id', $ids)
|
||||
->where('user_id', Auth::user()->id)
|
||||
->get();
|
||||
|
||||
// add empty budget if applicable.
|
||||
if (in_array('0', $ids)) {
|
||||
$object->push(new Budget);
|
||||
}
|
||||
|
||||
if ($object->count() > 0) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
// category list
|
||||
Route::bind(
|
||||
'categoryList',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
$ids = explode(',', $value);
|
||||
/** @var \Illuminate\Support\Collection $object */
|
||||
$object = Category::whereIn('id', $ids)
|
||||
->where('user_id', Auth::user()->id)
|
||||
->get();
|
||||
|
||||
// add empty budget if applicable.
|
||||
if (in_array('0', $ids)) {
|
||||
$object->push(new Category);
|
||||
}
|
||||
|
||||
if ($object->count() > 0) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
// Date
|
||||
Route::bind(
|
||||
'start_date',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
|
||||
try {
|
||||
$date = new Carbon($value);
|
||||
} catch (Exception $e) {
|
||||
Log::error('Could not parse date "' . $value . '" for user #' . Auth::user()->id);
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
// Date
|
||||
Route::bind(
|
||||
'end_date',
|
||||
function ($value) {
|
||||
if (Auth::check()) {
|
||||
|
||||
try {
|
||||
$date = new Carbon($value);
|
||||
} catch (Exception $e) {
|
||||
Log::error('Could not parse date "' . $value . '" for user #' . Auth::user()->id);
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'tj', function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = TransactionJournal::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException;
|
||||
//Route::get('/home', 'HomeController@index');
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'attachment', function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = Attachment::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'currency', function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = TransactionCurrency::find($value);
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'bill', function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = Bill::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'budget', function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = Budget::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'limitrepetition', function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = LimitRepetition::where('limit_repetitions.id', $value)
|
||||
->leftjoin('budget_limits', 'budget_limits.id', '=', 'limit_repetitions.budget_limit_id')
|
||||
->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
|
||||
->where('budgets.user_id', Auth::user()->id)
|
||||
->first(['limit_repetitions.*']);
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'piggyBank', function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = PiggyBank::where('piggy_banks.id', $value)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
|
||||
->where('accounts.user_id', Auth::user()->id)
|
||||
->first(['piggy_banks.*']);
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'category', function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = Category::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'tag', function ($value) {
|
||||
if (Auth::check()) {
|
||||
$object = Tag::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
if ($object) {
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Auth\AuthController
|
||||
*/
|
||||
Route::get('/register', ['uses' => 'Auth\AuthController@getRegister', 'as' => 'register']);
|
||||
|
||||
Route::controllers(
|
||||
[
|
||||
'auth' => 'Auth\AuthController',
|
||||
'password' => 'Auth\PasswordController',
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
Route::group(
|
||||
['middleware' => ['auth', 'range']], function () {
|
||||
['middleware' => ['web-auth-range']], function () {
|
||||
|
||||
/**
|
||||
* Home Controller
|
||||
@ -449,6 +202,9 @@ Route::group(
|
||||
Route::get('/json/box/bills-paid', ['uses' => 'JsonController@boxBillsPaid', 'as' => 'json.box.unpaid']);
|
||||
Route::get('/json/transaction-journals/{what}', 'JsonController@transactionJournals');
|
||||
|
||||
Route::get('/json/trigger', ['uses' => 'JsonController@trigger', 'as' => 'json.trigger']);
|
||||
Route::get('/json/action', ['uses' => 'JsonController@action', 'as' => 'json.action']);
|
||||
|
||||
/**
|
||||
* New user Controller
|
||||
*/
|
||||
@ -493,6 +249,39 @@ Route::group(
|
||||
Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']);
|
||||
Route::get('/reports/report/{reportType}/{start_date}/{end_date}/{accountList}', ['uses' => 'ReportController@report', 'as' => 'reports.report']);
|
||||
|
||||
/**
|
||||
* Rules Controller
|
||||
*/
|
||||
// index
|
||||
Route::get('/rules', ['uses' => 'RuleController@index', 'as' => 'rules.index']);
|
||||
|
||||
// rules GET:
|
||||
Route::get('/rules/create/{ruleGroup}', ['uses' => 'RuleController@create', 'as' => 'rules.rule.create']);
|
||||
Route::get('/rules/rules/up/{rule}', ['uses' => 'RuleController@up', 'as' => 'rules.rule.up']);
|
||||
Route::get('/rules/rules/down/{rule}', ['uses' => 'RuleController@down', 'as' => 'rules.rule.down']);
|
||||
Route::get('/rules/rules/edit/{rule}', ['uses' => 'RuleController@edit', 'as' => 'rules.rule.edit']);
|
||||
Route::get('/rules/rules/delete/{rule}', ['uses' => 'RuleController@delete', 'as' => 'rules.rule.delete']);
|
||||
|
||||
// rules POST:
|
||||
Route::post('/rules/rules/trigger/reorder/{rule}', ['uses' => 'RuleController@reorderRuleTriggers']);
|
||||
Route::post('/rules/rules/action/reorder/{rule}', ['uses' => 'RuleController@reorderRuleActions']);
|
||||
Route::post('/rules/store/{ruleGroup}', ['uses' => 'RuleController@store', 'as' => 'rules.rule.store']);
|
||||
Route::post('/rules/update/{rule}', ['uses' => 'RuleController@update', 'as' => 'rules.rule.update']);
|
||||
Route::post('/rules/destroy/{rule}', ['uses' => 'RuleController@destroy', 'as' => 'rules.rule.destroy']);
|
||||
|
||||
|
||||
// rule groups GET
|
||||
Route::get('/rules/groups/create', ['uses' => 'RuleGroupController@create', 'as' => 'rules.rule-group.create']);
|
||||
Route::get('/rules/groups/edit/{ruleGroup}', ['uses' => 'RuleGroupController@edit', 'as' => 'rules.rule-group.edit']);
|
||||
Route::get('/rules/groups/delete/{ruleGroup}', ['uses' => 'RuleGroupController@delete', 'as' => 'rules.rule-group.delete']);
|
||||
Route::get('/rules/groups/up/{ruleGroup}', ['uses' => 'RuleGroupController@up', 'as' => 'rules.rule-group.up']);
|
||||
Route::get('/rules/groups/down/{ruleGroup}', ['uses' => 'RuleGroupController@down', 'as' => 'rules.rule-group.down']);
|
||||
|
||||
// rule groups POST
|
||||
Route::post('/rules/groups/store', ['uses' => 'RuleGroupController@store', 'as' => 'rules.rule-group.store']);
|
||||
Route::post('/rules/groups/update/{ruleGroup}', ['uses' => 'RuleGroupController@update', 'as' => 'rules.rule-group.update']);
|
||||
Route::post('/rules/groups/destroy/{ruleGroup}', ['uses' => 'RuleGroupController@destroy', 'as' => 'rules.rule-group.destroy']);
|
||||
|
||||
/**
|
||||
* Search Controller
|
||||
*/
|
||||
@ -537,7 +326,7 @@ Route::group(
|
||||
/**
|
||||
* Auth\Auth Controller
|
||||
*/
|
||||
Route::get('/logout', ['uses' => 'Auth\AuthController@getLogout', 'as' => 'logout']);
|
||||
Route::get('/logout', ['uses' => 'Auth\AuthController@logout', 'as' => 'logout']);
|
||||
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user