From af9473c126b84b2545efa764fbff9f7b2575734c Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Mon, 10 Nov 2014 19:03:03 +0100 Subject: [PATCH 001/193] Fixed some bugs in various controllers and started rebuilding the category controller. --- app/controllers/AccountController.php | 2 +- app/controllers/BudgetController.php | 4 +- app/controllers/CategoryController.php | 69 +++++--- app/controllers/GoogleTableController.php | 36 +++- app/lib/FireflyIII/Database/Budget.php | 21 ++- app/lib/FireflyIII/Database/Category.php | 49 +++++- app/routes.php | 1 + app/views/accounts/edit.blade.php | 8 - app/views/accounts/index.blade.php | 5 +- app/views/categories/delete.blade.php | 38 ++-- app/views/categories/edit.blade.php | 57 +++--- app/views/categories/index.blade.php | 59 +++---- .../assets/javascript/firefly/categories.js | 162 +++++++++--------- 13 files changed, 291 insertions(+), 220 deletions(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index da88631243..08ddca55e8 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -312,7 +312,7 @@ class AccountController extends BaseController default: throw new FireflyException('Cannot handle post_submit_action "' . e($data['post_submit_action']) . '"'); break; - case 'create_another': + case 'return_to_edit': case 'store': $messages = $acct->validate($data); /** @var MessageBag $messages ['errors'] */ diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php index 54e095461d..6156d76c2d 100644 --- a/app/controllers/BudgetController.php +++ b/app/controllers/BudgetController.php @@ -263,7 +263,7 @@ class BudgetController extends BaseController default: throw new FireflyException('Cannot handle post_submit_action "' . e(Input::get('post_submit_action')) . '"'); break; - case 'create_another': + case 'return_to_edit': case 'update': $messages = $repos->validate($data); /** @var MessageBag $messages ['errors'] */ @@ -277,7 +277,7 @@ class BudgetController extends BaseController $repos->update($budget, $data); Session::flash('success', 'Budget updated!'); - if ($data['post_submit_action'] == 'create_another') { + if ($data['post_submit_action'] == 'return_to_edit') { return Redirect::route('budgets.edit', $budget->id); } else { return Redirect::route('budgets.index'); diff --git a/app/controllers/CategoryController.php b/app/controllers/CategoryController.php index 6b1d7a4e44..55a6e629d3 100644 --- a/app/controllers/CategoryController.php +++ b/app/controllers/CategoryController.php @@ -1,26 +1,17 @@ _repository = $repository; - $this->_category = $category; View::share('title', 'Categories'); View::share('mainTitleIcon', 'fa-bar-chart'); } @@ -40,8 +31,7 @@ class CategoryController extends BaseController */ public function delete(Category $category) { - return View::make('categories.delete')->with('category', $category) - ->with('subTitle', 'Delete category "' . $category->name . '"'); + return View::make('categories.delete')->with('category', $category)->with('subTitle', 'Delete category "' . $category->name . '"'); } /** @@ -51,7 +41,10 @@ class CategoryController extends BaseController */ public function destroy(Category $category) { - $this->_repository->destroy($category); + /** @var \FireflyIII\Database\Category $repos */ + $repos = App::make('FireflyIII\Database\Category'); + + $repos->destroy($category); Session::flash('success', 'The category was deleted.'); return Redirect::route('categories.index'); } @@ -72,10 +65,7 @@ class CategoryController extends BaseController */ public function index() { - $categories = $this->_repository->get(); - - return View::make('categories.index')->with('categories', $categories) - ->with('subTitle', 'All your categories'); + return View::make('categories.index'); } /** @@ -124,15 +114,40 @@ class CategoryController extends BaseController */ public function update(Category $category) { - $category = $this->_repository->update($category, Input::all()); - if ($category->validate()) { - Session::flash('success', 'Category "' . $category->name . '" updated.'); + /** @var \FireflyIII\Database\Category $repos */ + $repos = App::make('FireflyIII\Database\Category'); + $data = Input::except('_token'); - return Redirect::route('categories.index'); - } else { - Session::flash('success', 'Could not update category "' . $category->name . '".'); + switch (Input::get('post_submit_action')) { + default: + throw new FireflyException('Cannot handle post_submit_action "' . e(Input::get('post_submit_action')) . '"'); + break; + case 'return_to_edit': + case 'update': + $messages = $repos->validate($data); + /** @var MessageBag $messages ['errors'] */ + if ($messages['errors']->count() > 0) { + Session::flash('warnings', $messages['warnings']); + Session::flash('successes', $messages['successes']); + Session::flash('error', 'Could not save category: ' . $messages['errors']->first()); + return Redirect::route('categories.edit', $category->id)->withInput()->withErrors($messages['errors']); + } + // store! + $repos->update($category, $data); + Session::flash('success', 'Category updated!'); - return Redirect::route('categories.edit')->withErrors($category->errors())->withInput(); + if ($data['post_submit_action'] == 'return_to_edit') { + return Redirect::route('categories.edit', $category->id); + } else { + return Redirect::route('categories.index'); + } + case 'validate_only': + $messageBags = $repos->validate($data); + Session::flash('warnings', $messageBags['warnings']); + Session::flash('successes', $messageBags['successes']); + Session::flash('errors', $messageBags['errors']); + return Redirect::route('categories.edit', $category->id)->withInput(); + break; } diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php index 8f51270363..80b652fe4b 100644 --- a/app/controllers/GoogleTableController.php +++ b/app/controllers/GoogleTableController.php @@ -8,6 +8,38 @@ use Firefly\Exception\FireflyException; class GoogleTableController extends BaseController { + /** + * @return \Illuminate\Http\JsonResponse + */ + public function categoryList() + { + + /** @var \FireflyIII\Database\Category $repos */ + $repos = App::make('FireflyIII\Database\Category'); + + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('ID', 'number'); + $chart->addColumn('ID_Edit', 'string'); + $chart->addColumn('ID_Delete', 'string'); + $chart->addColumn('Name_URL', 'string'); + $chart->addColumn('Name', 'string'); + + $list = $repos->get(); + + /** @var Category $entry */ + foreach ($list as $entry) { + $chart->addRow( + $entry->id, route('categories.edit', $entry->id), route('categories.delete', $entry->id), route('categories.show', $entry->id), $entry->name + ); + } + + + $chart->generate(); + return Response::json($chart->getData()); + + } + /** * @param $what * @@ -84,8 +116,8 @@ class GoogleTableController extends BaseController if (is_null($repetition)) { $journals = $budget->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->orderBy('date', 'DESC')->get(); } else { - $journals = $budget->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])-> - after($repetition->startdate)->before($repetition->enddate)->orderBy('date', 'DESC')->get(); + $journals = $budget->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->after($repetition->startdate) + ->before($repetition->enddate)->orderBy('date', 'DESC')->get(); } /** @var TransactionJournal $transaction */ foreach ($journals as $journal) { diff --git a/app/lib/FireflyIII/Database/Budget.php b/app/lib/FireflyIII/Database/Budget.php index ba8d22fcf4..934941adf7 100644 --- a/app/lib/FireflyIII/Database/Budget.php +++ b/app/lib/FireflyIII/Database/Budget.php @@ -9,6 +9,7 @@ use Illuminate\Support\Collection; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\BudgetInterface; + /** * Class Budget * @@ -80,11 +81,11 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface $successes = new MessageBag; $errors = new MessageBag; - if(isset($model['name'])) { - if(strlen($model['name']) < 1) { + if (isset($model['name'])) { + if (strlen($model['name']) < 1) { $errors->add('name', 'Name is too short'); } - if(strlen($model['name']) > 200) { + if (strlen($model['name']) > 200) { $errors->add('name', 'Name is too long'); } @@ -98,8 +99,8 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface } - if(!$errors->has('name')) { - $successes->add('name','OK'); + if (!$errors->has('name')) { + $successes->add('name', 'OK'); } return [ @@ -118,7 +119,7 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface { $data['user_id'] = $this->getUser()->id; - $budget = new \Budget($data); + $budget = new \Budget($data); $budget->class = 'Budget'; if (!$budget->validate()) { @@ -155,10 +156,12 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface /** * @param \Budget $budget - * @param Carbon $date + * @param Carbon $date + * * @return float */ - public function spentInMonth(\Budget $budget, Carbon $date) { + public function spentInMonth(\Budget $budget, Carbon $date) + { $end = clone $date; $date->startOfMonth(); $end->endOfMonth(); @@ -220,7 +223,7 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface */ public function update(Ardent $model, array $data) { - $model->name = $data['name']; + $model->name = $data['name']; if (!$model->validate()) { var_dump($model->errors()->all()); exit; diff --git a/app/lib/FireflyIII/Database/Category.php b/app/lib/FireflyIII/Database/Category.php index 47349ac021..9e9ec6c93b 100644 --- a/app/lib/FireflyIII/Database/Category.php +++ b/app/lib/FireflyIII/Database/Category.php @@ -2,6 +2,7 @@ namespace FireflyIII\Database; use Carbon\Carbon; +use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\MessageBag; use LaravelBook\Ardent\Ardent; use Illuminate\Support\Collection; @@ -33,7 +34,8 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface */ public function destroy(Ardent $model) { - // TODO: Implement destroy() method. + $model->delete(); + return true; } /** @@ -59,7 +61,37 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface */ public function validate(array $model) { - // TODO: Implement validate() method. + $warnings = new MessageBag; + $successes = new MessageBag; + $errors = new MessageBag; + + if (isset($model['name'])) { + if (strlen($model['name']) < 1) { + $errors->add('name', 'Name is too short'); + } + if (strlen($model['name']) > 200) { + $errors->add('name', 'Name is too long'); + + } + } else { + $errors->add('name', 'Name is mandatory'); + } + $validator = \Validator::make($model, \Component::$rules); + + if ($validator->invalid()) { + $errors->merge($validator->errors()); + } + + + if (!$errors->has('name')) { + $successes->add('name', 'OK'); + } + + return [ + 'errors' => $errors, + 'warnings' => $warnings, + 'successes' => $successes + ]; } /** @@ -91,7 +123,7 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface */ public function get() { - // TODO: Implement get() method. + return $this->getUser()->categories()->orderBy('name', 'ASC')->get(); } /** @@ -124,6 +156,15 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface */ public function update(Ardent $model, array $data) { - // TODO: Implement update() method. + $model->name = $data['name']; + if (!$model->validate()) { + var_dump($model->errors()->all()); + exit; + } + + + $model->save(); + + return true; } } \ No newline at end of file diff --git a/app/routes.php b/app/routes.php index 4d85b37703..8b804a5d77 100644 --- a/app/routes.php +++ b/app/routes.php @@ -174,6 +174,7 @@ Route::group( // google table controller Route::get('/table/account/{account}/transactions', ['uses' => 'GoogleTableController@transactionsByAccount']); Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']); + Route::get('/table/categories', ['uses' => 'GoogleTableController@categoryList']); Route::get('/table/budget/{budget}/{limitrepetition?}/transactions', ['uses' => 'GoogleTableController@transactionsByBudget']); diff --git a/app/views/accounts/edit.blade.php b/app/views/accounts/edit.blade.php index 39e14486ca..47e3ee60c2 100644 --- a/app/views/accounts/edit.blade.php +++ b/app/views/accounts/edit.blade.php @@ -1,13 +1,5 @@ @extends('layouts.default') @section('content') -
-
-

- Bla text here. -

-
-
- {{Form::model($account, ['class' => 'form-horizontal','url' => route('accounts.update',$account->id)])}}
diff --git a/app/views/accounts/index.blade.php b/app/views/accounts/index.blade.php index 2410bc6c8e..2f43b6fbe2 100644 --- a/app/views/accounts/index.blade.php +++ b/app/views/accounts/index.blade.php @@ -40,7 +40,4 @@ -@stop - -@section('styles') -@endsection \ No newline at end of file +@stop \ No newline at end of file diff --git a/app/views/categories/delete.blade.php b/app/views/categories/delete.blade.php index 9524245af1..75e2d5929e 100644 --- a/app/views/categories/delete.blade.php +++ b/app/views/categories/delete.blade.php @@ -1,37 +1,31 @@ @extends('layouts.default') @section('content') -
-
-

- Remember that deleting something is permanent. -

-
-
- {{Form::open(['class' => 'form-horizontal','url' => route('categories.destroy',$category->id)])}}
-
- @if($category->transactionjournals()->count() > 0) -

+

+
+
+ Delete category "{{{$category->name}}}" +
+
+

+ Are you sure? +

- Account "{{{$category->name}}}" still has {{$category->transactionjournals()->count()}} transaction(s) associated to it. - These will NOT be deleted but will lose their connection to the category. -

- @endif - -

- Press "Delete permanently" If you are sure you want to delete "{{{$category->name}}}". -

+

+ + Cancel +

+
+
-
- - Cancel +
diff --git a/app/views/categories/edit.blade.php b/app/views/categories/edit.blade.php index d747576b34..bf4fcaf6ff 100644 --- a/app/views/categories/edit.blade.php +++ b/app/views/categories/edit.blade.php @@ -1,46 +1,37 @@ @extends('layouts.default') @section('content') +{{Form::model($category, ['class' => 'form-horizontal','url' => route('categories.update',$category->id)])}}
-
-

Use categories to group your expenses

+
+
+
+ Mandatory fields +
+
+ {{Form::ffText('name')}} +
+
+

+ +

-
- -{{Form::open(['class' => 'form-horizontal','url' => route('categories.update',$category->id)])}} +
-
-
-

Mandatory fields

- -
- -
- - @if($errors->has('name')) -

{{$errors->first('name')}}

- @else - For example: bike, utilities, daily groceries - @endif + +
+
+ Options +
+
+ {{Form::ffOptionsList('update','category')}}
- -
- -
-
- -
-
- -
-
-
{{Form::close()}} - - -@stop +@stop \ No newline at end of file diff --git a/app/views/categories/index.blade.php b/app/views/categories/index.blade.php index 78a2451a1f..86cb093906 100644 --- a/app/views/categories/index.blade.php +++ b/app/views/categories/index.blade.php @@ -2,37 +2,38 @@ @section('content')
-

Use categories to group your expenses

-

- Use categories to group expenses by hobby, for certain types of groceries or what bills are for. - Expenses grouped in categories do not have to reoccur every month or every week, like budgets. -

-

- Create a new category -

-
-
+
+
+ Categories -
-
- - - - - @foreach($categories as $category) - - - - - @endforeach -
- {{{$category->name}}} - -
- - + +
+
+ +
-
+
+ + +
+
+
+
+
+@stop +@section('scripts') + + +{{HTML::script('assets/javascript/firefly/gcharts.options.js')}} +{{HTML::script('assets/javascript/firefly/gcharts.js')}} + + + @stop \ No newline at end of file diff --git a/public/assets/javascript/firefly/categories.js b/public/assets/javascript/firefly/categories.js index b81fff48d1..4b959ed181 100644 --- a/public/assets/javascript/firefly/categories.js +++ b/public/assets/javascript/firefly/categories.js @@ -1,90 +1,94 @@ $(function () { -if($('#chart').length == 1) { - /** - * get data from controller for home charts: - */ - $.getJSON('chart/categories/show/' + categoryID).success(function (data) { - var options = { - chart: { - renderTo: 'chart', - type: 'column' - }, - series: [data.series], - title: { - text: data.chart_title - }, - yAxis: { - formatter: function () { - return '$' + Highcharts.numberFormat(this.y, 0); - } - }, - subtitle: { - text: data.subtitle, - useHTML: true - }, - xAxis: { - floor: 0, - type: 'category', - title: { - text: 'Period' - } - }, - tooltip: { - shared: true, - crosshairs: false, - formatter: function () { - var str = '' + Highcharts.dateFormat("%A, %e %B", this.x) + '
'; - for (x in this.points) { - var point = this.points[x]; - var colour = point.point.pointAttr[''].fill; - str += '' + point.series.name + ': \u20AC ' + Highcharts.numberFormat(point.y, 2) + '
'; - } - //console.log(); - return str; - return '' + this.series.name + ' on ' + Highcharts.dateFormat("%e %B", this.x) + ':
\u20AC ' + Highcharts.numberFormat(this.y, 2); - } - }, - plotOptions: { - line: { - shadow: true + if (typeof googleTable == 'function') { + googleTable('table/categories', 'category-list'); + } + + if ($('#chart').length == 1) { + /** + * get data from controller for home charts: + */ + $.getJSON('chart/categories/show/' + categoryID).success(function (data) { + var options = { + chart: { + renderTo: 'chart', + type: 'column' }, - series: { - cursor: 'pointer', - negativeColor: '#FF0000', - threshold: 0, - lineWidth: 1, - marker: { - radius: 2 + series: [data.series], + title: { + text: data.chart_title + }, + yAxis: { + formatter: function () { + return '$' + Highcharts.numberFormat(this.y, 0); + } + }, + subtitle: { + text: data.subtitle, + useHTML: true + }, + + xAxis: { + floor: 0, + type: 'category', + title: { + text: 'Period' + } + }, + tooltip: { + shared: true, + crosshairs: false, + formatter: function () { + var str = '' + Highcharts.dateFormat("%A, %e %B", this.x) + '
'; + for (x in this.points) { + var point = this.points[x]; + var colour = point.point.pointAttr[''].fill; + str += '' + point.series.name + ': \u20AC ' + Highcharts.numberFormat(point.y, 2) + '
'; + } + //console.log(); + return str; + return '' + this.series.name + ' on ' + Highcharts.dateFormat("%e %B", this.x) + ':
\u20AC ' + Highcharts.numberFormat(this.y, 2); + } + }, + plotOptions: { + line: { + shadow: true }, - point: { - events: { - click: function (e) { - hs.htmlExpand(null, { - src: 'chart/home/info/' + this.series.name + '/' + Highcharts.dateFormat("%d/%m/%Y", this.x), - pageOrigin: { - x: e.pageX, - y: e.pageY - }, - objectType: 'ajax', - headingText: '' + this.series.name + '', - width: 250 - } - ) - ; + series: { + cursor: 'pointer', + negativeColor: '#FF0000', + threshold: 0, + lineWidth: 1, + marker: { + radius: 2 + }, + point: { + events: { + click: function (e) { + hs.htmlExpand(null, { + src: 'chart/home/info/' + this.series.name + '/' + Highcharts.dateFormat("%d/%m/%Y", this.x), + pageOrigin: { + x: e.pageX, + y: e.pageY + }, + objectType: 'ajax', + headingText: '' + this.series.name + '', + width: 250 + } + ) + ; + } } } } + }, + credits: { + enabled: false } - }, - credits: { - enabled: false - } - }; - $('#chart').highcharts(options); - }); -} - + }; + $('#chart').highcharts(options); + }); + } }); \ No newline at end of file From 9fa326f6301e6e9debde0279cb1bcad76c4c98b7 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Mon, 10 Nov 2014 21:55:22 +0100 Subject: [PATCH 002/193] First attempt at unifying code for categories and budgets, which are basically the same thing. --- app/controllers/BudgetController.php | 10 +- app/controllers/CategoryController.php | 10 +- app/controllers/GoogleChartController.php | 23 +- app/controllers/GoogleTableController.php | 19 +- app/lib/FireflyIII/Database/Category.php | 26 + app/routes.php | 19 +- app/views/budgets/show.blade.php | 6 +- app/views/categories/show.blade.php | 57 +- public/assets/javascript/firefly/budgets.js | 14 +- .../assets/javascript/firefly/categories.js | 92 +-- public/assets/javascript/firefly/gcharts.js | 534 ++++++++++-------- 11 files changed, 417 insertions(+), 393 deletions(-) diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php index 6156d76c2d..faacb44535 100644 --- a/app/controllers/BudgetController.php +++ b/app/controllers/BudgetController.php @@ -84,7 +84,7 @@ class BudgetController extends BaseController $budgets = $repos->get(); // get the limits for the current month. - $date = \Session::get('start'); + $date = \Session::get('start'); $spent = 0; /** @var \Budget $budget */ foreach ($budgets as $budget) { @@ -114,9 +114,9 @@ class BudgetController extends BaseController } $budgetAmount = $preferences->get('budgetIncomeTotal' . $date->format('FY'), 1000); - $amount = floatval($budgetAmount->data); - $overspent = $spent > $amount; - if($overspent) { + $amount = floatval($budgetAmount->data); + $overspent = $spent > $amount; + if ($overspent) { // overspent on total amount $spentPCT = ceil($amount / $spent * 100); } else { @@ -124,7 +124,7 @@ class BudgetController extends BaseController $spentPCT = ceil($spent / $amount * 100); } - return View::make('budgets.index', compact('budgets','spent','spentPCT','overspent'))->with('budgetAmount', $budgetAmount); + return View::make('budgets.index', compact('budgets', 'spent', 'spentPCT', 'overspent'))->with('budgetAmount', $budgetAmount); } /** diff --git a/app/controllers/CategoryController.php b/app/controllers/CategoryController.php index 55a6e629d3..2a8fe2f472 100644 --- a/app/controllers/CategoryController.php +++ b/app/controllers/CategoryController.php @@ -75,15 +75,7 @@ class CategoryController extends BaseController */ public function show(Category $category) { - $start = \Session::get('start'); - $end = \Session::get('end'); - - - $journals = $this->_category->journalsInRange($category, $start, $end); - - return View::make('categories.show')->with('category', $category)->with('journals', $journals)->with( - 'highlight', Input::get('highlight') - )->with('subTitle', 'Overview for category "' . $category->name . '"'); + return View::make('categories.show', compact('category')); } /** diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index daeedcfddd..cc0aafb7d3 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -200,15 +200,26 @@ class GoogleChartController extends BaseController return Response::json($chart->getData()); } - public function budgetsAndSpending(Budget $budget, $year) { + /** + * @param Component $component + * @param $year + * + * @return \Illuminate\Http\JsonResponse + */ + public function componentsAndSpending(Component $component, $year) { try { $start = new Carbon('01-01-' . $year); } catch (Exception $e) { App::abort(500); } - /** @var \FireflyIII\Database\Budget $bdt */ - $bdt = App::make('FireflyIII\Database\Budget'); + if($component->class == 'Budget') { + /** @var \FireflyIII\Database\Budget $repos */ + $repos = App::make('FireflyIII\Database\Budget'); + } else { + /** @var \FireflyIII\Database\Category $repos */ + $repos = App::make('FireflyIII\Database\Category'); + } /** @var \Grumpydictator\Gchart\GChart $chart */ $chart = App::make('gchart'); @@ -220,12 +231,12 @@ class GoogleChartController extends BaseController $end->endOfYear(); while($start <= $end) { - $spent = $bdt->spentInMonth($budget, $start); - $repetition = $bdt->repetitionOnStartingOnDate($budget, $start); + $spent = $repos->spentInMonth($component, $start); + $repetition = $repos->repetitionOnStartingOnDate($component, $start); if($repetition) { $budgeted = floatval($repetition->amount); } else { - $budgeted = 0; + $budgeted = null; } $chart->addRow(clone $start, $budgeted, $spent); diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php index 80b652fe4b..2d1b091f49 100644 --- a/app/controllers/GoogleTableController.php +++ b/app/controllers/GoogleTableController.php @@ -90,10 +90,10 @@ class GoogleTableController extends BaseController } /** - * @param Budget $budget + * @param Component $component * @param LimitRepetition $repetition */ - public function transactionsByBudget(Budget $budget, LimitRepetition $repetition = null) + public function transactionsByComponent(Component $component, LimitRepetition $repetition = null) { /** @var \Grumpydictator\Gchart\GChart $chart */ $chart = App::make('gchart'); @@ -114,10 +114,13 @@ class GoogleTableController extends BaseController $chart->addColumn('Category', 'string'); if (is_null($repetition)) { - $journals = $budget->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->orderBy('date', 'DESC')->get(); + $journals = $component->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->orderBy('date', 'DESC') + ->get(); } else { - $journals = $budget->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->after($repetition->startdate) - ->before($repetition->enddate)->orderBy('date', 'DESC')->get(); + $journals = $component->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->after( + $repetition->startdate + ) + ->before($repetition->enddate)->orderBy('date', 'DESC')->get(); } /** @var TransactionJournal $transaction */ foreach ($journals as $journal) { @@ -138,10 +141,10 @@ class GoogleTableController extends BaseController } if (isset($journal->budgets[0])) { $budgetURL = route('budgets.show', $journal->budgets[0]->id); - $budget = $journal->budgets[0]->name; + $component = $journal->budgets[0]->name; } else { $budgetURL = ''; - $budget = ''; + $component = ''; } if (isset($journal->categories[0])) { @@ -157,7 +160,7 @@ class GoogleTableController extends BaseController $edit = route('transactions.edit', $journal->id); $delete = route('transactions.delete', $journal->id); $chart->addRow( - $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $budget, $categoryURL, + $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $component, $categoryURL, $category ); } diff --git a/app/lib/FireflyIII/Database/Category.php b/app/lib/FireflyIII/Database/Category.php index 9e9ec6c93b..7599acfe57 100644 --- a/app/lib/FireflyIII/Database/Category.php +++ b/app/lib/FireflyIII/Database/Category.php @@ -148,6 +148,32 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface // TODO: Implement findByWhat() method. } + /** + * @param \Category $budget + * @param Carbon $date + * + * @return null + */ + public function repetitionOnStartingOnDate(\Category $category, Carbon $date) + { + return null; + } + + /** + * @param \Category $category + * @param Carbon $date + * + * @return float + */ + public function spentInMonth(\Category $category, Carbon $date) + { + $end = clone $date; + $date->startOfMonth(); + $end->endOfMonth(); + $sum = floatval($category->transactionjournals()->before($end)->after($date)->lessThan(0)->sum('amount')) * -1; + return $sum; + } + /** * @param Ardent $model * @param array $data diff --git a/app/routes.php b/app/routes.php index 8b804a5d77..d0c193ba21 100644 --- a/app/routes.php +++ b/app/routes.php @@ -50,6 +50,16 @@ Route::bind( } ); +Route::bind( + 'component', function ($value, $route) { + if (Auth::check()) { + return Component:: + where('id', $value)->where('user_id', Auth::user()->id)->first(); + } + return null; + } +); + Route::bind( 'reminder', function ($value, $route) { if (Auth::check()) { @@ -169,13 +179,18 @@ Route::group( Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']); Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']); Route::get('/chart/reports/budgets/{year}', ['uses' => 'GoogleChartController@budgetsReportChart']); - Route::get('/chart/budgets/{budget}/spending/{year}', ['uses' => 'GoogleChartController@budgetsAndSpending']); + + // google chart (categories + budgets) + Route::get('/chart/component/{component}/spending/{year}', ['uses' => 'GoogleChartController@componentsAndSpending']); // google table controller Route::get('/table/account/{account}/transactions', ['uses' => 'GoogleTableController@transactionsByAccount']); Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']); Route::get('/table/categories', ['uses' => 'GoogleTableController@categoryList']); - Route::get('/table/budget/{budget}/{limitrepetition?}/transactions', ['uses' => 'GoogleTableController@transactionsByBudget']); + + // google table (categories + budgets) + + Route::get('/table/component/{component}/{limitrepetition}/transactions', ['uses' => 'GoogleTableController@transactionsByComponent']); Route::get('/chart/home/info/{accountnameA}/{day}/{month}/{year}', ['uses' => 'ChartController@homeAccountInfo', 'as' => 'chart.info']); diff --git a/app/views/budgets/show.blade.php b/app/views/budgets/show.blade.php index 2cdc0f3e14..dbf08c7f45 100644 --- a/app/views/budgets/show.blade.php +++ b/app/views/budgets/show.blade.php @@ -5,10 +5,10 @@
- Some stuff? + Overview
-
+
@@ -73,7 +73,7 @@ @stop @section('scripts') + + + +{{HTML::script('assets/javascript/firefly/gcharts.options.js')}} +{{HTML::script('assets/javascript/firefly/gcharts.js')}} {{HTML::script('assets/javascript/firefly/categories.js')}} + @stop \ No newline at end of file diff --git a/public/assets/javascript/firefly/budgets.js b/public/assets/javascript/firefly/budgets.js index a6de8b79cc..6efcabf7b7 100644 --- a/public/assets/javascript/firefly/budgets.js +++ b/public/assets/javascript/firefly/budgets.js @@ -8,12 +8,15 @@ $(function () { if (typeof(googleTable) == 'function') { - if (typeof budgetID != 'undefined' && typeof repetitionID == 'undefined') { - googleTable('table/budget/' + budgetID + '/0/transactions', 'transactions'); - googleColumnChart('chart/budgets/'+budgetID+'/spending/2014','budgetOverview'); + console.log('A'); + if (typeof componentID != 'undefined' && typeof repetitionID == 'undefined') { + console.log('B'); + googleTable('table/component/' + componentID + '/0/transactions', 'transactions'); + googleColumnChart('chart/component/' + componentID + '/spending/' + year, 'componentOverview'); - } else if (typeof budgetID != 'undefined' && typeof repetitionID != 'undefined') { - googleTable('table/budget/' + budgetID + '/' + repetitionID + '/transactions', 'transactions'); + } else if (typeof componentID != 'undefined' && typeof repetitionID != 'undefined') { + console.log('C'); + googleTable('table/component/' + componentID + '/' + repetitionID + '/transactions', 'transactions'); } } @@ -162,7 +165,6 @@ function updateRanges() { // we gaan er X overheen, var pct = totalAmount / sum * 100; - console.log(pct) var danger = 100 - pct; var err = 100 - danger; $('#progress-bar-default').css('width', 0); diff --git a/public/assets/javascript/firefly/categories.js b/public/assets/javascript/firefly/categories.js index 4b959ed181..502dfd7366 100644 --- a/public/assets/javascript/firefly/categories.js +++ b/public/assets/javascript/firefly/categories.js @@ -2,93 +2,17 @@ $(function () { if (typeof googleTable == 'function') { googleTable('table/categories', 'category-list'); + if (typeof(componentID) != 'undefined') { + googleTable('table/component/' + componentID + '/0/transactions','transactions'); + + if (typeof googleColumnChart == 'function') { + googleColumnChart('chart/component/' + componentID + '/spending/' + year, 'componentOverview'); + } + + } } - if ($('#chart').length == 1) { - /** - * get data from controller for home charts: - */ - $.getJSON('chart/categories/show/' + categoryID).success(function (data) { - var options = { - chart: { - renderTo: 'chart', - type: 'column' - }, - series: [data.series], - title: { - text: data.chart_title - }, - yAxis: { - formatter: function () { - return '$' + Highcharts.numberFormat(this.y, 0); - } - }, - subtitle: { - text: data.subtitle, - useHTML: true - }, - xAxis: { - floor: 0, - type: 'category', - title: { - text: 'Period' - } - }, - tooltip: { - shared: true, - crosshairs: false, - formatter: function () { - var str = '' + Highcharts.dateFormat("%A, %e %B", this.x) + '
'; - for (x in this.points) { - var point = this.points[x]; - var colour = point.point.pointAttr[''].fill; - str += '' + point.series.name + ': \u20AC ' + Highcharts.numberFormat(point.y, 2) + '
'; - } - //console.log(); - return str; - return '' + this.series.name + ' on ' + Highcharts.dateFormat("%e %B", this.x) + ':
\u20AC ' + Highcharts.numberFormat(this.y, 2); - } - }, - plotOptions: { - line: { - shadow: true - }, - series: { - cursor: 'pointer', - negativeColor: '#FF0000', - threshold: 0, - lineWidth: 1, - marker: { - radius: 2 - }, - point: { - events: { - click: function (e) { - hs.htmlExpand(null, { - src: 'chart/home/info/' + this.series.name + '/' + Highcharts.dateFormat("%d/%m/%Y", this.x), - pageOrigin: { - x: e.pageX, - y: e.pageY - }, - objectType: 'ajax', - headingText: '' + this.series.name + '', - width: 250 - } - ) - ; - } - } - } - } - }, - credits: { - enabled: false - } - }; - $('#chart').highcharts(options); - }); - } }); \ No newline at end of file diff --git a/public/assets/javascript/firefly/gcharts.js b/public/assets/javascript/firefly/gcharts.js index b17ab935e1..387b4a6afd 100644 --- a/public/assets/javascript/firefly/gcharts.js +++ b/public/assets/javascript/firefly/gcharts.js @@ -1,263 +1,315 @@ google.load('visualization', '1.1', {'packages': ['corechart', 'bar', 'sankey', 'table']}); function googleLineChart(URL, container) { - $.getJSON(URL).success(function (data) { - /* - Get the data from the JSON - */ - gdata = new google.visualization.DataTable(data); - - /* - Format as money - */ - var money = new google.visualization.NumberFormat({decimalSymbol: ',', groupingSymbol: '.', prefix: '\u20AC '}); - for (i = 1; i < gdata.getNumberOfColumns(); i++) { - money.format(gdata, i); - } - - /* - Create a new google charts object. - */ - var chart = new google.visualization.LineChart(document.getElementById(container)); - - /* - Draw it: - */ - chart.draw(gdata, defaultLineChartOptions); - - }).fail(function () { - $('#' + container).addClass('google-chart-error'); - }); -} - -function googleBarChart(URL, container) { - $.getJSON(URL).success(function (data) { - /* - Get the data from the JSON - */ - gdata = new google.visualization.DataTable(data); - - /* - Format as money - */ - var money = new google.visualization.NumberFormat({decimalSymbol: ',', groupingSymbol: '.', prefix: '\u20AC '}); - for (i = 1; i < gdata.getNumberOfColumns(); i++) { - money.format(gdata, i); - } - - /* - Create a new google charts object. - */ - var chart = new google.charts.Bar(document.getElementById(container)); - - /* - Draw it: - */ - chart.draw(gdata, defaultBarChartOptions); - - }).fail(function () { - $('#' + container).addClass('google-chart-error'); - }); -} - -function googleColumnChart(URL, container) { - $.getJSON(URL).success(function (data) { - /* - Get the data from the JSON - */ - gdata = new google.visualization.DataTable(data); - - /* - Format as money - */ - var money = new google.visualization.NumberFormat({decimalSymbol: ',', groupingSymbol: '.', prefix: '\u20AC '}); - for (i = 1; i < gdata.getNumberOfColumns(); i++) { - money.format(gdata, i); - } - - /* - Create a new google charts object. - */ - var chart = new google.charts.Bar(document.getElementById(container)); - /* - Draw it: - */ - chart.draw(gdata, defaultColumnChartOptions); - - }).fail(function () { - $('#' + container).addClass('google-chart-error'); - }); -} - -function googleStackedColumnChart(URL, container) { - $.getJSON(URL).success(function (data) { - /* - Get the data from the JSON - */ - gdata = new google.visualization.DataTable(data); - - /* - Format as money - */ - var money = new google.visualization.NumberFormat({decimalSymbol: ',', groupingSymbol: '.', prefix: '\u20AC '}); - for (i = 1; i < gdata.getNumberOfColumns(); i++) { - money.format(gdata, i); - } - - /* - Create a new google charts object. - */ - var chart = new google.visualization.ColumnChart(document.getElementById(container)); - /* - Draw it: - */ - chart.draw(gdata, defaultStackedColumnChartOptions); - - }).fail(function () { - $('#' + container).addClass('google-chart-error'); - }); -} - -function googlePieChart(URL, container) { - $.getJSON(URL).success(function (data) { - /* - Get the data from the JSON - */ - gdata = new google.visualization.DataTable(data); - - /* - Format as money - */ - var money = new google.visualization.NumberFormat({decimalSymbol: ',', groupingSymbol: '.', prefix: '\u20AC '}); - for (i = 1; i < gdata.getNumberOfColumns(); i++) { - money.format(gdata, i); - } - - /* - Create a new google charts object. - */ - var chart = new google.visualization.PieChart(document.getElementById(container)); - - /* - Draw it: - */ - chart.draw(gdata, defaultPieChartOptions); - - }).fail(function () { - $('#' + container).addClass('google-chart-error'); - }); -} - -function googleSankeyChart(URL, container) { - $.getJSON(URL).success(function (data) { - /* - Get the data from the JSON - */ - gdata = new google.visualization.DataTable(data); - - /* - Format as money - */ - - console.log(gdata.getNumberOfRows()) - if (gdata.getNumberOfRows() < 1) { - console.log('remove'); - $('#' + container).parent().parent().remove(); - return; - } else if (gdata.getNumberOfRows() < 6) { - defaultSankeyChartOptions.height = 100 - } else { - defaultSankeyChartOptions.height = 400 - } - - - /* - Create a new google charts object. - */ - var chart = new google.visualization.Sankey(document.getElementById(container)); - - /* - Draw it: - */ - chart.draw(gdata, defaultSankeyChartOptions); - - }).fail(function () { - $('#' + container).addClass('google-chart-error'); - }); -} - -function googleTable(URL, container) { - $.getJSON(URL).success(function (data) { - /* - Get the data from the JSON - */ - var gdata = new google.visualization.DataTable(data); - - /* - Create a new google charts object. - */ - var chart = new google.visualization.Table(document.getElementById(container)); - - /* - Do something with formatters: - */ - var x = gdata.getNumberOfColumns(); - var columnsToHide = new Array; - var URLFormatter = new google.visualization.PatternFormat('{1}'); - - var EditButtonFormatter = new google.visualization.PatternFormat('
'); - - var money = new google.visualization.NumberFormat({decimalSymbol: ',', groupingSymbol: '.', prefix: '\u20AC '}); - - - for (var i = 0; i < x; i++) { - var label = gdata.getColumnLabel(i); - console.log('Column ' + i + ':' + label); + if ($('#' + container).length == 1) { + $.getJSON(URL).success(function (data) { /* - Format a string using the previous column as URL. + Get the data from the JSON */ - if (label == 'Description' || label == 'From' || label == 'Name' || label == 'To' || label == 'Budget' || label == 'Category') { - URLFormatter.format(gdata, [i - 1, i], i); - columnsToHide.push(i - 1); - } - if (label == 'ID') { - EditButtonFormatter.format(gdata, [i + 1, i + 2], i); - columnsToHide.push(i + 1, i + 2); - } - - /* - Format with buttons: - */ - + gdata = new google.visualization.DataTable(data); /* Format as money */ - if (label == 'Amount' || label == 'Balance') { + var money = new google.visualization.NumberFormat({ + decimalSymbol: ',', + groupingSymbol: '.', + prefix: '\u20AC ' + }); + for (i = 1; i < gdata.getNumberOfColumns(); i++) { money.format(gdata, i); } - } + /* + Create a new google charts object. + */ + var chart = new google.visualization.LineChart(document.getElementById(container)); + + /* + Draw it: + */ + chart.draw(gdata, defaultLineChartOptions); + + }).fail(function () { + $('#' + container).addClass('google-chart-error'); + }); + } else { + console.log('No container found called "' + container + '"'); + } +} + +function googleBarChart(URL, container) { + if ($('#' + container).length == 1) { + $.getJSON(URL).success(function (data) { + /* + Get the data from the JSON + */ + gdata = new google.visualization.DataTable(data); + + /* + Format as money + */ + var money = new google.visualization.NumberFormat({ + decimalSymbol: ',', + groupingSymbol: '.', + prefix: '\u20AC ' + }); + for (i = 1; i < gdata.getNumberOfColumns(); i++) { + money.format(gdata, i); + } + + /* + Create a new google charts object. + */ + var chart = new google.charts.Bar(document.getElementById(container)); + + /* + Draw it: + */ + chart.draw(gdata, defaultBarChartOptions); + + }).fail(function () { + $('#' + container).addClass('google-chart-error'); + }); + } else { + console.log('No container found called "' + container + '"'); + } +} + +function googleColumnChart(URL, container) { + if ($('#' + container).length == 1) { + $.getJSON(URL).success(function (data) { + /* + Get the data from the JSON + */ + gdata = new google.visualization.DataTable(data); + + /* + Format as money + */ + var money = new google.visualization.NumberFormat({ + decimalSymbol: ',', + groupingSymbol: '.', + prefix: '\u20AC ' + }); + for (i = 1; i < gdata.getNumberOfColumns(); i++) { + money.format(gdata, i); + } + + /* + Create a new google charts object. + */ + var chart = new google.charts.Bar(document.getElementById(container)); + /* + Draw it: + */ + chart.draw(gdata, defaultColumnChartOptions); + + }).fail(function () { + $('#' + container).addClass('google-chart-error'); + }); + } else { + console.log('No container found called "' + container + '"'); + } +} + +function googleStackedColumnChart(URL, container) { + if ($('#' + container).length == 1) { + $.getJSON(URL).success(function (data) { + /* + Get the data from the JSON + */ + gdata = new google.visualization.DataTable(data); + + /* + Format as money + */ + var money = new google.visualization.NumberFormat({ + decimalSymbol: ',', + groupingSymbol: '.', + prefix: '\u20AC ' + }); + for (i = 1; i < gdata.getNumberOfColumns(); i++) { + money.format(gdata, i); + } + + /* + Create a new google charts object. + */ + var chart = new google.visualization.ColumnChart(document.getElementById(container)); + /* + Draw it: + */ + chart.draw(gdata, defaultStackedColumnChartOptions); + + }).fail(function () { + $('#' + container).addClass('google-chart-error'); + }); + } else { + console.log('No container found called "' + container + '"'); + } +} + +function googlePieChart(URL, container) { + if ($('#' + container).length == 1) { + $.getJSON(URL).success(function (data) { + /* + Get the data from the JSON + */ + gdata = new google.visualization.DataTable(data); + + /* + Format as money + */ + var money = new google.visualization.NumberFormat({ + decimalSymbol: ',', + groupingSymbol: '.', + prefix: '\u20AC ' + }); + for (i = 1; i < gdata.getNumberOfColumns(); i++) { + money.format(gdata, i); + } + + /* + Create a new google charts object. + */ + var chart = new google.visualization.PieChart(document.getElementById(container)); + + /* + Draw it: + */ + chart.draw(gdata, defaultPieChartOptions); + + }).fail(function () { + $('#' + container).addClass('google-chart-error'); + }); + } else { + console.log('No container found called "' + container + '"'); + } +} + +function googleSankeyChart(URL, container) { + if ($('#' + container).length == 1) { + $.getJSON(URL).success(function (data) { + /* + Get the data from the JSON + */ + gdata = new google.visualization.DataTable(data); + + /* + Format as money + */ + + console.log(gdata.getNumberOfRows()) + if (gdata.getNumberOfRows() < 1) { + console.log('remove'); + $('#' + container).parent().parent().remove(); + return; + } else if (gdata.getNumberOfRows() < 6) { + defaultSankeyChartOptions.height = 100 + } else { + defaultSankeyChartOptions.height = 400 + } - //var formatter = new google.visualization.PatternFormat('{1}'); + /* + Create a new google charts object. + */ + var chart = new google.visualization.Sankey(document.getElementById(container)); - //formatter.format(gdata, [5, 6], 6); - //formatter.format(gdata, [7, 8], 8); + /* + Draw it: + */ + chart.draw(gdata, defaultSankeyChartOptions); + + }).fail(function () { + $('#' + container).addClass('google-chart-error'); + }); + } else { + console.log('No container found called "' + container + '"'); + } +} + +function googleTable(URL, container) { + if ($('#' + container).length == 1) { + $.getJSON(URL).success(function (data) { + /* + Get the data from the JSON + */ + var gdata = new google.visualization.DataTable(data); + + /* + Create a new google charts object. + */ + var chart = new google.visualization.Table(document.getElementById(container)); + + /* + Do something with formatters: + */ + var x = gdata.getNumberOfColumns(); + var columnsToHide = new Array; + var URLFormatter = new google.visualization.PatternFormat('{1}'); + + var EditButtonFormatter = new google.visualization.PatternFormat('
'); + + var money = new google.visualization.NumberFormat({ + decimalSymbol: ',', + groupingSymbol: '.', + prefix: '\u20AC ' + }); - var view = new google.visualization.DataView(gdata); - // hide certain columns: + for (var i = 0; i < x; i++) { + var label = gdata.getColumnLabel(i); + console.log('Column ' + i + ':' + label); + /* + Format a string using the previous column as URL. + */ + if (label == 'Description' || label == 'From' || label == 'Name' || label == 'To' || label == 'Budget' || label == 'Category') { + URLFormatter.format(gdata, [i - 1, i], i); + columnsToHide.push(i - 1); + } + if (label == 'ID') { + EditButtonFormatter.format(gdata, [i + 1, i + 2], i); + columnsToHide.push(i + 1, i + 2); + } - view.hideColumns(columnsToHide); + /* + Format with buttons: + */ - /* - Draw it: - */ - chart.draw(view, defaultTableOptions); + /* + Format as money + */ + if (label == 'Amount' || label == 'Balance') { + money.format(gdata, i); + } - }).fail(function () { - $('#' + container).addClass('google-chart-error'); - }); + } + + + //var formatter = new google.visualization.PatternFormat('{1}'); + + //formatter.format(gdata, [5, 6], 6); + //formatter.format(gdata, [7, 8], 8); + + + var view = new google.visualization.DataView(gdata); + // hide certain columns: + + view.hideColumns(columnsToHide); + + + /* + Draw it: + */ + chart.draw(view, defaultTableOptions); + + }).fail(function () { + $('#' + container).addClass('google-chart-error'); + }); + } else { + console.log('No container found called "' + container + '"'); + } } \ No newline at end of file From e9afd55e9d3c73bd21a4c19a0c9825d3f1773099 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Mon, 10 Nov 2014 22:36:25 +0100 Subject: [PATCH 003/193] Updated the default user seeder. --- app/database/seeds/DefaultUserSeeder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/database/seeds/DefaultUserSeeder.php b/app/database/seeds/DefaultUserSeeder.php index dc7a102cbf..935d507811 100644 --- a/app/database/seeds/DefaultUserSeeder.php +++ b/app/database/seeds/DefaultUserSeeder.php @@ -11,7 +11,7 @@ class DefaultUserSeeder extends Seeder User::create( [ - 'email' => 's@nder.be', + 'email' => 'thegrumpydictator@gmail.com', 'password' => 'sander', 'reset' => null, 'remember_token' => null, From 9d4cba16206d26a4ae8dfd640b1ccfd359170989 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Tue, 11 Nov 2014 07:20:52 +0100 Subject: [PATCH 004/193] Fixed some initial startup bugs when working with Homestead. --- app/controllers/GoogleChartController.php | 34 +++++++++++++---------- bootstrap/start.php | 15 +++++----- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index cc0aafb7d3..0d5f79e7d3 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -18,11 +18,15 @@ class GoogleChartController extends BaseController /** @var \FireflyIII\Shared\Preferences\Preferences $preferences */ $preferences = App::make('FireflyIII\Shared\Preferences\Preferences'); - $pref = $preferences->get('frontpageAccounts'); + $pref = $preferences->get('frontpageAccounts', []); /** @var \FireflyIII\Database\Account $acct */ - $acct = App::make('FireflyIII\Database\Account'); - $accounts = $acct->getByIds($pref->data); + $acct = App::make('FireflyIII\Database\Account'); + if (count($pref->data) > 0) { + $accounts = $acct->getByIds($pref->data); + } else { + $accounts = $acct->getAssetAccounts(); + } /* @@ -169,7 +173,7 @@ class GoogleChartController extends BaseController foreach ($budgets as $budget) { $chart->addColumn($budget->name, 'number'); } - $chart->addColumn('No budget','number'); + $chart->addColumn('No budget', 'number'); /* * Loop budgets this year. @@ -179,7 +183,7 @@ class GoogleChartController extends BaseController while ($start <= $end) { $row = [clone $start]; - foreach($budgets as $budget) { + foreach ($budgets as $budget) { $row[] = $bdt->spentInMonth($budget, $start); } @@ -188,7 +192,7 @@ class GoogleChartController extends BaseController */ $endOfMonth = clone $start; $endOfMonth->endOfMonth(); - $set = $bdt->transactionsWithoutBudgetInDateRange($start, $endOfMonth); + $set = $bdt->transactionsWithoutBudgetInDateRange($start, $endOfMonth); $row[] = floatval($set->sum('amount')) * -1; $chart->addRowArray($row); @@ -202,23 +206,24 @@ class GoogleChartController extends BaseController /** * @param Component $component - * @param $year + * @param $year * * @return \Illuminate\Http\JsonResponse */ - public function componentsAndSpending(Component $component, $year) { + public function componentsAndSpending(Component $component, $year) + { try { $start = new Carbon('01-01-' . $year); } catch (Exception $e) { App::abort(500); } - if($component->class == 'Budget') { + if ($component->class == 'Budget') { /** @var \FireflyIII\Database\Budget $repos */ - $repos = App::make('FireflyIII\Database\Budget'); + $repos = App::make('FireflyIII\Database\Budget'); } else { /** @var \FireflyIII\Database\Category $repos */ - $repos = App::make('FireflyIII\Database\Category'); + $repos = App::make('FireflyIII\Database\Category'); } /** @var \Grumpydictator\Gchart\GChart $chart */ @@ -229,11 +234,11 @@ class GoogleChartController extends BaseController $end = clone $start; $end->endOfYear(); - while($start <= $end) { + while ($start <= $end) { - $spent = $repos->spentInMonth($component, $start); + $spent = $repos->spentInMonth($component, $start); $repetition = $repos->repetitionOnStartingOnDate($component, $start); - if($repetition) { + if ($repetition) { $budgeted = floatval($repetition->amount); } else { $budgeted = null; @@ -245,7 +250,6 @@ class GoogleChartController extends BaseController } - $chart->generate(); return Response::json($chart->getData()); diff --git a/bootstrap/start.php b/bootstrap/start.php index 1e76ce97dd..ba5d06556b 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -4,8 +4,8 @@ if (!function_exists('mf')) { function mf($n, $coloured = true) { - $n = floatval($n); - $n = round($n, 2); + $n = floatval($n); + $n = round($n, 2); $string = number_format($n, 2, ',', '.'); if ($coloured === true && $n === 0.0) { @@ -37,11 +37,12 @@ $app = new Illuminate\Foundation\Application; | */ -$env = $app->detectEnvironment(array( - - 'local' => array('homestead', 'SMJD*'), - - )); +$env = $app->detectEnvironment( + [ + 'local' => ['SMJD*'], + 'homestead' => ['homestead'] + ] +); /* From 86a586f866d732c58f87da1ed41ce03556ec8191 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Tue, 11 Nov 2014 07:26:16 +0100 Subject: [PATCH 005/193] Ignore homestead configuration. --- app/config/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/config/.gitignore b/app/config/.gitignore index 3415788027..72c3919328 100644 --- a/app/config/.gitignore +++ b/app/config/.gitignore @@ -1,3 +1,4 @@ local/ laptop/ -vagrant/ \ No newline at end of file +vagrant/ +homestead/ \ No newline at end of file From d231cd9f610703a2c585e2031864626b6ab637c6 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Tue, 11 Nov 2014 07:35:00 +0100 Subject: [PATCH 006/193] Added the homestead configuration because it's not really secret. --- app/config/.gitignore | 3 +- app/config/homestead/app.php | 14 +++++++++ app/config/homestead/database.php | 47 +++++++++++++++++++++++++++++++ app/config/homestead/mail.php | 13 +++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 app/config/homestead/app.php create mode 100644 app/config/homestead/database.php create mode 100644 app/config/homestead/mail.php diff --git a/app/config/.gitignore b/app/config/.gitignore index 72c3919328..3415788027 100644 --- a/app/config/.gitignore +++ b/app/config/.gitignore @@ -1,4 +1,3 @@ local/ laptop/ -vagrant/ -homestead/ \ No newline at end of file +vagrant/ \ No newline at end of file diff --git a/app/config/homestead/app.php b/app/config/homestead/app.php new file mode 100644 index 0000000000..16c4d11e1b --- /dev/null +++ b/app/config/homestead/app.php @@ -0,0 +1,14 @@ + true, +]; \ No newline at end of file diff --git a/app/config/homestead/database.php b/app/config/homestead/database.php new file mode 100644 index 0000000000..de7f714bdf --- /dev/null +++ b/app/config/homestead/database.php @@ -0,0 +1,47 @@ + [ + + 'mysql' => [ + 'driver' => 'mysql', + 'host' => 'localhost', + 'database' => 'homestead', + 'username' => 'homestead', + 'password' => 'secret', + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'host' => 'localhost', + 'database' => 'homestead', + 'username' => 'homestead', + 'password' => 'secret', + 'charset' => 'utf8', + 'prefix' => '', + 'schema' => 'public', + ], + + ], + +]; \ No newline at end of file diff --git a/app/config/homestead/mail.php b/app/config/homestead/mail.php new file mode 100644 index 0000000000..79a8bf2536 --- /dev/null +++ b/app/config/homestead/mail.php @@ -0,0 +1,13 @@ + 'smtp', + 'host' => 'smtp.gmail.com', + 'port' => 587, + 'from' => ['address' => '@gmail.com', 'name' => 'Firefly III'], + 'encryption' => 'tls', + 'username' => '@gmail.com', + 'password' => '', + 'sendmail' => '/usr/sbin/sendmail -bs', + 'pretend' => false, +]; From f08fcc36fb594c74487bc6127590ec7a9e15759b Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Tue, 11 Nov 2014 18:16:59 +0100 Subject: [PATCH 007/193] Half-way through with some cleaning up. --- app/config/app.php | 4 +- app/controllers/AccountController.php | 64 -- app/controllers/ChartController.php | 603 ------------------ app/controllers/HomeController.php | 87 +-- app/controllers/JsonController.php | 186 ------ app/controllers/LimitController.php | 162 ----- app/controllers/MigrateController.php | 52 -- app/filters.php | 9 +- app/lib/Firefly/Helper/Toolkit/Toolkit.php | 3 - .../Database/TransactionJournal.php | 28 + app/lib/FireflyIII/FF3ServiceProvider.php | 28 + app/lib/FireflyIII/Shared/Toolkit/Filter.php | 296 +++++++++ app/routes.php | 123 +--- app/views/partials/menu.blade.php | 133 +--- 14 files changed, 418 insertions(+), 1360 deletions(-) delete mode 100644 app/controllers/ChartController.php delete mode 100644 app/controllers/JsonController.php delete mode 100644 app/controllers/LimitController.php delete mode 100644 app/controllers/MigrateController.php create mode 100644 app/lib/FireflyIII/FF3ServiceProvider.php create mode 100644 app/lib/FireflyIII/Shared/Toolkit/Filter.php diff --git a/app/config/app.php b/app/config/app.php index b997979dd7..114350c2b5 100644 --- a/app/config/app.php +++ b/app/config/app.php @@ -39,9 +39,7 @@ return [ 'Illuminate\Workbench\WorkbenchServiceProvider', 'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider', 'Barryvdh\Debugbar\ServiceProvider', - 'Firefly\Storage\StorageServiceProvider', - 'Firefly\Helper\HelperServiceProvider', - 'Firefly\Validation\ValidationServiceProvider', + 'FireflyIII\FF3ServiceProvider', 'DaveJamesMiller\Breadcrumbs\ServiceProvider', 'Grumpydictator\Gchart\GchartServiceProvider', ], diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 08ddca55e8..c875e0be64 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -50,70 +50,6 @@ class AccountController extends BaseController } - /** - * @param string $what - * - * @return \Illuminate\Http\JsonResponse - * @throws FireflyException - */ - public function json($what = 'default') - { - /** @var \FireflyIII\Database\Account $acct */ - $acct = App::make('FireflyIII\Database\Account'); - - /** @var \FireflyIII\Shared\Json\Json $json */ - $json = App::make('FireflyIII\Shared\Json\Json'); - - $parameters = $json->dataTableParameters(); - - switch ($what) { - default: - throw new FireflyException('Cannot handle account type "' . e($what) . '".'); - break; - case 'asset': - $accounts = $acct->getAssetAccounts($parameters); - $count = $acct->countAssetAccounts(); - break; - case 'expense': - $accounts = $acct->getExpenseAccounts($parameters); - $count = $acct->countExpenseAccounts(); - break; - case 'revenue': - $accounts = $acct->getRevenueAccounts($parameters); - $count = $acct->countRevenueAccounts(); - break; - } - - /* - * Output the set compatible with data tables: - */ - $return = [ - 'draw' => intval(Input::get('draw')), - 'recordsTotal' => $count, - 'recordsFiltered' => $accounts->count(), - 'data' => [], - ]; - - /* - * Loop the accounts: - */ - /** @var \Account $account */ - foreach ($accounts as $account) { - $entry = [ - 'name' => ['name' => $account->name, 'url' => route('accounts.show', $account->id)], - 'balance' => $account->balance(), - 'id' => [ - 'edit' => route('accounts.edit', $account->id), - 'delete' => route('accounts.delete', $account->id), - ] - ]; - $return['data'][] = $entry; - } - - - return Response::jsoN($return); - } - /** * @return \Illuminate\View\View */ diff --git a/app/controllers/ChartController.php b/app/controllers/ChartController.php deleted file mode 100644 index 9b104ca379..0000000000 --- a/app/controllers/ChartController.php +++ /dev/null @@ -1,603 +0,0 @@ -_chart = $chart; - $this->_accounts = $accounts; - } - - /** - * This method takes a budget, all limits and all their repetitions and displays three numbers per repetition: - * the amount of money in the repetition (represented as "an envelope"), the amount spent and the spent percentage. - * - * @param Budget $budget - * - * @return \Illuminate\Http\JsonResponse - */ - public function budgetDefault(\Budget $budget) - { - $expense = []; - $left = []; - $envelope = []; - // get all limit repetitions for this budget. - /** @var \Limit $limit */ - foreach ($budget->limits as $limit) { - /** @var \LimitRepetition $rep */ - foreach ($limit->limitrepetitions as $rep) { - // get the amount of money spent in this period on this budget. - $spentInRep = $rep->amount - $rep->leftInRepetition(); - $pct = round((floatval($spentInRep) / floatval($limit->amount)) * 100, 2); - $name = $rep->periodShow(); - $envelope[] = [$name, floatval($limit->amount)]; - $expense[] = [$name, floatval($spentInRep)]; - $left[] = [$name, $pct]; - } - } - - $return = [ - 'chart_title' => 'Overview for budget ' . $budget->name, - 'subtitle' => 'All envelopes', - 'series' => [ - [ - 'type' => 'line', - 'yAxis' => 1, - 'name' => 'Amount in envelope', - 'data' => $envelope - ], - [ - 'type' => 'column', - 'name' => 'Expenses in envelope', - 'data' => $expense - ], - [ - 'type' => 'line', - 'yAxis' => 1, - 'name' => 'Spent percentage for envelope', - 'data' => $left - ] - - - ] - ]; - - return Response::json($return); - } - - /** - * This method takes a single limit repetition (so a single "envelope") and displays the amount of money spent - * per day and subsequently how much money is left. - * - * @param LimitRepetition $rep - * - * @return \Illuminate\Http\JsonResponse - */ - public function budgetLimit(\LimitRepetition $rep) - { - $budget = $rep->limit->budget; - $current = clone $rep->startdate; - $expense = []; - $leftInLimit = []; - $currentLeftInLimit = floatval($rep->limit->amount); - while ($current <= $rep->enddate) { - $spent = $this->_chart->spentOnDay($budget, $current); - $spent = floatval($spent) == 0 ? null : floatval($spent); - $entry = [$current->timestamp * 1000, $spent]; - $expense[] = $entry; - $currentLeftInLimit = $currentLeftInLimit - $spent; - $leftInLimit[] = [$current->timestamp * 1000, $currentLeftInLimit]; - $current->addDay(); - } - - $return = [ - 'chart_title' => 'Overview for budget ' . $budget->name, - 'subtitle' => - 'Between ' . $rep->startdate->format('M jS, Y') . ' and ' . $rep->enddate->format('M jS, Y'), - 'series' => [ - [ - 'type' => 'column', - 'name' => 'Expenses per day', - 'yAxis' => 1, - 'data' => $expense - ], - [ - 'type' => 'line', - 'name' => 'Left in envelope', - 'data' => $leftInLimit - ] - - ] - ]; - - return Response::json($return); - } - - /** - * This method takes a budget and gets all transactions in it which haven't got an envelope (limit). - * - * Usually this means that very old and unorganized or very NEW transactions get displayed; there was never an - * envelope or it hasn't been created (yet). - * - * - * @param Budget $budget - * - * @return \Illuminate\Http\JsonResponse - */ - public function budgetNoLimits(\Budget $budget) - { - /* - * Firefly can go about this two ways. Either it finds all transactions which definitely are IN an envelope - * and exclude them or it searches for transactions outside of the range of any of the envelopes there are. - * - * Since either is kinda shitty Firefly uses the first one because it's easier to build. - */ - $inRepetitions = $this->_chart->allJournalsInBudgetEnvelope($budget); - - /* - * With this set of id's, Firefly can search for all journals NOT in that set. - * BUT they have to be in the budget (duh). - */ - $set = $this->_chart->journalsNotInSet($budget, $inRepetitions); - /* - * Next step: get all transactions for those journals. - */ - $transactions = $this->_chart->transactionsByJournals($set); - - - /* - * this set builds the chart: - */ - $expense = []; - - foreach ($transactions as $t) { - $date = new Carbon($t->date); - $expense[] = [$date->timestamp * 1000, floatval($t->aggregate)]; - } - $return = [ - 'chart_title' => 'Overview for ' . $budget->name, - 'subtitle' => 'Not organized by an envelope', - 'series' => [ - [ - 'type' => 'column', - 'name' => 'Expenses per day', - 'data' => $expense - ] - - ] - ]; - return Response::json($return); - } - - /** - * This method gets all transactions within a budget within the period set by the current session - * start and end date. It also includes any envelopes which might exist within this period. - * - * @param Budget $budget - * - * @return \Illuminate\Http\JsonResponse - */ - public function budgetSession(\Budget $budget) - { - $series = []; - $end = clone Session::get('end'); - $start = clone Session::get('start'); - - - /* - * Expenses per day in the session's period. That's easy. - */ - $expense = []; - $current = clone Session::get('start'); - while ($current <= $end) { - $spent = $this->_chart->spentOnDay($budget, $current); - $spent = floatval($spent) == 0 ? null : floatval($spent); - $expense[] = [$current->timestamp * 1000, $spent]; - $current->addDay(); - } - - $series[] = [ - 'type' => 'column', - 'name' => 'Expenses per day', - 'data' => $expense - ]; - unset($expense, $spent, $current); - - /* - * Find all limit repetitions (for this budget) between start and end. This is - * quite a complex query. - */ - $reps = $this->_chart->limitsInRange($budget, $start, $end); - - /* - * For each limitrepetition Firefly creates a serie that contains the amount left in - * the limitrepetition for its entire date-range. Entries are only actually included when they - * fall into the charts date range. - * - * So example: the user has a session date from Jan 15 to Jan 30. The limitrepetition - * starts at 1 Jan until 1 Feb. - * - * Firefly loops from 1 Jan to 1 Feb but only includes Jan 15 / Jan 30. - * But it does keep count of the amount outside of these dates because otherwise the line might be wrong. - */ - /** @var \LimitRepetition $repetition */ - foreach ($reps as $repetition) { - $limitAmount = $repetition->limit->amount; - - // create a serie for the repetition. - $currentSerie = [ - 'type' => 'spline', - 'id' => 'rep-' . $repetition->id, - 'yAxis' => 1, - 'name' => 'Envelope #' . $repetition->id . ' in ' . $repetition->periodShow(), - 'data' => [] - ]; - $current = clone $repetition->startdate; - while ($current <= $repetition->enddate) { - if ($current >= $start && $current <= $end) { - // spent on limit: - $spentSoFar = $this->_chart->spentOnLimitRepetitionBetweenDates( - $repetition, $repetition->startdate, $current - ); - $leftInLimit = floatval($limitAmount) - floatval($spentSoFar); - - $currentSerie['data'][] = [$current->timestamp * 1000, $leftInLimit]; - } - $current->addDay(); - } - - // do something here. - $series[] = $currentSerie; - } - - $return = [ - 'chart_title' => 'Overview for budget ' . $budget->name, - 'subtitle' => - 'Between ' . Session::get('start')->format('M jS, Y') . ' and ' . Session::get('end')->format( - 'M jS, Y' - ), - 'series' => $series - ]; - - return Response::json($return); - - } - - /** - * @param Category $category - * - * @return \Illuminate\Http\JsonResponse - */ - public function categoryShowChart(Category $category) - { - $start = Session::get('start'); - $end = Session::get('end'); - $range = Session::get('range'); - - $serie = $this->_chart->categoryShowChart($category, $range, $start, $end); - $data = [ - 'chart_title' => $category->name, - 'subtitle' => 'View more', - 'series' => $serie - ]; - - return Response::json($data); - - - } - - /** - * @param Account $account - * - * @return mixed - */ - public function homeAccount(Account $account = null) - { - // get preferences and accounts (if necessary): - $start = Session::get('start'); - $end = Session::get('end'); - - if (is_null($account)) { - // get, depending on preferences: - /** @var \Firefly\Helper\Preferences\PreferencesHelperInterface $prefs */ - $prefs = \App::make('Firefly\Helper\Preferences\PreferencesHelperInterface'); - $pref = $prefs->get('frontpageAccounts', []); - - /** @var \Firefly\Storage\Account\AccountRepositoryInterface $acct */ - $acct = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); - $accounts = $acct->getByIds($pref->data); - } else { - $accounts = [$account]; - } - // loop and get array data. - - $url = count($accounts) == 1 && is_array($accounts) - ? 'View more' - : - 'View more'; - $data = [ - 'chart_title' => count($accounts) == 1 ? $accounts[0]->name : 'All accounts', - 'subtitle' => $url, - 'series' => [] - ]; - - foreach ($accounts as $account) { - $data['series'][] = $this->_chart->account($account, $start, $end); - } - - return Response::json($data); - } - - /** - * @param $name - * @param $day - * @param $month - * @param $year - * - * @return $this - */ - public function homeAccountInfo($name, $day, $month, $year) - { - $account = $this->_accounts->findByName($name); - - $date = Carbon::createFromDate($year, $month, $day); - $result = $this->_chart->accountDailySummary($account, $date); - - return View::make('charts.info')->with('rows', $result['rows'])->with('sum', $result['sum'])->with( - 'account', $account - ); - } - - /** - * @return \Illuminate\Http\JsonResponse - */ - public function homeBudgets() - { - $start = Session::get('start'); - $end = Session::get('end'); - $data = [ - 'labels' => [], - 'series' => [ - [ - 'name' => 'Limit', - 'data' => [] - ], - [ - 'name' => 'Spent', - 'data' => [] - ], - ] - ]; - - // Get all budgets. - $budgets = \Auth::user()->budgets()->orderBy('name', 'ASC')->get(); - $budgetIds = []; - /** @var \Budget $budget */ - foreach ($budgets as $budget) { - $budgetIds[] = $budget->id; - - // Does the budget have a limit starting on $start? - $rep = \LimitRepetition:: - leftJoin('limits', 'limit_repetitions.limit_id', '=', 'limits.id')->leftJoin( - 'components', 'limits.component_id', '=', 'components.id' - )->where('limit_repetitions.startdate', $start->format('Y-m-d'))->where( - 'components.id', $budget->id - )->first(['limit_repetitions.*']); - - if (is_null($rep)) { - $limit = 0.0; - $id = null; - $parameter = 'useSession=true'; - } else { - $limit = floatval($rep->amount); - $id = $rep->id; - $parameter = ''; - } - - // Date range to check for expenses made? - if (is_null($rep)) { - // use the session start and end for our search query - $expenseStart = Session::get('start'); - $expenseEnd = Session::get('end'); - - } else { - // use the limit's start and end for our search query - $expenseStart = $rep->startdate; - $expenseEnd = $rep->enddate; - } - // How much have we spent on this budget? - $expenses = floatval($budget->transactionjournals()->before($expenseEnd)->after($expenseStart)->lessThan(0)->sum('amount')) * -1; - - // Append to chart: - if ($limit > 0 || $expenses > 0) { - $data['labels'][] = $budget->name; - $data['series'][0]['data'][] = [ - 'y' => $limit, - 'url' => route('budgets.show', [$budget->id, $id]) . '?' . $parameter - ]; - $data['series'][1]['data'][] = [ - 'y' => $expenses, - 'url' => route('budgets.show', [$budget->id, $id]) . '?' . $parameter - ]; - } - } - // Add expenses that have no budget: - $set = \Auth::user()->transactionjournals()->whereNotIn( - 'transaction_journals.id', function ($query) use ($start, $end) { - $query->select('transaction_journals.id')->from('transaction_journals') - ->leftJoin( - 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', - 'transaction_journals.id' - ) - ->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) - ->where('components.class', 'Budget'); - } - )->before($end)->after($start)->lessThan(0)->transactionTypes(['Withdrawal'])->sum('amount'); - - // This can be debugged by using get(['transaction_journals.*','transactions.amount']); - $data['labels'][] = 'No budget'; - $data['series'][0]['data'][] = [ - 'y' => 0, - 'url' => route('budgets.nobudget', 'session') - ]; - $data['series'][1]['data'][] = [ - 'y' => floatval($set) * -1, - 'url' => route('budgets.nobudget', 'session') - ]; - - return Response::json($data); - - } - - /** - * @return \Illuminate\Http\JsonResponse - */ - public function homeCategories() - { - $start = Session::get('start'); - $end = Session::get('end'); - - return Response::json($this->_chart->categories($start, $end)); - - - } - - /** - * This method checks all recurring transactions, calculates the current "moment" and returns - * a list of yet to be paid (and paid) recurring transactions. This list can be used to show a beautiful chart - * to the end user who will love it and cherish it. - * - * @throws FireflyException - */ - public function homeRecurring() - { - /** @var \Firefly\Helper\Toolkit\ToolkitInterface $toolkit */ - $toolkit = App::make('Firefly\Helper\Toolkit\ToolkitInterface'); - - /* - * Set of paid transaction journals. - * Set of unpaid recurring transactions. - */ - $paid = []; - $unpaid = []; - - /* - * Loop the recurring transactions. - */ - - /** @var \RecurringTransaction $recurring */ - foreach (\Auth::user()->recurringtransactions()->get() as $recurring) { - /* - * Start another loop starting at the $date. - */ - $start = clone $recurring->date; - $end = Carbon::now(); - - /* - * The jump we make depends on the $repeat_freq - */ - $current = clone $start; - - while ($current <= $end) { - /* - * Get end of period for $current: - */ - $currentEnd = clone $current; - $toolkit->endOfPeriod($currentEnd, $recurring->repeat_freq); - - /* - * In the current session range? - */ - if (\Session::get('end') >= $current and $currentEnd >= \Session::get('start')) { - /* - * Lets see if we've already spent money on this recurring transaction (it hath recurred). - */ - /** @var TransactionJournal $set */ - $transaction = \Auth::user()->transactionjournals()->where('recurring_transaction_id', $recurring->id)->after($current)->before($currentEnd)->first(); - - if(is_null($transaction)) { - $unpaid[] = $recurring; - } else { - $paid[] = $transaction; - } - } - - /* - * Add some time for the next loop! - */ - $toolkit->addPeriod($current, $recurring->repeat_freq, intval($recurring->skip)); - - } - - } - /* - * Get some colors going. - */ - $unPaidColours = $toolkit->colorRange('AA4643', 'FFFFFF', count($unpaid) == 0 ? 1 : count($unpaid)); - $paidColours = $toolkit->colorRange('4572A7', 'FFFFFF', count($paid) == 0 ? 1 : count($paid)); - - /* - * The chart serie: - */ - $serie = [ - 'type' => 'pie', - 'name' => 'Amount', - 'data' => [] - ]; - - /* - * Loop paid and unpaid to make two haves for a pie chart. - */ - /** @var TransactionJournal $entry */ - foreach ($paid as $index => $entry) { - $transactions = $entry->transactions()->get(); - $amount = max(floatval($transactions[0]->amount), floatval($transactions[1]->amount)); - $serie['data'][] = [ - 'name' => 'Already paid "'.$entry->description.'"', - 'y' => $amount, - 'url' => route('transactions.show',$entry->id), - 'objType' => 'paid', - 'color' => $paidColours[$index] - ]; - } - - - /** @var RecurringTransaction $entry */ - foreach ($unpaid as $index => $entry) { - $amount = (floatval($entry->amount_max) + floatval($entry->amount_min)) / 2; - $serie['data'][] = [ - 'name' => 'Still due: '.$entry->name, - 'y' => $amount, - 'url' => route('recurring.show',$entry->id), - 'objType' => 'unpaid', - 'color' => $unPaidColours[$index] - ]; - } - - return Response::json([$serie]); - - } -} \ No newline at end of file diff --git a/app/controllers/HomeController.php b/app/controllers/HomeController.php index ffd33b86cd..814436a793 100644 --- a/app/controllers/HomeController.php +++ b/app/controllers/HomeController.php @@ -1,7 +1,5 @@ _accounts = $accounts; $this->_preferences = $preferences; - $this->_journal = $journal; } public function jobDev() @@ -85,12 +78,19 @@ class HomeController extends BaseController */ public function index() { - Event::fire('limits.check'); - Event::fire('piggybanks.check'); - Event::fire('recurring.check'); +// Event::fire('limits.check'); +// Event::fire('piggybanks.check'); +// Event::fire('recurring.check'); // count, maybe Firefly needs some introducing text to show: - $count = $this->_accounts->count(); + /** @var \FireflyIII\Database\Account $acct */ + $acct = App::make('FireflyIII\Database\Account'); + + /** @var \FireflyIII\Database\TransactionJournal $jrnls */ + $jrnls = App::make('FireflyIII\Database\TransactionJournal'); + + $count = $acct->countAssetAccounts(); + $start = Session::get('start'); $end = Session::get('end'); @@ -98,14 +98,14 @@ class HomeController extends BaseController // get the preference for the home accounts to show: $frontpage = $this->_preferences->get('frontpageAccounts', []); if ($frontpage->data == []) { - $accounts = $this->_accounts->getActiveDefault(); + $accounts = $acct->getAssetAccounts(); } else { - $accounts = $this->_accounts->getByIds($frontpage->data); + $accounts = $acct->getByIds($frontpage->data); } $transactions = []; foreach ($accounts as $account) { - $set = $this->_journal->getByAccountInDateRange($account, 10, $start, $end); + $set = $jrnls->getInDateRangeAccount($account, 10, $start, $end); if (count($set) > 0) { $transactions[] = [$set, $account]; } @@ -115,59 +115,4 @@ class HomeController extends BaseController return View::make('index')->with('count', $count)->with('transactions', $transactions)->with('title', 'Firefly') ->with('subTitle', 'What\'s playing?')->with('mainTitleIcon', 'fa-fire'); } - - public function cleanup() - { - /** @var \FireflyIII\Database\TransactionJournal $jrnls */ - $jrnls = App::make('FireflyIII\Database\TransactionJournal'); - - /** @var \FireflyIII\Database\Account $acct */ - $acct = \App::make('FireflyIII\Database\Account'); - - /** @var \FireflyIII\Database\AccountType $acctType */ - $acctType = \App::make('FireflyIII\Database\AccountType'); - $rightAcctType = $acctType->findByWhat('revenue'); - - $all = $jrnls->get(); - - /** @var \TransactionJournal $entry */ - foreach ($all as $entry) { - $wrongFromType = false; - $wrongToType = false; - $transactions = $entry->transactions; - if (count($transactions) == 2) { - switch ($entry->transactionType->type) { - case 'Deposit': - /** @var \Transaction $transaction */ - foreach ($transactions as $transaction) { - if (floatval($transaction->amount) < 0) { - $accountType = $transaction->account->accountType; - if ($accountType->type == 'Beneficiary account') { - // should be a Revenue account! - $name = $transaction->account->name; - /** @var \Account $account */ - $account = \Auth::user()->accounts()->where('name', $name)->where('account_type_id', $rightAcctType->id)->first(); - if (!$account) { - $new = [ - 'name' => $name, - 'what' => 'revenue' - ]; - $account = $acct->store($new); - } - $transaction->account()->associate($account); - $transaction->save(); - } - - echo 'Paid by: ' . $transaction->account->name . ' (' . $transaction->account->accountType->type . ')
'; - } - } - break; - } - - - } - } - - - } } \ No newline at end of file diff --git a/app/controllers/JsonController.php b/app/controllers/JsonController.php deleted file mode 100644 index 671e771b95..0000000000 --- a/app/controllers/JsonController.php +++ /dev/null @@ -1,186 +0,0 @@ -helper = $helper; - - - } - - /** - * Returns a list of categories. - * - * @return \Illuminate\Http\JsonResponse - */ - public function categories() - { - /** @var \Firefly\Storage\Category\EloquentCategoryRepository $categories */ - $categories = App::make('Firefly\Storage\Category\CategoryRepositoryInterface'); - $list = $categories->get(); - $return = []; - foreach ($list as $entry) { - $return[] = $entry->name; - } - - return Response::json($return); - - - } - - /** - * Returns a JSON list of all beneficiaries. - * - * @return \Illuminate\Http\JsonResponse - */ - public function expenseAccounts() - { - /** @var \Firefly\Storage\Account\EloquentAccountRepository $accounts */ - $accounts = App::make('Firefly\Storage\Account\AccountRepositoryInterface'); - $list = $accounts->getOfTypes(['Expense account', 'Beneficiary account']); - $return = []; - foreach ($list as $entry) { - $return[] = $entry->name; - } - - return Response::json($return); - - } - - /** - * Returns a list of transactions, expenses only, using the given parameters. - * - * @return \Illuminate\Http\JsonResponse - */ - public function expenses() - { - - /* - * Gets most parameters from the Input::all() array: - */ - $parameters = $this->helper->dataTableParameters(); - - /* - * Add some more parameters to fine tune the query: - */ - $parameters['transactionTypes'] = ['Withdrawal']; - $parameters['amount'] = 'negative'; - - /* - * Get the query: - */ - $query = $this->helper->journalQuery($parameters); - - /* - * Build result set: - */ - $resultSet = $this->helper->journalDataset($parameters, $query); - - - /* - * Build return data: - */ - return Response::json($resultSet); - } - - /** - * - */ - public function recurringjournals(RecurringTransaction $recurringTransaction) - { - $parameters = $this->helper->dataTableParameters(); - $parameters['transactionTypes'] = ['Withdrawal']; - $parameters['amount'] = 'negative'; - - $query = $this->helper->journalQuery($parameters); - - $query->where('recurring_transaction_id', $recurringTransaction->id); - $resultSet = $this->helper->journalDataset($parameters, $query); - - - /* - * Build return data: - */ - return Response::json($resultSet); - } - - public function recurring() - { - $parameters = $this->helper->dataTableParameters(); - $query = $this->helper->recurringTransactionsQuery($parameters); - $resultSet = $this->helper->recurringTransactionsDataset($parameters, $query); - return Response::json($resultSet); - } - - /** - * @return \Illuminate\Http\JsonResponse|string - */ - public function revenue() - { - $parameters = $this->helper->dataTableParameters(); - $parameters['transactionTypes'] = ['Deposit']; - $parameters['amount'] = 'positive'; - - $query = $this->helper->journalQuery($parameters); - $resultSet = $this->helper->journalDataset($parameters, $query); - - - /* - * Build return data: - */ - return Response::json($resultSet); - } - - /** - * Returns a JSON list of all revenue accounts. - * - * @return \Illuminate\Http\JsonResponse - */ - public function revenueAccounts() - { - /** @var \Firefly\Storage\Account\EloquentAccountRepository $accounts */ - $accounts = App::make('Firefly\Storage\Account\AccountRepositoryInterface'); - $list = $accounts->getOfTypes(['Revenue account']); - $return = []; - foreach ($list as $entry) { - $return[] = $entry->name; - } - - return Response::json($return); - - } - - /** - * Returns a list of all transfers. - * - * @return \Illuminate\Http\JsonResponse - */ - public function transfers() - { - $parameters = $this->helper->dataTableParameters(); - $parameters['transactionTypes'] = ['Transfer']; - $parameters['amount'] = 'positive'; - - $query = $this->helper->journalQuery($parameters); - $resultSet = $this->helper->journalDataset($parameters, $query); - - - /* - * Build return data: - */ - return Response::json($resultSet); - } -} \ No newline at end of file diff --git a/app/controllers/LimitController.php b/app/controllers/LimitController.php deleted file mode 100644 index f76345a5cf..0000000000 --- a/app/controllers/LimitController.php +++ /dev/null @@ -1,162 +0,0 @@ -_budgets = $budgets; - $this->_limits = $limits; - - View::share('title','Envelopes'); - View::share('mainTitleIcon', 'fa-tasks'); - } - - /** - * @param Budget $budget - * - * @return $this - */ - public function create(\Budget $budget = null) - { - $periods = \Config::get('firefly.periods_to_text'); - $prefilled = [ - 'startdate' => \Input::get('startdate') ? : date('Y-m-d'), - 'repeat_freq' => \Input::get('repeat_freq') ? : 'monthly', - 'budget_id' => $budget ? $budget->id : null - ]; - - /** @var \Firefly\Helper\Toolkit\Toolkit $toolkit */ - $toolkit = App::make('Firefly\Helper\Toolkit\Toolkit'); - $budgets = $toolkit->makeSelectList($this->_budgets->get()); - - return View::make('limits.create')->with('budgets', $budgets)->with( - 'periods', $periods - )->with('prefilled', $prefilled)->with('subTitle','New envelope'); - } - - /** - * @param Limit $limit - * - * @return $this - */ - public function delete(\Limit $limit) - { - return View::make('limits.delete')->with('limit', $limit)->with('subTitle','Delete envelope'); - } - - /** - * @param Limit $limit - * - * @return \Illuminate\Http\RedirectResponse - */ - public function destroy(\Limit $limit) - { - Event::fire('limits.destroy', [$limit]); // before - $success = $this->_limits->destroy($limit); - - if ($success) { - Session::flash('success', 'The envelope was deleted.'); - } else { - Session::flash('error', 'Could not delete the envelope. Check the logs to be sure.'); - } - if (Input::get('from') == 'date') { - return Redirect::route('budgets.index'); - } else { - return Redirect::route('budgets.index.budget'); - } - } - - /** - * @param Limit $limit - * - * @return $this - */ - public function edit(Limit $limit) - { - /** @var \Firefly\Helper\Toolkit\Toolkit $toolkit */ - $toolkit = App::make('Firefly\Helper\Toolkit\Toolkit'); - - $budgets = $toolkit->makeSelectList($this->_budgets->get()); - $periods = \Config::get('firefly.periods_to_text'); - - return View::make('limits.edit')->with('limit', $limit)->with('budgets', $budgets)->with( - 'periods', $periods - )->with('subTitle','Edit envelope'); - } - - /** - * @param Budget $budget - * - * @return $this|\Illuminate\Http\RedirectResponse - */ - public function store(Budget $budget = null) - { - - // find a limit with these properties, as Firefly might already have one: - $limit = $this->_limits->store(Input::all()); - if ($limit->validate()) { - Session::flash('success', 'Envelope created!'); - Event::fire('limits.store', [$limit]); - if (Input::get('from') == 'date') { - return Redirect::route('budgets.index'); - } else { - return Redirect::route('budgets.index.budget'); - } - } else { - Session::flash('error', 'Could not save new envelope.'); - $budgetId = $budget ? $budget->id : null; - $parameters = [$budgetId, 'from' => Input::get('from')]; - - return Redirect::route('budgets.limits.create', $parameters)->withInput() - ->withErrors($limit->errors()); - } - } - - /** - * @param Limit $limit - * - * @return $this|\Illuminate\Http\RedirectResponse - */ - public function update(\Limit $limit) - { - - - $limit = $this->_limits->update($limit, Input::all()); - - if ($limit->validate()) { - Event::fire('limits.update', [$limit]); - Session::flash('success', 'Limit saved!'); - if (Input::get('from') == 'date') { - return Redirect::route('budgets.index'); - } else { - return Redirect::route('budgets.index.budget'); - } - - - } else { - Session::flash('error', 'Could not save new limit: ' . $limit->errors()->first()); - - return Redirect::route('budgets.limits.edit', [$limit->id, 'from' => Input::get('from')])->withInput() - ->withErrors($limit->errors()); - } - - } - - -} \ No newline at end of file diff --git a/app/controllers/MigrateController.php b/app/controllers/MigrateController.php deleted file mode 100644 index a9bd16c200..0000000000 --- a/app/controllers/MigrateController.php +++ /dev/null @@ -1,52 +0,0 @@ -with('index', 'Migration')->with('title','Migrate')-> - with('subTitle','From Firefly II to Firefly III'); - } - - /** - * - */ - public function upload() - { - if (Input::hasFile('file') && Input::file('file')->isValid()) { - $path = storage_path(); - $fileName = 'firefly-iii-import-' . date('Y-m-d-H-i') . '.json'; - $fullName = $path . DIRECTORY_SEPARATOR . $fileName; - if (Input::file('file')->move($path, $fileName)) { - // so now Firefly pushes something in a queue and does something with it! Yay! - \Log::debug('Pushed a job to start the import.'); - Queue::push('Firefly\Queue\Import@start', ['file' => $fullName, 'user' => \Auth::user()->id]); - if (Config::get('queue.default') == 'sync') { - Session::flash('success', 'Your data has been imported!'); - } else { - Session::flash( - 'success', - 'The import job has been queued. Please be patient. Data will appear slowly. Please be patient.' - ); - } - - return Redirect::route('index'); - } - Session::flash('error', 'Could not save file to storage.'); - return Redirect::route('migrate.index'); - - } else { - Session::flash('error', 'Please upload a file.'); - return Redirect::route('migrate.index'); - } - - } - -} \ No newline at end of file diff --git a/app/filters.php b/app/filters.php index 5b4cf13296..835ecba055 100644 --- a/app/filters.php +++ b/app/filters.php @@ -6,11 +6,10 @@ App::before( function ($request) { if (Auth::check()) { - /** @var \Firefly\Helper\Toolkit\ToolkitInterface $toolkit */ - $toolkit = App::make('Firefly\Helper\Toolkit\ToolkitInterface'); - $toolkit->getDateRange(); - $toolkit->checkImportJobs(); - Event::fire('recurring.verify'); + /** @var \FireflyIII\Shared\Toolkit\Filter $toolkit */ + $filter = App::make('FireflyIII\Shared\Toolkit\Filter'); + $filter->setSessionDateRange(); + //Event::fire('recurring.verify'); } } diff --git a/app/lib/Firefly/Helper/Toolkit/Toolkit.php b/app/lib/Firefly/Helper/Toolkit/Toolkit.php index 51941a2508..2e9dbeb725 100644 --- a/app/lib/Firefly/Helper/Toolkit/Toolkit.php +++ b/app/lib/Firefly/Helper/Toolkit/Toolkit.php @@ -107,9 +107,6 @@ class Toolkit implements ToolkitInterface } } - /** - * @return mixed - */ protected function _getRange() { if (!is_null(\Session::get('range'))) { diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 3355f458a8..8f26645ade 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -85,6 +85,34 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData return $this->getuser()->transactionjournals()->withRelevantData()->before($end)->after($start)->get(); } + /** + * @param \Account $account + * @param int $count + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function getInDateRangeAccount(\Account $account, $count = 20, Carbon $start, Carbon $end) + { + + $accountID = $account->id; + $query = $this->_user + ->transactionjournals() + ->with(['transactions', 'transactioncurrency', 'transactiontype']) + ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') + ->where('accounts.id', $accountID) + ->where('date', '>=', $start->format('Y-m-d')) + ->where('date', '<=', $end->format('Y-m-d')) + ->orderBy('transaction_journals.date', 'DESC') + ->orderBy('transaction_journals.id', 'DESC') + ->take($count) + ->get(['transaction_journals.*']); + + return $query; + } + /** * @return TransactionJournal */ diff --git a/app/lib/FireflyIII/FF3ServiceProvider.php b/app/lib/FireflyIII/FF3ServiceProvider.php new file mode 100644 index 0000000000..2f8206f937 --- /dev/null +++ b/app/lib/FireflyIII/FF3ServiceProvider.php @@ -0,0 +1,28 @@ +app->bind('Interface', 'Class'); + + // preferences: + $this->app->bind('FireflyIII\Shared\Preferences\PreferencesInterface', 'FireflyIII\Shared\Preferences\Preferences'); + + } + +} \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Toolkit/Filter.php b/app/lib/FireflyIII/Shared/Toolkit/Filter.php new file mode 100644 index 0000000000..a927d64408 --- /dev/null +++ b/app/lib/FireflyIII/Shared/Toolkit/Filter.php @@ -0,0 +1,296 @@ +get('viewRange', '1M'); + + // default range: + $range = $viewRange->data; + \Session::put('range', $range); + } + return $range; + + } + + /** + * Save Session::get('start') and Session::get('end') for other methods to use. + */ + public function setSessionDateRange() + { + /* + * Get the current range. + */ + $range = $this->setSessionRangeValue(); + $start = \Session::has('start') ? \Session::get('start') : new Carbon; + + /* + * Force start date to at the start of the $range. + * Ie. the start of the week, month, year. This also to protect against nefarious users + * who change their session data (I just wanted to use the word "nefarious"). + */ + $start = $this->updateStartDate($range, $start); + + /* + * Force end date to at the END of the $range. Always based on $start. + * Ie. the END of the week, month, year. + */ + $end = $this->updateEndDate($range, $start); + #\Log::debug('After update, session end is : ' . $end->format('Y-m-d')); + + /* + * get the name of the month, depending on the range. Purely for astetics + */ + $period = $this->periodName($range, $start); + + /* + * Get the date for the previous and next period. + * Ie. next week, next month, etc. + */ + $prev = $this->previous($range, clone $start); + $next = $this->next($range, clone $start); + + /* + * Save everything in the session: + */ + \Session::put('start', $start); + \Session::put('end', $end); + \Session::put('range', $range); + \Session::put('period', $period); + \Session::put('prev', $this->periodName($range, $prev)); + \Session::put('next', $this->periodName($range, $next)); + return null; + + } + + /** + * @param $range + * @param Carbon $start + * + * @return Carbon + * @throws FireflyException + */ + protected function updateStartDate($range, Carbon $start) + { + switch ($range) { + default: + throw new FireflyException('updateStartDate cannot handle $range ' . $range); + break; + case '1D': + $start->startOfDay(); + break; + case '1W': + $start->startOfWeek(); + break; + case '1M': + $start->startOfMonth(); + break; + case '3M': + $start->firstOfQuarter(); + break; + case '6M': + if (intval($start->format('m')) >= 7) { + $start->startOfYear()->addMonths(6); + } else { + $start->startOfYear(); + } + break; + case '1Y': + $start->startOfYear(); + break; + } + + return $start; + + } + + /** + * @param $range + * @param Carbon $start + * + * @return Carbon + * @throws FireflyException + */ + protected function updateEndDate($range, Carbon $start) + { + $end = clone $start; + switch ($range) { + default: + throw new FireflyException('updateEndDate cannot handle $range ' . $range); + break; + case '1D': + $end->endOfDay(); + break; + case '1W': + $end->endOfWeek(); + break; + case '1M': + $end->endOfMonth(); + break; + case '3M': + $end->lastOfQuarter(); + break; + case '6M': + if (intval($start->format('m')) >= 7) { + $end->endOfYear(); + } else { + $end->startOfYear()->addMonths(6); + } + break; + case '1Y': + $end->endOfYear(); + break; + + } + + return $end; + } + + /** + * @param $range + * @param Carbon $date + * + * @return string + * @throws FireflyException + */ + protected function periodName($range, Carbon $date) + { + switch ($range) { + default: + throw new FireflyException('No _periodName() for range "' . $range . '"'); + break; + case '1D': + return $date->format('jS F Y'); + break; + case '1W': + return 'week ' . $date->format('W, Y'); + break; + case '1M': + return $date->format('F Y'); + break; + case '3M': + $month = intval($date->format('m')); + return 'Q' . ceil(($month / 12) * 4) . ' ' . $date->format('Y'); + break; + case '6M': + $month = intval($date->format('m')); + $half = ceil(($month / 12) * 2); + $halfName = $half == 1 ? 'first' : 'second'; + return $halfName . ' half of ' . $date->format('d-m-Y'); + break; + case '1Y': + return $date->format('Y'); + break; + + + } + } + + /** + * @param $range + * @param Carbon $date + * + * @return Carbon + * @throws FireflyException + */ + protected function previous($range, Carbon $date) + { + switch ($range) { + default: + throw new FireflyException('Cannot do _previous() on ' . $range); + break; + case '1D': + $date->startOfDay()->subDay(); + break; + case '1W': + $date->startOfWeek()->subWeek(); + break; + case '1M': + $date->startOfMonth()->subMonth(); + break; + case '3M': + $date->firstOfQuarter()->subMonths(3)->firstOfQuarter(); + break; + case '6M': + $month = intval($date->format('m')); + if ($month <= 6) { + $date->startOfYear()->subMonths(6); + } else { + $date->startOfYear(); + } + break; + case '1Y': + $date->startOfYear()->subYear(); + break; + + } + return $date; + } + + /** + * @param $range + * @param Carbon $date + * + * @return Carbon + * @throws FireflyException + */ + protected function next($range, Carbon $date) + { + switch ($range) { + case '1D': + $date->endOfDay()->addDay(); + break; + case '1W': + $date->endOfWeek()->addDay()->startOfWeek(); + break; + case '1M': + $date->endOfMonth()->addDay()->startOfMonth(); + break; + case '3M': + $date->lastOfQuarter()->addDay(); + break; + case '6M': + if (intval($date->format('m')) >= 7) { + $date->startOfYear()->addYear(); + } else { + $date->startOfYear()->addMonths(6); + } + break; + case '1Y': + $date->startOfYear()->addYear(); + break; + default: + throw new FireflyException('Cannot do _next() on ' . $range); + break; + } + return $date; + } +} \ No newline at end of file diff --git a/app/routes.php b/app/routes.php index d0c193ba21..b846454ab1 100644 --- a/app/routes.php +++ b/app/routes.php @@ -1,8 +1,5 @@ leftJoin('components', 'components.id', '=', 'limits.component_id')->where('components.class', 'Budget')->where( - 'components.user_id', Auth::user()->id - )->first(['limits.*']); - } - return null; - } -); - Route::bind( 'limitrepetition', function ($value, $route) { if (Auth::check()) { @@ -126,22 +111,18 @@ Route::bind( ); -// a development route: -Route::get('/dev', ['uses' => 'HomeController@jobDev']); - // protected routes: Route::group( ['before' => 'auth'], function () { - // some date routes: + // some date routes used for (well duh) date-based navigation. Route::get('/prev', ['uses' => 'HomeController@sessionPrev', 'as' => 'sessionPrev']); Route::get('/next', ['uses' => 'HomeController@sessionNext', 'as' => 'sessionNext']); Route::get('/jump/{range}', ['uses' => 'HomeController@rangeJump', 'as' => 'rangeJump']); Route::get('/cleanup', ['uses' => 'HomeController@cleanup', 'as' => 'cleanup']); // account controller: - Route::get('/accounts/json/{what}', ['uses' => 'AccountController@json', 'as' => 'accounts.json'])->where('what', 'revenue|asset|expense'); Route::get('/accounts/{what}', ['uses' => 'AccountController@index', 'as' => 'accounts.index'])->where('what', 'revenue|asset|expense'); Route::get('/accounts/create/{what}', ['uses' => 'AccountController@create', 'as' => 'accounts.create'])->where('what', 'revenue|asset|expense'); Route::get('/accounts/edit/{account}', ['uses' => 'AccountController@edit', 'as' => 'accounts.edit']); @@ -150,23 +131,18 @@ Route::group( // budget controller: Route::get('/budgets', ['uses' => 'BudgetController@index', 'as' => 'budgets.index']); - Route::get('/budgets/income', ['uses' => 'BudgetController@updateIncome', 'as' => 'budgets.income']); - Route::get('/budgets/show/{budget}/{limitrepetition?}', ['uses' => 'BudgetController@show', 'as' => 'budgets.show']); - - #Route::get('/budgets/date', ['uses' => 'BudgetController@indexByDate', 'as' => 'budgets.index.date']); - #Route::get('/budgets/budget', ['uses' => 'BudgetController@indexByBudget', 'as' => 'budgets.index.budget']); + Route::get('/budgets/income', ['uses' => 'BudgetController@updateIncome', 'as' => 'budgets.income']); # extra. Route::get('/budgets/create', ['uses' => 'BudgetController@create', 'as' => 'budgets.create']); - #Route::get('/budgets/nobudget/{period}', ['uses' => 'BudgetController@nobudget', 'as' => 'budgets.nobudget']); - Route::get('/budgets/edit/{budget}', ['uses' => 'BudgetController@edit', 'as' => 'budgets.edit']); Route::get('/budgets/delete/{budget}', ['uses' => 'BudgetController@delete', 'as' => 'budgets.delete']); + Route::get('/budgets/show/{budget}/{limitrepetition?}', ['uses' => 'BudgetController@show', 'as' => 'budgets.show']); // category controller: Route::get('/categories', ['uses' => 'CategoryController@index', 'as' => 'categories.index']); Route::get('/categories/create', ['uses' => 'CategoryController@create', 'as' => 'categories.create']); - Route::get('/categories/show/{category}', ['uses' => 'CategoryController@show', 'as' => 'categories.show']); Route::get('/categories/edit/{category}', ['uses' => 'CategoryController@edit', 'as' => 'categories.edit']); Route::get('/categories/delete/{category}', ['uses' => 'CategoryController@delete', 'as' => 'categories.delete']); + Route::get('/categories/show/{category}', ['uses' => 'CategoryController@show', 'as' => 'categories.show']); // google chart controller Route::get('/chart/home/account', ['uses' => 'GoogleChartController@allAccountsBalanceChart']); @@ -180,7 +156,7 @@ Route::group( Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']); Route::get('/chart/reports/budgets/{year}', ['uses' => 'GoogleChartController@budgetsReportChart']); - // google chart (categories + budgets) + // google chart for components (categories + budgets combined) Route::get('/chart/component/{component}/spending/{year}', ['uses' => 'GoogleChartController@componentsAndSpending']); // google table controller @@ -188,57 +164,23 @@ Route::group( Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']); Route::get('/table/categories', ['uses' => 'GoogleTableController@categoryList']); - // google table (categories + budgets) - + // google table for components (categories + budgets) Route::get('/table/component/{component}/{limitrepetition}/transactions', ['uses' => 'GoogleTableController@transactionsByComponent']); - Route::get('/chart/home/info/{accountnameA}/{day}/{month}/{year}', ['uses' => 'ChartController@homeAccountInfo', 'as' => 'chart.info']); - Route::get('/chart/categories/show/{category}', ['uses' => 'ChartController@categoryShowChart', 'as' => 'chart.showcategory']); - - // (new charts for budgets) - Route::get('/chart/budget/{budget}/default', ['uses' => 'ChartController@budgetDefault', 'as' => 'chart.budget.default']); - Route::get('chart/budget/{budget}/no_envelope', ['uses' => 'ChartController@budgetNoLimits', 'as' => 'chart.budget.nolimit']); - Route::get('chart/budget/{budget}/session', ['uses' => 'ChartController@budgetSession', 'as' => 'chart.budget.session']); - Route::get('chart/budget/envelope/{limitrepetition}', ['uses' => 'ChartController@budgetLimit', 'as' => 'chart.budget.limit']); - // home controller Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']); - Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); - - // JSON controller: - Route::get('/json/expense-accounts', ['uses' => 'JsonController@expenseAccounts', 'as' => 'json.expense-accounts']); - Route::get('/json/revenue-accounts', ['uses' => 'JsonController@revenueAccounts', 'as' => 'json.revenue-accounts']); - Route::get('/json/categories', ['uses' => 'JsonController@categories', 'as' => 'json.categories']); - Route::get('/json/expenses', ['uses' => 'JsonController@expenses', 'as' => 'json.expenses']); - Route::get('/json/revenue', ['uses' => 'JsonController@revenue', 'as' => 'json.revenue']); - Route::get('/json/transfers', ['uses' => 'JsonController@transfers', 'as' => 'json.transfers']); - Route::get('/json/recurring', ['uses' => 'JsonController@recurring', 'as' => 'json.recurring']); - Route::get('/json/recurringjournals/{recurring}', ['uses' => 'JsonController@recurringjournals', 'as' => 'json.recurringjournals']); - - // limit controller: - Route::get('/budgets/limits/create/{budget?}', ['uses' => 'LimitController@create', 'as' => 'budgets.limits.create']); - Route::get('/budgets/limits/delete/{limit}', ['uses' => 'LimitController@delete', 'as' => 'budgets.limits.delete']); - Route::get('/budgets/limits/edit/{limit}', ['uses' => 'LimitController@edit', 'as' => 'budgets.limits.edit']); - - Route::get('/migrate', ['uses' => 'MigrateController@index', 'as' => 'migrate.index']); + Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); # even though nothing is cached. // piggy bank controller Route::get('/piggybanks', ['uses' => 'PiggybankController@index', 'as' => 'piggybanks.index']); - Route::get('/piggybanks/add/{piggybank}', ['uses' => 'PiggybankController@add']); - Route::get('/piggybanks/remove/{piggybank}', ['uses' => 'PiggybankController@remove']); - Route::get('/piggybanks/edit/{piggybank}', ['uses' => 'PiggybankController@edit', 'as' => 'piggybanks.edit']); + Route::get('/piggybanks/add/{piggybank}', ['uses' => 'PiggybankController@add']); # add money + Route::get('/piggybanks/remove/{piggybank}', ['uses' => 'PiggybankController@remove']); #remove money + Route::get('/piggybanks/create', ['uses' => 'PiggybankController@create', 'as' => 'piggybanks.create']); + Route::get('/piggybanks/edit/{piggybank}', ['uses' => 'PiggybankController@edit', 'as' => 'piggybanks.edit']); Route::get('/piggybanks/delete/{piggybank}', ['uses' => 'PiggybankController@delete', 'as' => 'piggybanks.delete']); - - -// Route::get('/repeated',['uses' => 'PiggybankController@repeated','as' => 'piggybanks.index.repeated']); -// Route::get('/piggybanks/create/repeated', ['uses' => 'PiggybankController@createRepeated','as' => 'piggybanks.create.repeated']); -// Route::get('/piggybanks/addMoney/{piggybank}', ['uses' => 'PiggybankController@addMoney','as' => 'piggybanks.amount.add']); -// Route::get('/piggybanks/removeMoney/{piggybank}', ['uses' => 'PiggybankController@removeMoney','as' => 'piggybanks.amount.remove']); -// Route::get('/piggybanks/show/{piggybank}', ['uses' => 'PiggybankController@show','as' => 'piggybanks.show']); -// Route::get('/piggybanks/delete/{piggybank}', ['uses' => 'PiggybankController@delete','as' => 'piggybanks.delete']); -// Route::post('/piggybanks/updateAmount/{piggybank}',['uses' => 'PiggybankController@updateAmount','as' => 'piggybanks.updateAmount']); + Route::get('/piggybanks/show/{piggybank}', ['uses' => 'PiggybankController@show', 'as' => 'piggybanks.show']); // preferences controller Route::get('/preferences', ['uses' => 'PreferencesController@index', 'as' => 'preferences']); @@ -249,11 +191,11 @@ Route::group( // recurring transactions controller Route::get('/recurring', ['uses' => 'RecurringController@index', 'as' => 'recurring.index']); - Route::get('/recurring/show/{recurring}', ['uses' => 'RecurringController@show', 'as' => 'recurring.show']); - Route::get('/recurring/rescan/{recurring}', ['uses' => 'RecurringController@rescan', 'as' => 'recurring.rescan']); + Route::get('/recurring/rescan/{recurring}', ['uses' => 'RecurringController@rescan', 'as' => 'recurring.rescan']); # rescan for matching. Route::get('/recurring/create', ['uses' => 'RecurringController@create', 'as' => 'recurring.create']); Route::get('/recurring/edit/{recurring}', ['uses' => 'RecurringController@edit', 'as' => 'recurring.edit']); Route::get('/recurring/delete/{recurring}', ['uses' => 'RecurringController@delete', 'as' => 'recurring.delete']); + Route::get('/recurring/show/{recurring}', ['uses' => 'RecurringController@show', 'as' => 'recurring.show']); // report controller: Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']); @@ -263,25 +205,20 @@ Route::group( Route::get('/search', ['uses' => 'SearchController@index', 'as' => 'search']); // transaction controller: - Route::get('/transactions/create/{what}', ['uses' => 'TransactionController@create', 'as' => 'transactions.create'])->where( - ['what' => 'withdrawal|deposit|transfer'] + Route::get('/transactions/{what}', ['uses' => 'TransactionController@index', 'as' => 'transactions.index'])->where( + ['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers'] + ); + Route::get('/transactions/create/{what}', ['uses' => 'TransactionController@create', 'as' => 'transactions.create'])->where( + ['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers'] ); - Route::get('/transaction/show/{tj}', ['uses' => 'TransactionController@show', 'as' => 'transactions.show']); Route::get('/transaction/edit/{tj}', ['uses' => 'TransactionController@edit', 'as' => 'transactions.edit']); Route::get('/transaction/delete/{tj}', ['uses' => 'TransactionController@delete', 'as' => 'transactions.delete']); - Route::get('/transactions/index', ['uses' => 'TransactionController@index', 'as' => 'transactions.index']); - Route::get('/transactions/expenses', ['uses' => 'TransactionController@expenses', 'as' => 'transactions.expenses']); - Route::get('/transactions/revenue', ['uses' => 'TransactionController@revenue', 'as' => 'transactions.revenue']); - Route::get('/transactions/transfers', ['uses' => 'TransactionController@transfers', 'as' => 'transactions.transfers']); - - Route::get('/transactions/expenses', ['uses' => 'TransactionController@expenses', 'as' => 'transactions.index.withdrawal']); - Route::get('/transactions/revenue', ['uses' => 'TransactionController@revenue', 'as' => 'transactions.index.deposit']); - Route::get('/transactions/transfers', ['uses' => 'TransactionController@transfers', 'as' => 'transactions.index.transfer']); + Route::get('/transaction/show/{tj}', ['uses' => 'TransactionController@show', 'as' => 'transactions.show']); // user controller Route::get('/logout', ['uses' => 'UserController@logout', 'as' => 'logout']); - Route::post('budgets/amount/{budget}', ['uses' => 'BudgetController@amount']); + //Route::post('budgets/amount/{budget}', ['uses' => 'BudgetController@amount']); } @@ -297,8 +234,8 @@ Route::group( // budget controller: Route::post('/budgets/income', ['uses' => 'BudgetController@postUpdateIncome', 'as' => 'budgets.postIncome']); - Route::post('/budgets/update/{budget}', ['uses' => 'BudgetController@update', 'as' => 'budgets.update']); Route::post('/budgets/store', ['uses' => 'BudgetController@store', 'as' => 'budgets.store']); + Route::post('/budgets/update/{budget}', ['uses' => 'BudgetController@update', 'as' => 'budgets.update']); Route::post('/budgets/destroy/{budget}', ['uses' => 'BudgetController@destroy', 'as' => 'budgets.destroy']); // category controller @@ -306,22 +243,12 @@ Route::group( Route::post('/categories/update/{category}', ['uses' => 'CategoryController@update', 'as' => 'categories.update']); Route::post('/categories/destroy/{category}', ['uses' => 'CategoryController@destroy', 'as' => 'categories.destroy']); - // limit controller: - Route::post('/budgets/limits/store/{budget?}', ['uses' => 'LimitController@store', 'as' => 'budgets.limits.store']); - Route::post('/budgets/limits/destroy/{limit}', ['uses' => 'LimitController@destroy', 'as' => 'budgets.limits.destroy']); - Route::post('/budgets/limits/update/{limit}', ['uses' => 'LimitController@update', 'as' => 'budgets.limits.update']); - - Route::post('/migrate/upload', ['uses' => 'MigrateController@upload', 'as' => 'migrate.upload']); - - // piggy bank controller Route::post('/piggybanks/store', ['uses' => 'PiggybankController@store', 'as' => 'piggybanks.store']); - #Route::post('/piggybanks/store/repeated', ['uses' => 'PiggybankController@storeRepeated', 'as' => 'piggybanks.store.repeated']); Route::post('/piggybanks/update/{piggybank}', ['uses' => 'PiggybankController@update', 'as' => 'piggybanks.update']); Route::post('/piggybanks/destroy/{piggybank}', ['uses' => 'PiggybankController@destroy', 'as' => 'piggybanks.destroy']); - #Route::post('/piggybanks/mod/{piggybank}', ['uses' => 'PiggybankController@modMoney', 'as' => 'piggybanks.modMoney']); - Route::post('/piggybanks/add/{piggybank}', ['uses' => 'PiggybankController@postAdd', 'as' => 'piggybanks.add']); - Route::post('/piggybanks/remove/{piggybank}', ['uses' => 'PiggybankController@postRemove', 'as' => 'piggybanks.remove']); + Route::post('/piggybanks/add/{piggybank}', ['uses' => 'PiggybankController@postAdd', 'as' => 'piggybanks.add']); # add money + Route::post('/piggybanks/remove/{piggybank}', ['uses' => 'PiggybankController@postRemove', 'as' => 'piggybanks.remove']); # remove money. // preferences controller @@ -337,7 +264,7 @@ Route::group( // transaction controller: Route::post('/transactions/store/{what}', ['uses' => 'TransactionController@store', 'as' => 'transactions.store'])->where( - ['what' => 'withdrawal|deposit|transfer'] + ['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers'] ); Route::post('/transaction/update/{tj}', ['uses' => 'TransactionController@update', 'as' => 'transactions.update']); Route::post('/transaction/destroy/{tj}', ['uses' => 'TransactionController@destroy', 'as' => 'transactions.destroy']); diff --git a/app/views/partials/menu.blade.php b/app/views/partials/menu.blade.php index 21a5068f89..b27ec1f4ad 100644 --- a/app/views/partials/menu.blade.php +++ b/app/views/partials/menu.blade.php @@ -12,40 +12,6 @@
-
-

Migrate from Firefly II

- -

- Use this option if you have a JSON file from your current Firefly II installation. -

-

Start from scratch

- -

- Use this option if you are new to Firefly (III). -

@else From 638fa9005f7e523265444ce8df182f8536a9f12f Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 12 Nov 2014 07:31:48 +0100 Subject: [PATCH 009/193] Excluded more files from the "old" libraries and included new ones instead. This should greatly clean up the code base. --- app/controllers/AccountController.php | 2 +- app/controllers/BudgetController.php | 2 +- app/controllers/CategoryController.php | 2 +- app/controllers/GoogleTableController.php | 2 +- app/controllers/PiggybankController.php | 2 +- app/controllers/PreferencesController.php | 37 +++++++++---------- app/controllers/ProfileController.php | 12 +++--- .../FireflyIII/Exception/FireflyException.php | 14 +++++++ .../Exception/ValidationException.php | 11 ++++++ 9 files changed, 53 insertions(+), 31 deletions(-) create mode 100644 app/lib/FireflyIII/Exception/FireflyException.php create mode 100644 app/lib/FireflyIII/Exception/ValidationException.php diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index c875e0be64..2397451853 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -1,6 +1,6 @@ _accounts = $accounts; - $this->_preferences = $preferences; - View::share('title','Preferences'); - View::share('mainTitleIcon','fa-gear'); + View::share('title', 'Preferences'); + View::share('mainTitleIcon', 'fa-gear'); } /** @@ -31,13 +22,16 @@ class PreferencesController extends BaseController */ public function index() { - $accounts = $this->_accounts->getDefault(); + /** @var \FireflyIII\Database\Account $acct */ + $acct = App::make('FireflyIII\Database\Account'); - $viewRange = $this->_preferences->get('viewRange', '1M'); + /** @var \FireflyIII\Shared\Preferences\Preferences $preferences */ + $preferences = App::make('FireflyIII\Shared\Preferences\Preferences'); + + $accounts = $acct->getAssetAccounts(); + $viewRange = $preferences->get('viewRange', '1M'); $viewRangeValue = $viewRange->data; - - // pref: - $frontpage = $this->_preferences->get('frontpageAccounts', []); + $frontpage = $preferences->get('frontpageAccounts', []); return View::make('preferences.index')->with('accounts', $accounts)->with('frontpageAccounts', $frontpage) ->with('viewRange', $viewRangeValue); @@ -49,15 +43,18 @@ class PreferencesController extends BaseController public function postIndex() { + /** @var \FireflyIII\Shared\Preferences\Preferences $preferences */ + $preferences = App::make('FireflyIII\Shared\Preferences\Preferences'); + // frontpage accounts $frontpageAccounts = []; foreach (Input::get('frontpageAccounts') as $id) { $frontpageAccounts[] = intval($id); } - $this->_preferences->set('frontpageAccounts', $frontpageAccounts); + $preferences->set('frontpageAccounts', $frontpageAccounts); // view range: - $this->_preferences->set('viewRange', Input::get('viewRange')); + $preferences->set('viewRange', Input::get('viewRange')); // forget session values: Session::forget('start'); Session::forget('end'); diff --git a/app/controllers/ProfileController.php b/app/controllers/ProfileController.php index beda24d3cf..6692e02872 100644 --- a/app/controllers/ProfileController.php +++ b/app/controllers/ProfileController.php @@ -23,9 +23,9 @@ class ProfileController extends BaseController public function index() { return View::make('profile.index') - ->with('title', 'Profile') - ->with('subTitle', Auth::user()->email) - ->with('mainTitleIcon', 'fa-user'); + ->with('title', 'Profile') + ->with('subTitle', Auth::user()->email) + ->with('mainTitleIcon', 'fa-user'); } /** @@ -34,9 +34,9 @@ class ProfileController extends BaseController public function changePassword() { return View::make('profile.change-password') - ->with('title', Auth::user()->email) - ->with('subTitle', 'Change your password') - ->with('mainTitleIcon', 'fa-user'); + ->with('title', Auth::user()->email) + ->with('subTitle', 'Change your password') + ->with('mainTitleIcon', 'fa-user'); } /** diff --git a/app/lib/FireflyIII/Exception/FireflyException.php b/app/lib/FireflyIII/Exception/FireflyException.php new file mode 100644 index 0000000000..566a0cb437 --- /dev/null +++ b/app/lib/FireflyIII/Exception/FireflyException.php @@ -0,0 +1,14 @@ + Date: Wed, 12 Nov 2014 10:54:53 +0100 Subject: [PATCH 010/193] There's a giant mix brewing between "old" code, bad code and not implemented exceptions. I suspect the next change will be to cut out all old stuff, throw a lot of NotImplementedExceptions and get going. --- app/controllers/AccountController.php | 37 ++-- app/controllers/BudgetController.php | 15 +- app/controllers/GoogleTableController.php | 45 ++++ app/controllers/HomeController.php | 28 +-- app/controllers/ProfileController.php | 27 +-- app/controllers/RecurringController.php | 135 +----------- app/controllers/SearchController.php | 12 +- app/controllers/TransactionController.php | 20 +- .../Ifaces/RecurringTransactionInterface.php | 14 ++ .../Database/RecurringTransaction.php | 139 ++++++++++++ app/lib/FireflyIII/Database/User.php | 22 +- app/lib/FireflyIII/Shared/Toolkit/Filter.php | 6 +- .../FireflyIII/Shared/Toolkit/Navigation.php | 64 ++++++ app/routes.php | 1 + app/views/recurring/index.blade.php | 34 +-- public/assets/javascript/firefly/recurring.js | 203 +----------------- 16 files changed, 366 insertions(+), 436 deletions(-) create mode 100644 app/lib/FireflyIII/Database/Ifaces/RecurringTransactionInterface.php create mode 100644 app/lib/FireflyIII/Database/RecurringTransaction.php create mode 100644 app/lib/FireflyIII/Shared/Toolkit/Navigation.php diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 2397451853..f05d11623a 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -32,21 +32,21 @@ class AccountController extends BaseController break; case 'asset': $subTitleIcon = 'fa-money'; - $subTitle = 'Asset accounts'; + $subTitle = 'Asset accounts'; break; case 'expense': $subTitleIcon = 'fa-shopping-cart'; - $subTitle = 'Expense accounts'; + $subTitle = 'Expense accounts'; break; case 'revenue': $subTitleIcon = 'fa-download'; - $subTitle = 'Revenue accounts'; + $subTitle = 'Revenue accounts'; break; } return View::make('accounts.index') - ->with('what', $what) - ->with(compact('subTitleIcon')) - ->with(compact('subTitle')); + ->with('what', $what) + ->with(compact('subTitleIcon')) + ->with(compact('subTitle')); } @@ -68,9 +68,9 @@ class AccountController extends BaseController } return View::make('accounts.create') - ->with('subTitle', 'Create a new ' . $what . ' account') - ->with('what', $what) - ->with(compact('subTitleIcon')); + ->with('subTitle', 'Create a new ' . $what . ' account') + ->with('what', $what) + ->with(compact('subTitleIcon')); } /** @@ -194,13 +194,10 @@ class AccountController extends BaseController } return View::make('accounts.edit') - ->with('account', $account) - ->with('openingBalance', $openingBalance) - ->with(compact('subTitleIcon')) - ->with('subTitle', 'Edit ' . strtolower( - $account->accountType->type - ) . ' "' . $account->name . '"' - ); + ->with('account', $account) + ->with('openingBalance', $openingBalance) + ->with(compact('subTitleIcon')) + ->with('subTitle', 'Edit ' . strtolower($account->accountType->type) . ' "' . $account->name . '"'); } /** @@ -227,9 +224,9 @@ class AccountController extends BaseController //$data = $this->_accounts->show($account, 40); return View::make('accounts.show') - ->with('account', $account) - ->with('subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"') - ->with(compact('subTitleIcon')); + ->with('account', $account) + ->with('subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"') + ->with(compact('subTitleIcon')); } /** @@ -327,7 +324,7 @@ class AccountController extends BaseController if ($data['post_submit_action'] == 'create_another') { return Redirect::route('accounts.edit', $account->id); } else { - return Redirect::route('accounts.index',$data['what']); + return Redirect::route('accounts.index', $data['what']); } case 'validate_only': $messageBags = $acct->validate($data); diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php index ae8d0b123e..02a108a14e 100644 --- a/app/controllers/BudgetController.php +++ b/app/controllers/BudgetController.php @@ -22,8 +22,8 @@ class BudgetController extends BaseController */ public function postUpdateIncome() { - /** @var \Firefly\Helper\Preferences\PreferencesHelperInterface $preferences */ - $preferences = App::make('Firefly\Helper\Preferences\PreferencesHelperInterface'); + /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ + $preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); $date = Session::get('start'); $value = intval(Input::get('amount')); @@ -72,11 +72,14 @@ class BudgetController extends BaseController } + /** + * @return $this + */ public function index() { - /** @var \Firefly\Helper\Preferences\PreferencesHelperInterface $preferences */ - $preferences = App::make('Firefly\Helper\Preferences\PreferencesHelperInterface'); + /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ + $preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); $date = Session::get('start'); /** @var \FireflyIII\Database\Budget $repos */ @@ -133,8 +136,8 @@ class BudgetController extends BaseController public function updateIncome() { $date = Session::get('start'); - /** @var \Firefly\Helper\Preferences\PreferencesHelperInterface $preferences */ - $preferences = App::make('Firefly\Helper\Preferences\PreferencesHelperInterface'); + /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ + $preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); $budgetAmount = $preferences->get('budgetIncomeTotal' . $date->format('FY'), 1000); return View::make('budgets.income')->with('amount', $budgetAmount)->with('date', $date); } diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php index 05ec289c46..555440e380 100644 --- a/app/controllers/GoogleTableController.php +++ b/app/controllers/GoogleTableController.php @@ -171,6 +171,51 @@ class GoogleTableController extends BaseController } + public function recurringList() + { + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('ID', 'number'); + $chart->addColumn('ID_Edit', 'string'); + $chart->addColumn('ID_Delete', 'string'); + $chart->addColumn('Name_URL', 'string'); + $chart->addColumn('Name', 'string'); + + /** @var \FireflyIII\Database\RecurringTransaction $repository */ + $repository = App::make('FireflyIII\Database\RecurringTransaction'); + + $set = $repository->get(); + + /** @var \RecurringTransaction $entry */ + foreach ($set as $entry) { + $row = [ + $entry->id, + route('recurring.edit', $entry->id), + route('recurring.delete', $entry->id), + route('recurring.show', $entry->id), + $entry->name + ]; + $chart->addRowArray($row); + + } + + + /* + * name + match + amount_min + amount_max + date + active + automatch + repeat_freq + id + + */ + $chart->generate(); + return Response::json($chart->getData()); + } + /** * @param Account $account */ diff --git a/app/controllers/HomeController.php b/app/controllers/HomeController.php index 4bf3ee667b..56d61564ef 100644 --- a/app/controllers/HomeController.php +++ b/app/controllers/HomeController.php @@ -9,40 +9,44 @@ use FireflyIII\Shared\Preferences\PreferencesInterface as Prefs; class HomeController extends BaseController { protected $_preferences; - protected $_journal; /** - * @param PHI $preferences + * @param Prefs $preferences */ public function __construct(Prefs $preferences) { $this->_preferences = $preferences; } - /* - * + /** + * @return \Illuminate\Http\RedirectResponse */ public function sessionPrev() { - /** @var \Firefly\Helper\Toolkit\ToolkitInterface $toolkit */ - $toolkit = App::make('Firefly\Helper\Toolkit\ToolkitInterface'); - $toolkit->prev(); + /** @var \FireflyIII\Shared\Toolkit\Navigation $navigation */ + $navigation = App::make('FireflyIII\Shared\Toolkit\Navigation'); + $navigation->prev(); return Redirect::back(); //return Redirect::route('index'); } - /* - * + /** + * @return \Illuminate\Http\RedirectResponse */ public function sessionNext() { - /** @var \Firefly\Helper\Toolkit\ToolkitInterface $toolkit */ - $toolkit = App::make('Firefly\Helper\Toolkit\ToolkitInterface'); - $toolkit->next(); + /** @var \FireflyIII\Shared\Toolkit\Navigation $navigation */ + $navigation = App::make('FireflyIII\Shared\Toolkit\Navigation'); + $navigation->next(); return Redirect::back(); //return Redirect::route('index'); } + /** + * @param $range + * + * @return \Illuminate\Http\RedirectResponse + */ public function rangeJump($range) { diff --git a/app/controllers/ProfileController.php b/app/controllers/ProfileController.php index 6692e02872..ebfbc437cd 100644 --- a/app/controllers/ProfileController.php +++ b/app/controllers/ProfileController.php @@ -1,31 +1,18 @@ user = $user; - } - /** * @return \Illuminate\View\View * */ public function index() { - return View::make('profile.index') - ->with('title', 'Profile') - ->with('subTitle', Auth::user()->email) - ->with('mainTitleIcon', 'fa-user'); + return View::make('profile.index')->with('title', 'Profile')->with('subTitle', Auth::user()->email)->with('mainTitleIcon', 'fa-user'); } /** @@ -33,10 +20,9 @@ class ProfileController extends BaseController */ public function changePassword() { - return View::make('profile.change-password') - ->with('title', Auth::user()->email) - ->with('subTitle', 'Change your password') - ->with('mainTitleIcon', 'fa-user'); + return View::make('profile.change-password')->with('title', Auth::user()->email)->with('subTitle', 'Change your password')->with( + 'mainTitleIcon', 'fa-user' + ); } /** @@ -70,8 +56,9 @@ class ProfileController extends BaseController } // update the user with the new password. - /** @noinspection PhpParamsInspection */ - $this->user->updatePassword(Auth::user(), Input::get('new1')); + /** @var \FireflyIII\Database\User $repository */ + $repository = \App::make('FireflyIII\Database\User'); + $repository->updatePassword(Auth::user(), Input::get('new1')); Session::flash('success', 'Password changed!'); diff --git a/app/controllers/RecurringController.php b/app/controllers/RecurringController.php index db60b34004..b780a4822b 100644 --- a/app/controllers/RecurringController.php +++ b/app/controllers/RecurringController.php @@ -1,8 +1,6 @@ _repository = $repository; - $this->_helper = $helper; View::share('title', 'Recurring transactions'); View::share('mainTitleIcon', 'fa-rotate-right'); @@ -59,7 +48,11 @@ class RecurringController extends BaseController public function destroy(RecurringTransaction $recurringTransaction) { //Event::fire('recurring.destroy', [$recurringTransaction]); - $result = $this->_repository->destroy($recurringTransaction); + + /** @var \FireflyIII\Database\RecurringTransaction $repository */ + $repository = App::make('FireflyIII\Database\RecurringTransaction'); + + $result = $repository->destroy($recurringTransaction); if ($result === true) { Session::flash('success', 'The recurring transaction was deleted.'); } else { @@ -113,127 +106,19 @@ class RecurringController extends BaseController Session::flash('warning', 'Inactive recurring transactions cannot be scanned.'); return Redirect::back(); } - // do something! - /** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $repo */ - $repo = App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); - $set = $repo->get(); - - /** @var TransactionJournal $journal */ - foreach ($set as $journal) { - Event::fire('recurring.rescan', [$recurringTransaction, $journal]); - } + throw new NotImplementedException; Session::flash('success', 'Rescanned everything.'); return Redirect::back(); - - } public function store() { - $data = Input::except(['_token', 'post_submit_action']); - switch (Input::get('post_submit_action')) { - default: - throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.'); - break; - case 'store': - case 'create_another': - /* - * Try to store: - */ - $messageBag = $this->_repository->store($data); - - /* - * Failure! - */ - if ($messageBag->count() > 0) { - Session::flash('error', 'Could not save recurring transaction: ' . $messageBag->first()); - return Redirect::route('recurring.create')->withInput()->withErrors($messageBag); - } - - /* - * Success! - */ - Session::flash('success', 'Recurring transaction "' . e(Input::get('name')) . '" saved!'); - - /* - * Redirect to original location or back to the form. - */ - if (Input::get('post_submit_action') == 'create_another') { - return Redirect::route('recurring.create')->withInput(); - } else { - return Redirect::route('recurring.index'); - } - break; - case 'validate_only': - $messageBags = $this->_helper->validate($data); - - Session::flash('warnings', $messageBags['warnings']); - Session::flash('successes', $messageBags['successes']); - Session::flash('errors', $messageBags['errors']); - return Redirect::route('recurring.create')->withInput(); - break; - } + throw new NotImplementedException; } public function update(RecurringTransaction $recurringTransaction) { - $data = Input::except(['_token', 'post_submit_action']); - switch (Input::get('post_submit_action')) { - case 'update': - case 'return_to_edit': - $messageBag = $this->_repository->update($recurringTransaction, $data); - if ($messageBag->count() == 0) { - // has been saved, return to index: - Session::flash('success', 'Recurring transaction updated!'); - - if (Input::get('post_submit_action') == 'return_to_edit') { - return Redirect::route('recurring.edit', $recurringTransaction->id)->withInput(); - } else { - return Redirect::route('recurring.index'); - } - } else { - Session::flash('error', 'Could not update recurring transaction: ' . $messageBag->first()); - - return Redirect::route('transactions.edit', $recurringTransaction->id)->withInput() - ->withErrors($messageBag); - } - - - break; - case 'validate_only': - $data = Input::all(); - $data['id'] = $recurringTransaction->id; - $messageBags = $this->_helper->validate($data); - - Session::flash('warnings', $messageBags['warnings']); - Session::flash('successes', $messageBags['successes']); - Session::flash('errors', $messageBags['errors']); - return Redirect::route('recurring.edit', $recurringTransaction->id)->withInput(); - - break; - // update - default: - throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.'); - break; - } - - -// /** @var \RecurringTransaction $recurringTransaction */ -// $recurringTransaction = $this->_repository->update($recurringTransaction, Input::all()); -// if ($recurringTransaction->errors()->count() == 0) { -// Session::flash('success', 'The recurring transaction has been updated.'); -// //Event::fire('recurring.update', [$recurringTransaction]); -// -// return Redirect::route('recurring.index'); -// } else { -// Session::flash( -// 'error', 'Could not update the recurring transaction: ' . $recurringTransaction->errors()->first() -// ); -// -// return Redirect::route('recurring.edit', $recurringTransaction->id)->withInput()->withErrors( -// $recurringTransaction->errors() -// ); -// } + throw new NotImplementedException; } } \ No newline at end of file diff --git a/app/controllers/SearchController.php b/app/controllers/SearchController.php index 205933400b..49fe5ff1af 100644 --- a/app/controllers/SearchController.php +++ b/app/controllers/SearchController.php @@ -1,25 +1,17 @@ _helper = $helper; - - } - /** * Results always come in the form of an array [results, count, fullCount] */ public function index() { + throw new NotImplementedException; $subTitle = null; $rawQuery = null; $result = []; diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index e3ed758ed3..0f9fe231c1 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -1,33 +1,22 @@ _repository = $repository; - $this->_helper = $helper; View::share('title', 'Transactions'); View::share('mainTitleIcon', 'fa-repeat'); } @@ -41,6 +30,7 @@ class TransactionController extends BaseController */ public function create($what = 'deposit') { + throw new NotImplementedException; /* * The repositories we need: */ @@ -110,6 +100,7 @@ class TransactionController extends BaseController */ public function destroy(TransactionJournal $transactionJournal) { + throw new NotImplementedException; $type = $transactionJournal->transactionType->type; $transactionJournal->delete(); @@ -135,6 +126,7 @@ class TransactionController extends BaseController */ public function edit(TransactionJournal $journal) { + throw new NotImplementedException; /* * All the repositories we need: */ @@ -268,6 +260,7 @@ class TransactionController extends BaseController */ public function store($what) { + throw new NotImplementedException; /* * Collect data to process: */ @@ -334,6 +327,7 @@ class TransactionController extends BaseController */ public function update(TransactionJournal $journal) { + throw new NotImplementedException; switch (Input::get('post_submit_action')) { case 'update': case 'return_to_edit': diff --git a/app/lib/FireflyIII/Database/Ifaces/RecurringTransactionInterface.php b/app/lib/FireflyIII/Database/Ifaces/RecurringTransactionInterface.php new file mode 100644 index 0000000000..1669902ab1 --- /dev/null +++ b/app/lib/FireflyIII/Database/Ifaces/RecurringTransactionInterface.php @@ -0,0 +1,14 @@ +setUser(\Auth::user()); + } + + /** + * @param Ardent $model + * + * @return bool + */ + public function destroy(Ardent $model) + { + // TODO: Implement destroy() method. + throw new NotImplementedException; + } + + /** + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param Ardent $model + * + * @return array + */ + public function validateObject(Ardent $model) + { + // TODO: Implement validateObject() method. + throw new NotImplementedException; + } + + /** + * Validates an array. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param array $model + * + * @return array + */ + public function validate(array $model) + { + // TODO: Implement validate() method. + throw new NotImplementedException; + } + + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. + throw new NotImplementedException; + } + + /** + * Returns an object with id $id. + * + * @param int $id + * + * @return Ardent + */ + public function find($id) + { + // TODO: Implement find() method. + throw new NotImplementedException; + } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + return $this->getUser()->recurringtransactions()->get(); + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } + + /** + * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. + * + * @param $what + * + * @return \AccountType|null + */ + public function findByWhat($what) + { + // TODO: Implement findByWhat() method. + throw new NotImplementedException; + } +} \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/User.php b/app/lib/FireflyIII/Database/User.php index 591b204991..f72a26d415 100644 --- a/app/lib/FireflyIII/Database/User.php +++ b/app/lib/FireflyIII/Database/User.php @@ -5,6 +5,7 @@ namespace FireflyIII\Database; /** * Class User + * * @package FireflyIII\Database */ class User @@ -12,14 +13,15 @@ class User /** * @param array $data + * * @return bool|\User */ public function register(array $data) { - $user = new \User; - $user->email = isset($data['email']) ? $data['email'] : null; + $user = new \User; + $user->email = isset($data['email']) ? $data['email'] : null; $user->migrated = 0; - $user->reset = \Str::random(32); + $user->reset = \Str::random(32); $user->password = \Hash::make(\Str::random(12)); if (!$user->save()) { @@ -34,6 +36,20 @@ class User } + /** + * @param \User $user + * @param $password + * + * @return bool + */ + public function updatePassword(\User $user, $password) + { + $user->password = $password; + $user->forceSave(); + + return true; + } + /** * @param $mail * diff --git a/app/lib/FireflyIII/Shared/Toolkit/Filter.php b/app/lib/FireflyIII/Shared/Toolkit/Filter.php index c0cc51834e..b3cb70686c 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Filter.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Filter.php @@ -24,7 +24,7 @@ class Filter * * @return string */ - protected function setSessionRangeValue() + public function setSessionRangeValue() { if (!is_null(\Session::get('range'))) { $range = \Session::get('range'); @@ -221,7 +221,7 @@ class Filter * @return Carbon * @throws FireflyException */ - protected function previous($range, Carbon $date) + public function previous($range, Carbon $date) { switch ($range) { default: @@ -262,7 +262,7 @@ class Filter * @return Carbon * @throws FireflyException */ - protected function next($range, Carbon $date) + public function next($range, Carbon $date) { switch ($range) { case '1D': diff --git a/app/lib/FireflyIII/Shared/Toolkit/Navigation.php b/app/lib/FireflyIII/Shared/Toolkit/Navigation.php new file mode 100644 index 0000000000..f4f40e9117 --- /dev/null +++ b/app/lib/FireflyIII/Shared/Toolkit/Navigation.php @@ -0,0 +1,64 @@ +setSessionRangeValue(); + $start = \Session::get('start'); + + /* + * Add some period to $start. + */ + $next = $filter->next($range, clone $start); + + /* + * Save in session: + */ + \Session::put('start', $next); + return true; + } + + /** + * @return bool + * @throws \Firefly\Exception\FireflyException + */ + public function prev() + { + /* + * Get the start date and the range from the session + */ + $filter = new Filter; + + $range = $filter->setSessionRangeValue(); + $start = \Session::get('start'); + + /* + * Substract some period to $start. + */ + $prev = $filter->previous($range, clone $start); + + /* + * Save in session: + */ + \Session::put('start', $prev); + return true; + } +} \ No newline at end of file diff --git a/app/routes.php b/app/routes.php index b846454ab1..983c2f318d 100644 --- a/app/routes.php +++ b/app/routes.php @@ -163,6 +163,7 @@ Route::group( Route::get('/table/account/{account}/transactions', ['uses' => 'GoogleTableController@transactionsByAccount']); Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']); Route::get('/table/categories', ['uses' => 'GoogleTableController@categoryList']); + Route::get('/table/recurring', ['uses' => 'GoogleTableController@recurringList']); // google table for components (categories + budgets) Route::get('/table/component/{component}/{limitrepetition}/transactions', ['uses' => 'GoogleTableController@transactionsByComponent']); diff --git a/app/views/recurring/index.blade.php b/app/views/recurring/index.blade.php index ac3831d090..ddfbf6f309 100644 --- a/app/views/recurring/index.blade.php +++ b/app/views/recurring/index.blade.php @@ -7,35 +7,21 @@ {{{$title}}}
- - - - - - - - - - - - - - -
namematchamount_minamount_maxdateactiveautomatchrepeat_freqid
+
@stop @section('scripts') - -{{HTML::script('assets/javascript/typeahead/bootstrap3-typeahead.min.js')}} -{{HTML::script('assets/javascript/datatables/jquery.dataTables.min.js')}} -{{HTML::script('assets/javascript/datatables/dataTables.bootstrap.js')}} + + + +{{HTML::script('assets/javascript/firefly/gcharts.options.js')}} +{{HTML::script('assets/javascript/firefly/gcharts.js')}} + + + + {{HTML::script('assets/javascript/firefly/recurring.js')}} -@stop -@section('styles') -{{HTML::style('assets/stylesheets/datatables/dataTables.bootstrap.css')}} @stop \ No newline at end of file diff --git a/public/assets/javascript/firefly/recurring.js b/public/assets/javascript/firefly/recurring.js index 06aacad3f4..11b33573d7 100644 --- a/public/assets/javascript/firefly/recurring.js +++ b/public/assets/javascript/firefly/recurring.js @@ -1,204 +1,7 @@ $(document).ready(function () { - if ($('#recurringTable').length > 0) { - $('#recurringTable').DataTable( - { - serverSide: true, - ajax: URL, - paging: true, - processing: true, - order: [], - "lengthMenu": [[50, 100, 250, -1], [50, 100, 250, "All"]], - columns: [ - { - name: 'name', - data: 'name', - searchable: true, - title: 'Name', - render: function (data) { - return '' + data.name + ''; - } - }, - { - name: 'match', - data: 'match', - searchable: true, - title: 'Matches on', - render: function (data) { - var str = ''; - for (x in data) { - str += '' + data[x] + ' '; - } - return str;//return '' + data.name + ''; - } - }, - { - name: 'amount_min', - data: 'amount_min', - searchable: false, - title: '→', - render: function (data) { - return '\u20AC ' + data.toFixed(2) + ''; - } - }, - { - name: 'amount_max', - data: 'amount_max', - searchable: false, - title: '←', - render: function (data) { - return '\u20AC ' + data.toFixed(2) + ''; - } - }, - { - name: 'date', - data: 'date', - title: 'Expected on', - searchable: false - }, - - { - name: 'active', - data: 'active', - searchable: false, - sortable: false, - render: function (data) { - if (data == 1) { - return ''; - } else { - return ''; - } - }, - title: 'Is active?' - }, - { - name: 'automatch', - data: 'automatch', - sortable: false, - searchable: false, - render: function (data) { - if (data == 1) { - return ''; - } else { - return ''; - } - }, - title: 'Automatch?' - }, - { - name: 'repeat_freq', - data: 'repeat_freq', - searchable: false, - sortable: false, - title: 'Repeat frequency' - }, - { - name: 'id', - data: 'id', - searchable: false, - sortable: false, - title: '', - render: function (data, type, full, meta) { - return ''; - } - } - ] - } - ); - } - if ($('#transactionTable').length > 0) { - $('#transactionTable').DataTable( - { - serverSide: true, - ajax: URL, - paging: true, - processing: true, - order: [], - "lengthMenu": [[50, 100, 250, -1], [50, 100, 250, "All"]], - columns: [ - { - name: 'date', - data: 'date', - searchable: false - }, - { - name: 'description', - data: 'description', - render: function (data, type, full, meta) { - icon = 'glyphicon-arrow-left'; - - return ' ' + - '' + data.description + ''; - } - }, - { - name: 'amount', - data: 'amount', - 'title': 'Amount (\u20AC)', - searchable: false, - render: function (data, type, full, meta) { - return '\u20AC ' + data.toFixed(2) + ''; - } - }, - { - name: 'from', - data: 'from', - searchable: false, - render: function (data, type, full, meta) { - return '' + data.name + ''; - } - }, - { - name: 'to', - data: 'to', - searchable: false, - render: function (data, type, full, meta) { - return '' + data.name + ''; - } - }, - { - name: 'components', - data: 'components', - searchable: true, - sortable: false, - title: '', - render: function (data, type, full, meta) { - var html = ''; - if (data.budget_id > 0) { - html += ' '; - } - if (data.category_id > 0) { - html += ' '; - } - if (data.recurring_id > 0) { - html += ' '; - } - return html; - } - }, - { - name: 'id', - data: 'id', - searchable: false, - sortable: false, - title: '', - render: function (data, type, full, meta) { - return ''; - } - } - ] - } - ); - } + if (typeof(googleTable) == 'function') { + googleTable('table/recurring','recurring-table'); + } } ); \ No newline at end of file From d34cc65984217c7c435ee89745909815d29e2712 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Wed, 12 Nov 2014 14:38:32 +0100 Subject: [PATCH 011/193] Start cleaning up transactions controller. --- app/controllers/GoogleChartController.php | 2 +- app/controllers/HomeController.php | 21 +- app/controllers/TransactionController.php | 90 ++--- app/lib/FireflyIII/Form/Form.php | 379 ++++++++++++++++++ .../Shared/SingleTableInheritanceEntity.php | 121 ++++++ app/models/Component.php | 2 +- app/models/LimitRepetition.php | 11 +- app/models/Reminder.php | 1 - app/models/Transaction.php | 26 +- app/start/global.php | 18 +- app/tests/TestCase.php | 1 - .../{list.blade.php => index.blade.php} | 12 +- app/views/user/register.blade.php | 2 +- .../assets/javascript/firefly/transactions.js | 103 ----- 14 files changed, 585 insertions(+), 204 deletions(-) create mode 100644 app/lib/FireflyIII/Form/Form.php create mode 100644 app/lib/FireflyIII/Shared/SingleTableInheritanceEntity.php rename app/views/transactions/{list.blade.php => index.blade.php} (66%) diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index 0d5f79e7d3..281bc124db 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -371,7 +371,7 @@ class GoogleChartController extends BaseController /** * @return \Illuminate\Http\JsonResponse - * @throws \Firefly\Exception\FireflyException + * @throws \FireflyIII\Exception\FireflyException */ public function recurringTransactionsOverview() { diff --git a/app/controllers/HomeController.php b/app/controllers/HomeController.php index 56d61564ef..833ea0a044 100644 --- a/app/controllers/HomeController.php +++ b/app/controllers/HomeController.php @@ -4,20 +4,9 @@ use FireflyIII\Shared\Preferences\PreferencesInterface as Prefs; /** * Class HomeController * - * @SuppressWarnings(PHPMD.CamelCasePropertyName) */ class HomeController extends BaseController { - protected $_preferences; - - /** - * @param Prefs $preferences - */ - public function __construct(Prefs $preferences) - { - $this->_preferences = $preferences; - } - /** * @return \Illuminate\Http\RedirectResponse */ @@ -52,8 +41,11 @@ class HomeController extends BaseController $valid = ['1D', '1W', '1M', '3M', '6M', '1Y',]; + /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ + $preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); + if (in_array($range, $valid)) { - $this->_preferences->set('viewRange', $range); + $preferences->set('viewRange', $range); Session::forget('range'); } return Redirect::back(); @@ -85,6 +77,9 @@ class HomeController extends BaseController /** @var \FireflyIII\Database\TransactionJournal $jrnls */ $jrnls = App::make('FireflyIII\Database\TransactionJournal'); + /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ + $preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); + $count = $acct->countAssetAccounts(); $start = Session::get('start'); @@ -92,7 +87,7 @@ class HomeController extends BaseController // get the preference for the home accounts to show: - $frontpage = $this->_preferences->get('frontpageAccounts', []); + $frontpage = $preferences->get('frontpageAccounts', []); if ($frontpage->data == []) { $accounts = $acct->getAssetAccounts(); } else { diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 0f9fe231c1..26154381ed 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -2,6 +2,7 @@ use FireflyIII\Exception\FireflyException; +use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\MessageBag; /** @@ -30,31 +31,30 @@ class TransactionController extends BaseController */ public function create($what = 'deposit') { - throw new NotImplementedException; /* * The repositories we need: */ - /** @var \Firefly\Helper\Toolkit\Toolkit $toolkit */ - $toolkit = App::make('Firefly\Helper\Toolkit\Toolkit'); + /** @var \FireflyIII\Shared\Toolkit\Form $form */ + $form = App::make('FireflyIII\Shared\Toolkit\Form'); - /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accountRepository */ - $accountRepository = App::make('Firefly\Storage\Account\AccountRepositoryInterface'); + /** @var \FireflyIII\Database\Account $accountRepository */ + $accountRepository = App::make('FireflyIII\Database\Account'); - /** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budgetRepository */ - $budgetRepository = App::make('Firefly\Storage\Budget\BudgetRepositoryInterface'); + /** @var \FireflyIII\Database\Budget $budgetRepository */ + $budgetRepository = App::make('FireflyIII\Database\Budget'); - /** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggyRepository */ - $piggyRepository = App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface'); + /** @var \FireflyIII\Database\Piggybank $piggyRepository */ + $piggyRepository = App::make('FireflyIII\Database\Piggybank'); // get asset accounts with names and id's. - $assetAccounts = $toolkit->makeSelectList($accountRepository->getActiveDefault()); + $assetAccounts = $form->makeSelectList($accountRepository->getAssetAccounts()); // get budgets as a select list. - $budgets = $toolkit->makeSelectList($budgetRepository->get()); + $budgets = $form->makeSelectList($budgetRepository->get()); $budgets[0] = '(no budget)'; // get the piggy banks. - $piggies = $toolkit->makeSelectList($piggyRepository->get()); + $piggies = $form->makeSelectList($piggyRepository->get()); $piggies[0] = '(no piggy bank)'; /* @@ -100,19 +100,21 @@ class TransactionController extends BaseController */ public function destroy(TransactionJournal $transactionJournal) { - throw new NotImplementedException; $type = $transactionJournal->transactionType->type; - $transactionJournal->delete(); + + /** @var \FireflyIII\Database\TransactionJournal $repository */ + $repository = App::make('FireflyIII\Database\TransactionJournal'); + $repository->destroy($transactionJournal); switch ($type) { case 'Withdrawal': - return Redirect::route('transactions.expenses'); + return Redirect::route('transactions.index', 'withdrawal'); break; case 'Deposit': - return Redirect::route('transactions.revenue'); + return Redirect::route('transactions.index', 'deposit'); break; case 'Transfer': - return Redirect::route('transactions.transfers'); + return Redirect::route('transactions.index', 'transfers'); break; } } @@ -126,30 +128,30 @@ class TransactionController extends BaseController */ public function edit(TransactionJournal $journal) { - throw new NotImplementedException; /* * All the repositories we need: */ - /** @var \Firefly\Helper\Toolkit\Toolkit $toolkit */ - $toolkit = App::make('Firefly\Helper\Toolkit\Toolkit'); + /** @var \FireflyIII\Shared\Toolkit\Form $form */ + $form = App::make('FireflyIII\Shared\Toolkit\Form'); - /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accountRepository */ - $accountRepository = App::make('Firefly\Storage\Account\AccountRepositoryInterface'); + /** @var \FireflyIII\Database\Account $accountRepository */ + $accountRepository = App::make('FireflyIII\Database\Account'); - /** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budgetRepository */ - $budgetRepository = App::make('Firefly\Storage\Budget\BudgetRepositoryInterface'); + /** @var \FireflyIII\Database\Budget $budgetRepository */ + $budgetRepository = App::make('FireflyIII\Database\Budget'); + + /** @var \FireflyIII\Database\Piggybank $piggyRepository */ + $piggyRepository = App::make('FireflyIII\Database\Piggybank'); - /** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggyRepository */ - $piggyRepository = App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface'); // type is useful for display: $what = strtolower($journal->transactiontype->type); // get asset accounts with names and id's. - $accounts = $toolkit->makeSelectList($accountRepository->getActiveDefault()); + $accounts = $form->makeSelectList($accountRepository->getAssetAccounts()); // get budgets as a select list. - $budgets = $toolkit->makeSelectList($budgetRepository->get()); + $budgets = $form->makeSelectList($budgetRepository->get()); $budgets[0] = '(no budget)'; /* @@ -157,8 +159,8 @@ class TransactionController extends BaseController * of the transactions in the journal has this field, it should all fill in nicely. */ // get the piggy banks. - $piggies = $toolkit->makeSelectList($piggyRepository->get()); - $piggies[0] = '(no piggy bank)'; + $piggies = $form->makeSelectList($piggyRepository->get()); + $piggies[0] = '(no piggy bank)'; $piggyBankId = 0; foreach ($journal->transactions as $t) { if (!is_null($t->piggybank_id)) { @@ -190,23 +192,23 @@ class TransactionController extends BaseController */ switch ($what) { case 'withdrawal': - $prefilled['account_id'] = $journal->transactions[0]->account->id; + $prefilled['account_id'] = $journal->transactions[0]->account->id; $prefilled['expense_account'] = $journal->transactions[1]->account->name; - $prefilled['amount'] = floatval($journal->transactions[1]->amount); - $budget = $journal->budgets()->first(); + $prefilled['amount'] = floatval($journal->transactions[1]->amount); + $budget = $journal->budgets()->first(); if (!is_null($budget)) { $prefilled['budget_id'] = $budget->id; } break; case 'deposit': - $prefilled['account_id'] = $journal->transactions[1]->account->id; + $prefilled['account_id'] = $journal->transactions[1]->account->id; $prefilled['revenue_account'] = $journal->transactions[0]->account->name; - $prefilled['amount'] = floatval($journal->transactions[1]->amount); + $prefilled['amount'] = floatval($journal->transactions[1]->amount); break; case 'transfer': $prefilled['account_from_id'] = $journal->transactions[1]->account->id; - $prefilled['account_to_id'] = $journal->transactions[0]->account->id; - $prefilled['amount'] = floatval($journal->transactions[1]->amount); + $prefilled['account_to_id'] = $journal->transactions[0]->account->id; + $prefilled['amount'] = floatval($journal->transactions[1]->amount); break; } @@ -264,7 +266,7 @@ class TransactionController extends BaseController /* * Collect data to process: */ - $data = Input::except(['_token']); + $data = Input::except(['_token']); $data['what'] = $what; switch (Input::get('post_submit_action')) { @@ -312,11 +314,9 @@ class TransactionController extends BaseController } } - public function transfers() + public function index($what) { - return View::make('transactions.list')->with('subTitle', 'Transfers')->with( - 'subTitleIcon', 'fa-arrows-h' - )->with('what', 'transfers'); + return View::make('transactions.index')->with('subTitle', 'Bla bla')->with('subTitleIcon', 'fa-arrows-h')->with('what', $what); } @@ -331,7 +331,7 @@ class TransactionController extends BaseController switch (Input::get('post_submit_action')) { case 'update': case 'return_to_edit': - $what = strtolower($journal->transactionType->type); + $what = strtolower($journal->transactionType->type); $messageBag = $this->_helper->update($journal, Input::all()); if ($messageBag->count() == 0) { // has been saved, return to index: @@ -353,9 +353,9 @@ class TransactionController extends BaseController break; case 'validate_only': - $data = Input::all(); + $data = Input::all(); $data['what'] = strtolower($journal->transactionType->type); - $messageBags = $this->_helper->validate($data); + $messageBags = $this->_helper->validate($data); Session::flash('warnings', $messageBags['warnings']); Session::flash('successes', $messageBags['successes']); diff --git a/app/lib/FireflyIII/Form/Form.php b/app/lib/FireflyIII/Form/Form.php new file mode 100644 index 0000000000..ad7483cc07 --- /dev/null +++ b/app/lib/FireflyIII/Form/Form.php @@ -0,0 +1,379 @@ + 'Amount (min)', + 'amount_max' => 'Amount (max)', + 'match' => 'Matches on', + 'repeat_freq' => 'Repetition', + 'account_from_id' => 'Account from', + 'account_to_id' => 'Account to', + 'account_id' => 'Asset account' + ]; + + return isset($labels[$name]) ? $labels[$name] : str_replace('_', ' ', ucfirst($name)); + + } + + /** + * Return buttons for update/validate/return. + * + * @param $type + * @param $name + */ + public static function ffOptionsList($type, $name) + { + $previousValue = \Input::old('post_submit_action'); + $previousValue = is_null($previousValue) ? 'store' : $previousValue; + /* + * Store. + */ + $store = ''; + switch ($type) { + case 'create': + $store = '
'; + $store .= '
'; + break; + case 'update': + $store = '
'; + $store .= '
'; + break; + default: + throw new FireflyException('Cannot create ffOptionsList for option (store) ' . $type); + break; + } + + /* + * validate is always the same: + */ + $validate = '
'; + + /* + * Store & return: + */ + switch ($type) { + case 'create': + $return = '
'; + break; + case 'update': + $return = '
'; + break; + default: + throw new FireflyException('Cannot create ffOptionsList for option (store+return) ' . $type); + break; + } + return $store . $validate . $return; + } + + /** + * @param $type + * @param $name + * @param null $value + * @param array $options + * @param array $list + * + * @return string + * @throws FireflyException + */ + public static function ffInput($type, $name, $value = null, array $options = array(), $list = []) + { + /* + * add some defaults to this method: + */ + $options['class'] = 'form-control'; + $options['id'] = 'ffInput_' . $name; + $options['autocomplete'] = 'off'; + $label = self::label($name, $options); + /* + * Make label and placeholder look nice. + */ + $options['placeholder'] = ucfirst($name); + + /* + * Get prefilled value: + */ + if (\Session::has('prefilled')) { + $prefilled = \Session::get('prefilled'); + $value = isset($prefilled[$name]) && is_null($value) ? $prefilled[$name] : $value; + } + + /* + * Get the value. + */ + if (!is_null(\Input::old($name))) { + /* + * Old value overrules $value. + */ + $value = \Input::old($name); + } + + /* + * Get errors, warnings and successes from session: + */ + /** @var MessageBag $errors */ + $errors = \Session::get('errors'); + + /** @var MessageBag $warnings */ + $warnings = \Session::get('warnings'); + + /** @var MessageBag $successes */ + $successes = \Session::get('successes'); + + + /* + * If errors, add some more classes. + */ + switch (true) { + case (!is_null($errors) && $errors->has($name)): + $classes = 'form-group has-error has-feedback'; + break; + case (!is_null($warnings) && $warnings->has($name)): + $classes = 'form-group has-warning has-feedback'; + break; + case (!is_null($successes) && $successes->has($name)): + $classes = 'form-group has-success has-feedback'; + break; + default: + $classes = 'form-group'; + break; + } + + /* + * Add some HTML. + */ + $html = '
'; + $html .= ''; + $html .= '
'; + + + /* + * Switch input type: + */ + unset($options['label']); + switch ($type) { + case 'text': + $html .= \Form::input('text', $name, $value, $options); + break; + case 'amount': + $html .= '
'; + $html .= \Form::input('number', $name, $value, $options); + $html .= '
'; + break; + case 'number': + $html .= \Form::input('number', $name, $value, $options); + break; + case 'checkbox': + $checked = $options['checked']; + unset($options['checked'], $options['placeholder'], $options['autocomplete'], $options['class']); + $html .= '
'; + + + break; + case 'date': + $html .= \Form::input('date', $name, $value, $options); + break; + case 'select': + $html .= \Form::select($name, $list, $value, $options); + break; + default: + throw new FireflyException('Cannot handle type "' . $type . '" in FFFormBuilder.'); + break; + } + + /* + * If errors, respond to them: + */ + + if (!is_null($errors)) { + if ($errors->has($name)) { + $html .= ''; + $html .= '

' . e($errors->first($name)) . '

'; + } + } + unset($errors); + /* + * If warnings, respond to them: + */ + + if (!is_null($warnings)) { + if ($warnings->has($name)) { + $html .= ''; + $html .= '

' . e($warnings->first($name)) . '

'; + } + } + unset($warnings); + + /* + * If successes, respond to them: + */ + + if (!is_null($successes)) { + if ($successes->has($name)) { + $html .= ''; + $html .= '

' . e($successes->first($name)) . '

'; + } + } + unset($successes); + + $html .= '
'; + $html .= '
'; + + return $html; + + } +} \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/SingleTableInheritanceEntity.php b/app/lib/FireflyIII/Shared/SingleTableInheritanceEntity.php new file mode 100644 index 0000000000..9787e02e40 --- /dev/null +++ b/app/lib/FireflyIII/Shared/SingleTableInheritanceEntity.php @@ -0,0 +1,121 @@ +mapData((array)$attributes)->newInstance([], true); + $instance->setRawAttributes((array)$attributes, true); + + return $instance; + } + + + /** + * if no subclass is defined, function as normal + * + * @param array $attributes + * + * @return \Illuminate\Database\Eloquent\Model|static + */ + public function mapData(array $attributes) + { + if (!$this->subclassField) { + return $this->newInstance(); + } + + return new $attributes[$this->subclassField]; + } + + + /** + * + * instead of using $this->newInstance(), call + * newInstance() on the object from mapData + * + * @param bool $excludeDeleted + * + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function newQuery($excludeDeleted = true) + { + // If using Laravel 4.0.x then use the following commented version of this command + // $builder = new Builder($this->newBaseQueryBuilder()); + // newEloquentBuilder() was added in 4.1 + $builder = $this->newEloquentBuilder($this->newBaseQueryBuilder()); + + // Once Firefly has the query builders, it will set the model instances so the + // builder can easily access any information it may need from the model + // while it is constructing and executing various queries against it. + $builder->setModel($this)->with($this->with); + + if ($excludeDeleted && $this->softDelete) { + $builder->whereNull($this->getQualifiedDeletedAtColumn()); + } + + if ($this->subclassField && $this->isSubclass()) { + $builder->where($this->subclassField, '=', get_class($this)); + } + + return $builder; + } + + /** + * @return bool + */ + public function isSubclass() + { + return $this->isSubclass; + } + + /** + * ensure that the subclass field is assigned on save + * + * @param array $rules + * @param array $customMessages + * @param array $options + * @param callable $beforeSave + * @param callable $afterSave + * + * @return bool + */ + public function save( + array $rules = [], + array $customMessages = [], + array $options = [], + \Closure $beforeSave = null, + \Closure $afterSave = null + ) { + if ($this->subclassField) { + $this->attributes[$this->subclassField] = get_class($this); + } + + return parent::save($rules, $customMessages, $options, $beforeSave, $afterSave); + } +} \ No newline at end of file diff --git a/app/models/Component.php b/app/models/Component.php index 9337fcced7..f0905fcb84 100644 --- a/app/models/Component.php +++ b/app/models/Component.php @@ -1,5 +1,5 @@ repeat_freq) { default: - throw new \Firefly\Exception\FireflyException( - 'No date formats for frequency "' . $this->repeat_freq - . '"!' - ); + throw new FireflyException('No date formats for frequency "' . $this->repeat_freq . '"!'); break; case 'daily': return $this->startdate->format('Ymd') . '-5'; @@ -119,10 +117,7 @@ class LimitRepetition extends Ardent } switch ($this->repeat_freq) { default: - throw new \Firefly\Exception\FireflyException( - 'No date formats for frequency "' . $this->repeat_freq - . '"!' - ); + throw new FireflyException('No date formats for frequency "' . $this->repeat_freq . '"!'); break; case 'daily': return $this->startdate->format('j F Y'); diff --git a/app/models/Reminder.php b/app/models/Reminder.php index c2fb74936c..0d11a174f5 100644 --- a/app/models/Reminder.php +++ b/app/models/Reminder.php @@ -1,7 +1,6 @@ account_id == $piggybank->account_id) { - $this->piggybank()->associate($piggybank); - $this->save(); - \Event::fire('piggybanks.createRelatedTransfer', [$piggybank, $this->transactionJournal, $this]); - return true; - } - return false; + throw new NotImplementedException; +// if (is_null($piggybank)) { +// return true; +// } +// /** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggyRepository */ +// $piggyRepository = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface'); +// if ($this->account_id == $piggybank->account_id) { +// $this->piggybank()->associate($piggybank); +// $this->save(); +// \Event::fire('piggybanks.createRelatedTransfer', [$piggybank, $this->transactionJournal, $this]); +// return true; +// } +// return false; } /** diff --git a/app/start/global.php b/app/start/global.php index 10109df498..6968b4dfba 100644 --- a/app/start/global.php +++ b/app/start/global.php @@ -74,47 +74,47 @@ App::down( // forms: \Form::macro( 'ffText', function ($name, $value = null, array $options = []) { - return \Firefly\Form\Form::ffText($name, $value, $options); + return \FireflyIII\Form\Form::ffText($name, $value, $options); } ); \Form::macro( 'ffSelect', function ($name, array $list = [], $selected = null, array $options = []) { - return \Firefly\Form\Form::ffSelect($name, $list, $selected, $options); + return \FireflyIII\Form\Form::ffSelect($name, $list, $selected, $options); } ); \Form::macro( 'ffInteger', function ($name, $value = null, array $options = []) { - return \Firefly\Form\Form::ffInteger($name, $value, $options); + return \FireflyIII\Form\Form::ffInteger($name, $value, $options); } ); \Form::macro( 'ffAmount', function ($name, $value = null, array $options = []) { - return \Firefly\Form\Form::ffAmount($name, $value, $options); + return \FireflyIII\Form\Form::ffAmount($name, $value, $options); } ); \Form::macro( 'ffBalance', function ($name, $value = null, array $options = []) { - return \Firefly\Form\Form::ffBalance($name, $value, $options); + return \FireflyIII\Form\Form::ffBalance($name, $value, $options); } ); \Form::macro( 'ffDate', function ($name, $value = null, array $options = []) { - return \Firefly\Form\Form::ffDate($name, $value, $options); + return \FireflyIII\Form\Form::ffDate($name, $value, $options); } ); \Form::macro( 'ffTags', function ($name, $value = null, array $options = []) { - return \Firefly\Form\Form::ffTags($name, $value, $options); + return \FireflyIII\Form\Form::ffTags($name, $value, $options); } ); \Form::macro( 'ffCheckbox', function ($name, $value = 1, $checked = null, $options = []) { - return \Firefly\Form\Form::ffCheckbox($name, $value, $checked, $options); + return \FireflyIII\Form\Form::ffCheckbox($name, $value, $checked, $options); } ); \Form::macro( 'ffOptionsList', function ($type, $name) { - return \Firefly\Form\Form::ffOptionsList($type, $name); + return \FireflyIII\Form\Form::ffOptionsList($type, $name); } ); diff --git a/app/tests/TestCase.php b/app/tests/TestCase.php index f6230dd2ef..872cc48bcc 100644 --- a/app/tests/TestCase.php +++ b/app/tests/TestCase.php @@ -11,7 +11,6 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase * Creates the application. * * @return \Symfony\Component\HttpKernel\HttpKernelInterface - * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ public function createApplication() { diff --git a/app/views/transactions/list.blade.php b/app/views/transactions/index.blade.php similarity index 66% rename from app/views/transactions/list.blade.php rename to app/views/transactions/index.blade.php index 729a7d2263..f96f23b171 100644 --- a/app/views/transactions/list.blade.php +++ b/app/views/transactions/index.blade.php @@ -7,7 +7,8 @@ {{{$subTitle}}}
- +
+ @@ -29,14 +30,7 @@ @stop @section('scripts') -{{HTML::script('assets/javascript/typeahead/bootstrap3-typeahead.min.js')}} -{{HTML::script('assets/javascript/datatables/jquery.dataTables.min.js')}} -{{HTML::script('assets/javascript/datatables/dataTables.bootstrap.js')}} {{HTML::script('assets/javascript/firefly/transactions.js')}} -@stop -@section('styles') -{{HTML::style('assets/stylesheets/datatables/dataTables.bootstrap.css')}} @stop \ No newline at end of file diff --git a/app/views/user/register.blade.php b/app/views/user/register.blade.php index c067e57389..0b012cb628 100644 --- a/app/views/user/register.blade.php +++ b/app/views/user/register.blade.php @@ -11,7 +11,7 @@ Registering an account on Firefly requires an e-mail address. All instructions will be sent to you.

- {{Form::open()}} + {{Form::open(['id' => 'register'])}}
diff --git a/public/assets/javascript/firefly/transactions.js b/public/assets/javascript/firefly/transactions.js index 98ca8a33ed..39bb0507ec 100644 --- a/public/assets/javascript/firefly/transactions.js +++ b/public/assets/javascript/firefly/transactions.js @@ -15,108 +15,5 @@ if ($('input[name="category"]').length > 0) { } $(document).ready(function () { - $('#transactionTable').DataTable( - { - serverSide: true, - ajax: URL, - paging: true, - processing: true, - order: [], - "lengthMenu": [[50, 100, 250, -1], [50, 100, 250, "All"]], - columns: [ - { - name: 'date', - data: 'date', - searchable: false - }, - { - name: 'description', - data: 'description', - render: function (data, type, full, meta) { - var icon = ''; - if (display == 'expenses') { - icon = 'glyphicon-arrow-left'; - } - if (display == 'revenue') { - icon = 'glyphicon-arrow-right'; - } - if (display == 'transfers') { - icon = 'glyphicon-resize-full'; - } - return ' ' + - '' + data.description + ''; - } - }, - { - name: 'amount', - data: 'amount', - 'title': 'Amount (\u20AC)', - searchable: false, - render: function (data, type, full, meta) { - if (display == 'expenses') { - return '\u20AC ' + data.toFixed(2) + ''; - } - if (display == 'revenue') { - return '\u20AC ' + data.toFixed(2) + ''; - } - if (display == 'transfers') { - return '\u20AC ' + data.toFixed(2) + ''; - } - } - }, - { - name: 'from', - data: 'from', - searchable: false, - render: function (data, type, full, meta) { - return '' + data.name + ''; - } - }, - { - name: 'to', - data: 'to', - searchable: false, - render: function (data, type, full, meta) { - return '' + data.name + ''; - } - }, - { - name: 'components', - data: 'components', - searchable: true, - sortable: false, - title: '', - render: function (data, type, full, meta) { - var html = ''; - if (data.budget_id > 0) { - html += ' '; - } - if (data.category_id > 0) { - html += ' '; - } - if(data.recurring_id > 0) { - html += ' '; - } - return html; - } - }, - { - name: 'id', - data: 'id', - searchable: false, - sortable: false, - title: '', - render: function (data, type, full, meta) { - return ''; - } - } - ] - } - ); }); \ No newline at end of file From 0a627f6f9e24df21346763835e540b5a59e9eef0 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Wed, 12 Nov 2014 15:22:01 +0100 Subject: [PATCH 012/193] More work done for the transaction controller. --- app/controllers/GoogleTableController.php | 102 ++++++++++++++++++ app/controllers/TransactionController.php | 71 ++++++------ .../Database/TransactionJournal.php | 32 ++++++ app/routes.php | 1 + app/views/transactions/index.blade.php | 10 +- .../assets/javascript/firefly/transactions.js | 4 +- 6 files changed, 184 insertions(+), 36 deletions(-) diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php index 555440e380..2480dd786c 100644 --- a/app/controllers/GoogleTableController.php +++ b/app/controllers/GoogleTableController.php @@ -216,6 +216,107 @@ class GoogleTableController extends BaseController return Response::json($chart->getData()); } + /** + * @param $what + * + * @return \Illuminate\Http\JsonResponse + */ + public function transactionsList($what) + { + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('ID', 'number'); + $chart->addColumn('ID_Edit', 'string'); + $chart->addColumn('ID_Delete', 'string'); + $chart->addColumn('Date', 'date'); + $chart->addColumn('Description_URL', 'string'); + $chart->addColumn('Description', 'string'); + $chart->addColumn('Amount', 'number'); + $chart->addColumn('From_URL', 'string'); + $chart->addColumn('From', 'string'); + $chart->addColumn('To_URL', 'string'); + $chart->addColumn('To', 'string'); + $chart->addColumn('Budget_URL', 'string'); + $chart->addColumn('Budget', 'string'); + $chart->addColumn('Category_URL', 'string'); + $chart->addColumn('Category', 'string'); + + /** @var \FireflyIII\Database\TransactionJournal $repository */ + $repository = App::make('FireflyIII\Database\TransactionJournal'); + + switch ($what) { + case 'expenses': + case 'withdrawal': + $list = $repository->getWithdrawals(); + break; + case 'revenue': + case 'deposit': + $list = $repository->getDeposits(); + break; + case 'transfer': + case 'transfers': + $list = $repository->getTransfers(); + break; + } + + /** @var Transaction $transaction */ + foreach ($list as $transaction) { + $date = $transaction->transactionJournal->date; + $descriptionURL = route('transactions.show', $transaction->transaction_journal_id); + $description = $transaction->transactionJournal->description; + $amount = floatval($transaction->amount); + + if ($transaction->transactionJournal->transactions[0]->account->id == $account->id) { + $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[1]->account->id); + $opposingAccountName = $transaction->transactionJournal->transactions[1]->account->name; + } else { + $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[0]->account->id); + $opposingAccountName = $transaction->transactionJournal->transactions[0]->account->name; + } + if (isset($transaction->transactionJournal->budgets[0])) { + $budgetURL = route('budgets.show', $transaction->transactionJournal->budgets[0]->id); + $budget = $transaction->transactionJournal->budgets[0]->name; + } else { + $budgetURL = ''; + $budget = ''; + } + + if (isset($transaction->transactionJournal->categories[0])) { + $categoryURL = route('categories.show', $transaction->transactionJournal->categories[0]->id); + $category = $transaction->transactionJournal->categories[0]->name; + } else { + $categoryURL = ''; + $category = ''; + } + + + if ($amount < 0) { + $from = $account->name; + $fromURL = route('accounts.show', $account->id); + + $to = $opposingAccountName; + $toURL = $opposingAccountURI; + } else { + $to = $account->name; + $toURL = route('accounts.show', $account->id); + + $from = $opposingAccountName; + $fromURL = $opposingAccountURI; + } + + $id = $transaction->transactionJournal->id; + $edit = route('transactions.edit', $transaction->transactionJournal->id); + $delete = route('transactions.delete', $transaction->transactionJournal->id); + $chart->addRow( + $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $budget, $categoryURL, $category + ); + } + + + $chart->generate(); + return Response::json($chart->getData()); + } + /** * @param Account $account */ @@ -239,6 +340,7 @@ class GoogleTableController extends BaseController $chart->addColumn('Category_URL', 'string'); $chart->addColumn('Category', 'string'); + /* * Find transactions: */ diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 26154381ed..58a205af53 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -12,6 +12,7 @@ use Illuminate\Support\MessageBag; class TransactionController extends BaseController { + /** * Construct a new transaction controller with two of the most often used helpers. * @@ -22,6 +23,36 @@ class TransactionController extends BaseController View::share('mainTitleIcon', 'fa-repeat'); } + /** + * @param $what + * + * @return $this + */ + public function index($what) + { + + switch ($what) { + case 'expenses': + case 'withdrawal': + $subTitleIcon = 'fa-long-arrow-left'; + $subTitle = 'Expenses'; + break; + case 'revenue': + case 'deposit': + $subTitleIcon = 'fa-long-arrow-right'; + $subTitle = 'Revenue, income and deposits'; + break; + case 'transfer': + case 'transfers': + $subTitleIcon = 'fa-arrows-h'; + $subTitle = 'Transfers'; + break; + } + + return View::make('transactions.index', compact('subTitle', 'subTitleIcon'))->with('what', $what); + + } + /** * Shows the view helping the user to create a new transaction journal. * @@ -46,7 +77,7 @@ class TransactionController extends BaseController /** @var \FireflyIII\Database\Piggybank $piggyRepository */ $piggyRepository = App::make('FireflyIII\Database\Piggybank'); - // get asset accounts with names and id's. + // get asset accounts with names and id's . $assetAccounts = $form->makeSelectList($accountRepository->getAssetAccounts()); // get budgets as a select list. @@ -222,33 +253,14 @@ class TransactionController extends BaseController ); } - /** - * @return $this - */ - public function expenses() - { - return View::make('transactions.list')->with('subTitle', 'Expenses')->with( - 'subTitleIcon', 'fa-long-arrow-left' - )->with('what', 'expenses'); - } - - /** - * @return $this - */ - public function revenue() - { - return View::make('transactions.list')->with('subTitle', 'Revenue')->with( - 'subTitleIcon', 'fa-long-arrow-right' - )->with('what', 'revenue'); - } - /** * @param TransactionJournal $journal * * @return $this */ - public function show(TransactionJournal $journal) - { + public function show( + TransactionJournal $journal + ) { return View::make('transactions.show')->with('journal', $journal)->with( 'subTitle', $journal->transactionType->type . ' "' . $journal->description . '"' ); @@ -260,8 +272,7 @@ class TransactionController extends BaseController * @return $this|\Illuminate\Http\RedirectResponse * @throws FireflyException */ - public function store($what) - { + public function store($what) { throw new NotImplementedException; /* * Collect data to process: @@ -314,19 +325,13 @@ class TransactionController extends BaseController } } - public function index($what) - { - return View::make('transactions.index')->with('subTitle', 'Bla bla')->with('subTitleIcon', 'fa-arrows-h')->with('what', $what); - - } /** * @param TransactionJournal $journal * * @throws FireflyException */ - public function update(TransactionJournal $journal) - { + public function update(TransactionJournal $journal) { throw new NotImplementedException; switch (Input::get('post_submit_action')) { case 'update': @@ -370,4 +375,4 @@ class TransactionController extends BaseController } -} \ No newline at end of file +} \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 8f26645ade..57639de92f 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -327,6 +327,38 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData return $this->getUser()->transactionjournals()->get(); } + /** + * Some objects. + * + * @return Collection + */ + public function getTransfers() + { + return $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Transfer'])->get(['transaction_journals.*']); + } + + /** + * Some objects. + * + * @return Collection + */ + public function getDeposits() + { + return $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Deposit'])->get(['transaction_journals.*']); + } + + /** + * Some objects. + * + * @return Collection + */ + public function getWithdrawals() + { + return $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Withdrawal'])->get(['transaction_journals.*']); + } + + + /** * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. * diff --git a/app/routes.php b/app/routes.php index 983c2f318d..eb112edd04 100644 --- a/app/routes.php +++ b/app/routes.php @@ -164,6 +164,7 @@ Route::group( Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']); Route::get('/table/categories', ['uses' => 'GoogleTableController@categoryList']); Route::get('/table/recurring', ['uses' => 'GoogleTableController@recurringList']); + Route::get('/table/transactions/{what}', ['uses' => 'GoogleTableController@transactionsList'])->where(['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers']); // google table for components (categories + budgets) Route::get('/table/component/{component}/{limitrepetition}/transactions', ['uses' => 'GoogleTableController@transactionsByComponent']); diff --git a/app/views/transactions/index.blade.php b/app/views/transactions/index.blade.php index f96f23b171..d01b0bb15d 100644 --- a/app/views/transactions/index.blade.php +++ b/app/views/transactions/index.blade.php @@ -7,7 +7,7 @@ {{{$subTitle}}}
-
+
+ +{{HTML::script('assets/javascript/firefly/gcharts.options.js')}} +{{HTML::script('assets/javascript/firefly/gcharts.js')}} + + {{HTML::script('assets/javascript/firefly/transactions.js')}} @stop \ No newline at end of file diff --git a/public/assets/javascript/firefly/transactions.js b/public/assets/javascript/firefly/transactions.js index 39bb0507ec..7f65416544 100644 --- a/public/assets/javascript/firefly/transactions.js +++ b/public/assets/javascript/firefly/transactions.js @@ -15,5 +15,7 @@ if ($('input[name="category"]').length > 0) { } $(document).ready(function () { - + if(typeof googleTable != 'undefined') { + googleTable('table/transactions/' + what,'transaction-table'); + } }); \ No newline at end of file From 7f175a4870bf87194592091836742721be0bac79 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Wed, 12 Nov 2014 15:34:32 +0100 Subject: [PATCH 013/193] Some more work on the transactions. --- app/controllers/TransactionController.php | 53 +++++++++++++++++-- .../Database/TransactionJournal.php | 11 ++-- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 58a205af53..43147f8b06 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -100,9 +100,8 @@ class TransactionController extends BaseController } Session::put('prefilled', $prefilled); - return View::make('transactions.create')->with('accounts', $assetAccounts)->with('budgets', $budgets)->with( - 'what', $what - )->with('piggies', $piggies)->with('subTitle', 'Add a new ' . $what); + return View::make('transactions.create')->with('accounts', $assetAccounts)->with('budgets', $budgets)->with('what', $what)->with('piggies', $piggies) + ->with('subTitle', 'Add a new ' . $what); } /** @@ -272,7 +271,50 @@ class TransactionController extends BaseController * @return $this|\Illuminate\Http\RedirectResponse * @throws FireflyException */ - public function store($what) { + public function store($what) + { + $data = Input::except('_token'); + $data['what'] = $what; + $data['currency'] = 'EUR'; + + /** @var \FireflyIII\Database\TransactionJournal $repository */ + $repository = App::make('FireflyIII\Database\TransactionJournal'); + + switch ($data['post_submit_action']) { + default: + throw new FireflyException('Cannot handle post_submit_action "' . e($data['post_submit_action']) . '"'); + break; + case 'create_another': + case 'store': + $messages = $repository->validate($data); + /** @var MessageBag $messages ['errors'] */ + if ($messages['errors']->count() > 0) { + Session::flash('warnings', $messages['warnings']); + Session::flash('successes', $messages['successes']); + Session::flash('error', 'Could not save transaction: ' . $messages['errors']->first()); + return Redirect::route('transactions.create', $what)->withInput()->withErrors($messages['errors']); + } + // store! + $repository->store($data); + Session::flash('success', 'New transaction stored!'); + + if ($data['post_submit_action'] == 'create_another') { + return Redirect::route('transactions.create', $what); + } else { + return Redirect::route('transactions.index'); + } + break; + case 'validate_only': + $messageBags = $repository->validate($data); + Session::flash('warnings', $messageBags['warnings']); + Session::flash('successes', $messageBags['successes']); + Session::flash('errors', $messageBags['errors']); + + return Redirect::route('transactions.create')->withInput(); + break; + } + + throw new NotImplementedException; /* * Collect data to process: @@ -331,7 +373,8 @@ class TransactionController extends BaseController * * @throws FireflyException */ - public function update(TransactionJournal $journal) { + public function update(TransactionJournal $journal) + { throw new NotImplementedException; switch (Input::get('post_submit_action')) { case 'update': diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 57639de92f..743d4d0ce5 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -191,11 +191,16 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $errors->add('date', 'This date is invalid.'); } - if (isset($model['to_id']) && intval($model['to_id']) < 0) { + if (isset($model['to_id']) && intval($model['to_id']) < 1) { $errors->add('account_to', 'Invalid to-account'); } - if (isset($model['from_id']) && intval($model['from_id']) < 0) { + + if (isset($model['from_id']) && intval($model['from_id']) < 1) { $errors->add('account_from', 'Invalid from-account'); + + } + if (isset($model['account_id']) && intval($model['account_id']) < 1) { + $errors->add('account_id', 'Invalid account!'); } if (isset($model['to']) && !($model['to'] instanceof \Account)) { $errors->add('account_to', 'Invalid to-account'); @@ -208,6 +213,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData } if (!isset($model['from']) && !isset($model['to'])) { $errors->add('account_to', 'No accounts found!'); + $errors->add('account_id', 'No accounts found!'); } $validator = \Validator::make([$model], \Transaction::$rules); @@ -358,7 +364,6 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData } - /** * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. * From 4e166c7d2ee4b55cd7b44202da96ebd1fc743fef Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 12 Nov 2014 20:46:55 +0100 Subject: [PATCH 014/193] This should fix the transactions again. --- app/controllers/TransactionController.php | 2 +- .../Database/TransactionJournal.php | 174 ++++++++++++------ 2 files changed, 122 insertions(+), 54 deletions(-) diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 43147f8b06..1f6bb3008a 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -310,7 +310,7 @@ class TransactionController extends BaseController Session::flash('successes', $messageBags['successes']); Session::flash('errors', $messageBags['errors']); - return Redirect::route('transactions.create')->withInput(); + return Redirect::route('transactions.create',$what)->withInput(); break; } diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 743d4d0ce5..b97de82083 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -5,13 +5,12 @@ namespace FireflyIII\Database; use Carbon\Carbon; use Firefly\Exception\FireflyException; -use FireflyIII\Exception\NotImplementedException; -use Illuminate\Support\Collection; -use Illuminate\Support\MessageBag; -use LaravelBook\Ardent\Ardent; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\TransactionJournalInterface; +use Illuminate\Support\Collection; +use Illuminate\Support\MessageBag; +use LaravelBook\Ardent\Ardent; /** * Class TransactionJournal @@ -42,12 +41,12 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $end->endOfMonth(); $sum = \DB::table('transactions') - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') - ->where('amount', '>', 0) - ->where('transaction_types.type', '=', 'Deposit') - ->where('transaction_journals.date', '>=', $date->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount'); + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') + ->where('amount', '>', 0) + ->where('transaction_types.type', '=', 'Deposit') + ->where('transaction_journals.date', '>=', $date->format('Y-m-d')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount'); $sum = floatval($sum); return $sum; } @@ -64,12 +63,12 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $end->endOfMonth(); $sum = \DB::table('transactions') - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') - ->where('amount', '>', 0) - ->where('transaction_types.type', '=', 'Withdrawal') - ->where('transaction_journals.date', '>=', $date->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount'); + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') + ->where('amount', '>', 0) + ->where('transaction_types.type', '=', 'Withdrawal') + ->where('transaction_journals.date', '>=', $date->format('Y-m-d')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount'); $sum = floatval($sum); return $sum; } @@ -87,9 +86,9 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData /** * @param \Account $account - * @param int $count - * @param Carbon $start - * @param Carbon $end + * @param int $count + * @param Carbon $start + * @param Carbon $end * * @return Collection */ @@ -97,7 +96,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData { $accountID = $account->id; - $query = $this->_user + $query = $this->_user ->transactionjournals() ->with(['transactions', 'transactioncurrency', 'transactiontype']) ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') @@ -156,9 +155,9 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; if (!isset($model['what'])) { @@ -191,30 +190,99 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $errors->add('date', 'This date is invalid.'); } - if (isset($model['to_id']) && intval($model['to_id']) < 1) { - $errors->add('account_to', 'Invalid to-account'); + /* + * Amount: + */ + if (isset($model['amount']) && floatval($model['amount']) < 0.01) { + $errors->add('amount', 'Amount must be > 0.01'); + } else if (!isset($model['amount'])) { + $errors->add('amount', 'Amount must be set!'); + } else { + $successes->add('amount', 'OK'); } - if (isset($model['from_id']) && intval($model['from_id']) < 1) { - $errors->add('account_from', 'Invalid from-account'); + /* + * Budget: + */ + if (isset($model['budget_id']) && !ctype_digit($model['budget_id'])) { + $errors->add('budget_id', 'Invalid budget'); + } else { + $successes->add('budget_id', 'OK'); + } + $successes->add('category', 'OK'); + + /* + * Many checks to catch invalid or not-existing accounts. + */ + $accountError = false; + switch (true) { + // this combination is often seen in withdrawals. + case (isset($model['account_id']) && isset($model['expense_account'])): + if (intval($model['account_id']) < 1) { + $errors->add('account_id', 'Invalid account.'); + } else { + $successes->add('account_id', 'OK'); + } + $successes->add('expense_account', 'OK'); + break; + case (isset($model['account_id']) && isset($model['revenue_account'])): + if (intval($model['account_id']) < 1) { + $errors->add('account_id', 'Invalid account.'); + } else { + $successes->add('account_id', 'OK'); + } + $successes->add('revenue_account', 'OK'); + break; + case (isset($model['account_from_id']) && isset($model['account_to_id'])): + if (intval($model['account_from_id']) < 1 || intval($model['account_from_id']) < 1) { + $errors->add('account_from_id', 'Invalid account selected.'); + $errors->add('account_to_id', 'Invalid account selected.'); + + } else { + if (intval($model['account_from_id']) == intval($model['account_from_id'])) { + $errors->add('account_to_id', 'Cannot be the same as "from" account.'); + $errors->add('account_from_id', 'Cannot be the same as "to" account.'); + } else { + $successes->add('account_from_id', 'OK'); + $successes->add('account_to_id', 'OK'); + } + } + break; + + case (isset($model['to']) && isset($model['from'])): + if (is_object($model['to']) && is_object($model['from'])) { + $successes->add('from', 'OK'); + $successes->add('to', 'OK'); + } + break; + + default: + throw new FireflyException('Cannot validate accounts for transaction journal.'); + break; } - if (isset($model['account_id']) && intval($model['account_id']) < 1) { - $errors->add('account_id', 'Invalid account!'); - } - if (isset($model['to']) && !($model['to'] instanceof \Account)) { - $errors->add('account_to', 'Invalid to-account'); - } - if (isset($model['from']) && !($model['from'] instanceof \Account)) { - $errors->add('account_from', 'Invalid from-account'); - } - if (!isset($model['amount']) || (isset($model['amount']) && floatval($model['amount']) < 0)) { - $errors->add('amount', 'Invalid amount'); - } - if (!isset($model['from']) && !isset($model['to'])) { - $errors->add('account_to', 'No accounts found!'); - $errors->add('account_id', 'No accounts found!'); - } + +// if (isset($model['to_id']) && intval($model['to_id']) < 1) { +// $errors->add('account_to', 'Invalid to-account'); +// } +// +// if (isset($model['from_id']) && intval($model['from_id']) < 1) { +// $errors->add('account_from', 'Invalid from-account'); +// +// } +// if (isset($model['account_id']) && intval($model['account_id']) < 1) { +// $errors->add('account_id', 'Invalid account!'); +// } +// if (isset($model['to']) && !($model['to'] instanceof \Account)) { +// $errors->add('account_to', 'Invalid to-account'); +// } +// if (isset($model['from']) && !($model['from'] instanceof \Account)) { +// $errors->add('account_from', 'Invalid from-account'); +// } +// if (!isset($model['amount']) || (isset($model['amount']) && floatval($model['amount']) < 0)) { +// $errors->add('amount', 'Invalid amount'); +// } + $validator = \Validator::make([$model], \Transaction::$rules); if ($validator->invalid()) { @@ -232,8 +300,8 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $successes->add('date', 'OK'); } return [ - 'errors' => $errors, - 'warnings' => $warnings, + 'errors' => $errors, + 'warnings' => $warnings, 'successes' => $successes ]; @@ -258,15 +326,15 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $transactionRepository = \App::make('FireflyIII\Database\Transaction'); $journalType = $typeRepository->findByWhat($data['what']); - $currency = $currencyRepository->findByCode($data['currency']); + $currency = $currencyRepository->findByCode($data['currency']); $journal = new \TransactionJournal; $journal->transactionType()->associate($journalType); $journal->transactionCurrency()->associate($currency); $journal->user()->associate($this->getUser()); $journal->description = $data['description']; - $journal->date = $data['date']; - $journal->completed = 0; + $journal->date = $data['date']; + $journal->completed = 0; //$journal->user_id = $this->getUser()->id; /* @@ -281,10 +349,10 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData /* * Then store both transactions. */ - $first = [ - 'account' => $data['from'], + $first = [ + 'account' => $data['from'], 'transaction_journal' => $journal, - 'amount' => ($data['amount'] * -1), + 'amount' => ($data['amount'] * -1), ]; $validate = $transactionRepository->validate($first); if ($validate['errors']->count() == 0) { @@ -294,9 +362,9 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData } $second = [ - 'account' => $data['to'], + 'account' => $data['to'], 'transaction_journal' => $journal, - 'amount' => floatval($data['amount']), + 'amount' => floatval($data['amount']), ]; $validate = $transactionRepository->validate($second); @@ -388,7 +456,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData /** * @param Ardent $model - * @param array $data + * @param array $data * * @return bool */ From ab508a3d9ea4f8f77b4b0b05774975c37d05a1fb Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 12 Nov 2014 20:52:34 +0100 Subject: [PATCH 015/193] Recreated the JSON controller to fix auto-complete forms. --- app/controllers/JsonController.php | 65 ++++++++++++++++++++++++++++++ app/routes.php | 6 +++ 2 files changed, 71 insertions(+) create mode 100644 app/controllers/JsonController.php diff --git a/app/controllers/JsonController.php b/app/controllers/JsonController.php new file mode 100644 index 0000000000..3dbe758b39 --- /dev/null +++ b/app/controllers/JsonController.php @@ -0,0 +1,65 @@ +get(); + $return = []; + foreach ($list as $entry) { + $return[] = $entry->name; + } + + return Response::json($return); + + + } + + /** + * Returns a JSON list of all beneficiaries. + * + * @return \Illuminate\Http\JsonResponse + */ + public function expenseAccounts() + { + /** @var \FireflyIII\Database\Account $accounts */ + $accounts = App::make('FireflyIII\Database\Account'); + $list = $accounts->getExpenseAccounts(); + $return = []; + foreach ($list as $entry) { + $return[] = $entry->name; + } + + return Response::json($return); + + } + + /** + * @return \Illuminate\Http\JsonResponse + */ + public function revenueAccounts() + { + /** @var \FireflyIII\Database\Account $accounts */ + $accounts = App::make('FireflyIII\Database\Account'); + $list = $accounts->getRevenueAccounts(); + $return = []; + foreach ($list as $entry) { + $return[] = $entry->name; + } + + return Response::json($return); + + } +} \ No newline at end of file diff --git a/app/routes.php b/app/routes.php index eb112edd04..81fa459a25 100644 --- a/app/routes.php +++ b/app/routes.php @@ -174,6 +174,12 @@ Route::group( Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']); Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); # even though nothing is cached. + // JSON controller + Route::get('/json/expense-accounts', ['uses' => 'JsonController@expenseAccounts', 'as' => 'json.expense-accounts']); + Route::get('/json/revenue-accounts', ['uses' => 'JsonController@revenueAccounts', 'as' => 'json.revenue-accounts']); + Route::get('/json/categories', ['uses' => 'JsonController@categories', 'as' => 'json.categories']); + + // piggy bank controller Route::get('/piggybanks', ['uses' => 'PiggybankController@index', 'as' => 'piggybanks.index']); Route::get('/piggybanks/add/{piggybank}', ['uses' => 'PiggybankController@add']); # add money From 44d189d7d336c0c0568b947c14ad9f3c19438924 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 12 Nov 2014 21:19:31 +0100 Subject: [PATCH 016/193] Fixed a bug where the transaction list was a giant mess. --- app/controllers/GoogleTableController.php | 139 +++++++++--------- app/controllers/TransactionController.php | 2 +- app/lib/FireflyIII/Database/Account.php | 139 ++++++++++-------- .../Database/TransactionJournal.php | 25 +++- .../FireflyIII/Database/TransactionType.php | 14 +- 5 files changed, 180 insertions(+), 139 deletions(-) diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php index 2480dd786c..a3a26d673e 100644 --- a/app/controllers/GoogleTableController.php +++ b/app/controllers/GoogleTableController.php @@ -1,5 +1,4 @@ id); + $edit = route('accounts.edit', $entry->id); $delete = route('accounts.delete', $entry->id); - $show = route('accounts.show', $entry->id); + $show = route('accounts.show', $entry->id); $chart->addRow($entry->id, $edit, $delete, $show, $entry->name, $entry->balance()); } @@ -90,7 +89,7 @@ class GoogleTableController extends BaseController } /** - * @param Component $component + * @param Component $component * @param LimitRepetition $repetition */ public function transactionsByComponent(Component $component, LimitRepetition $repetition = null) @@ -115,26 +114,26 @@ class GoogleTableController extends BaseController if (is_null($repetition)) { $journals = $component->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->orderBy('date', 'DESC') - ->get(); + ->get(); } else { $journals = $component->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->after( $repetition->startdate ) - ->before($repetition->enddate)->orderBy('date', 'DESC')->get(); + ->before($repetition->enddate)->orderBy('date', 'DESC')->get(); } /** @var TransactionJournal $transaction */ foreach ($journals as $journal) { - $date = $journal->date; + $date = $journal->date; $descriptionURL = route('transactions.show', $journal->id); - $description = $journal->description; + $description = $journal->description; /** @var Transaction $transaction */ foreach ($journal->transactions as $transaction) { if (floatval($transaction->amount) > 0) { $amount = floatval($transaction->amount); - $to = $transaction->account->name; - $toURL = route('accounts.show', $transaction->account->id); + $to = $transaction->account->name; + $toURL = route('accounts.show', $transaction->account->id); } else { - $from = $transaction->account->name; + $from = $transaction->account->name; $fromURL = route('accounts.show', $transaction->account->id); } @@ -149,15 +148,15 @@ class GoogleTableController extends BaseController if (isset($journal->categories[0])) { $categoryURL = route('categories.show', $journal->categories[0]->id); - $category = $journal->categories[0]->name; + $category = $journal->categories[0]->name; } else { $categoryURL = ''; - $category = ''; + $category = ''; } - $id = $journal->id; - $edit = route('transactions.edit', $journal->id); + $id = $journal->id; + $edit = route('transactions.edit', $journal->id); $delete = route('transactions.delete', $journal->id); $chart->addRow( $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $component, $categoryURL, @@ -232,6 +231,7 @@ class GoogleTableController extends BaseController $chart->addColumn('Description_URL', 'string'); $chart->addColumn('Description', 'string'); $chart->addColumn('Amount', 'number'); + $chart->addColumn('From_URL', 'string'); $chart->addColumn('From', 'string'); $chart->addColumn('To_URL', 'string'); @@ -259,56 +259,53 @@ class GoogleTableController extends BaseController break; } - /** @var Transaction $transaction */ - foreach ($list as $transaction) { - $date = $transaction->transactionJournal->date; - $descriptionURL = route('transactions.show', $transaction->transaction_journal_id); - $description = $transaction->transactionJournal->description; - $amount = floatval($transaction->amount); + /** @var TransactionJournal $journal */ + foreach ($list as $journal) { + $date = $journal->date; + $descriptionURL = route('transactions.show', $journal->id); + $description = $journal->description; + $amount = floatval(-0.01); // TODO + $id = $journal->id; + + + if ($journal->transactions[0]->amount < 0) { + + $fromURL = route('accounts.show', $journal->transactions[0]->account->id); + $fromName = $journal->transactions[0]->account->name; + $amount = floatval($journal->transactions[0]->amount); + + $toURL = route('accounts.show', $journal->transactions[1]->account->id); + $toName = $journal->transactions[1]->account->name; - if ($transaction->transactionJournal->transactions[0]->account->id == $account->id) { - $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[1]->account->id); - $opposingAccountName = $transaction->transactionJournal->transactions[1]->account->name; } else { - $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[0]->account->id); - $opposingAccountName = $transaction->transactionJournal->transactions[0]->account->name; + $fromURL = route('accounts.show', $journal->transactions[1]->account->id); + $fromName = $journal->transactions[1]->account->name; + $amount = floatval($journal->transactions[1]->amount); + + $toURL = route('accounts.show', $journal->transactions[0]->account->id); + $toName = $journal->transactions[0]->account->name; } - if (isset($transaction->transactionJournal->budgets[0])) { - $budgetURL = route('budgets.show', $transaction->transactionJournal->budgets[0]->id); - $budget = $transaction->transactionJournal->budgets[0]->name; + if (isset($journal->budgets[0])) { + $budgetURL = route('budgets.show', $journal->budgets[0]->id); + $budget = $journal->budgets[0]->name; } else { $budgetURL = ''; - $budget = ''; + $budget = ''; } - if (isset($transaction->transactionJournal->categories[0])) { - $categoryURL = route('categories.show', $transaction->transactionJournal->categories[0]->id); - $category = $transaction->transactionJournal->categories[0]->name; + if (isset($journal->categories[0])) { + $categoryURL = route('categories.show', $journal->categories[0]->id); + $category = $journal->categories[0]->name; } else { $categoryURL = ''; - $category = ''; + $category = ''; } - - - if ($amount < 0) { - $from = $account->name; - $fromURL = route('accounts.show', $account->id); - - $to = $opposingAccountName; - $toURL = $opposingAccountURI; - } else { - $to = $account->name; - $toURL = route('accounts.show', $account->id); - - $from = $opposingAccountName; - $fromURL = $opposingAccountURI; - } - - $id = $transaction->transactionJournal->id; - $edit = route('transactions.edit', $transaction->transactionJournal->id); - $delete = route('transactions.delete', $transaction->transactionJournal->id); + $edit = route('transactions.edit', $journal->id); + $delete = route('transactions.delete', $journal->id); $chart->addRow( - $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $budget, $categoryURL, $category + $id, $edit, $delete, $date, $descriptionURL, $description, $amount, + $fromURL, $fromName, $toURL, $toName, + $budgetURL, $budget, $categoryURL, $category ); } @@ -344,63 +341,63 @@ class GoogleTableController extends BaseController /* * Find transactions: */ - $accountID = $account->id; + $accountID = $account->id; $transactions = $account->transactions()->with( ['transactionjournal', 'transactionjournal.transactions' => function ($q) use ($accountID) { $q->where('account_id', '!=', $accountID); }, 'transactionjournal.budgets', 'transactionjournal.transactiontype', - 'transactionjournal.categories'] + 'transactionjournal.categories'] )->before(Session::get('end'))->after( Session::get('start') )->orderBy('date', 'DESC')->get(); /** @var Transaction $transaction */ foreach ($transactions as $transaction) { - $date = $transaction->transactionJournal->date; + $date = $transaction->transactionJournal->date; $descriptionURL = route('transactions.show', $transaction->transaction_journal_id); - $description = $transaction->transactionJournal->description; - $amount = floatval($transaction->amount); + $description = $transaction->transactionJournal->description; + $amount = floatval($transaction->amount); if ($transaction->transactionJournal->transactions[0]->account->id == $account->id) { - $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[1]->account->id); + $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[1]->account->id); $opposingAccountName = $transaction->transactionJournal->transactions[1]->account->name; } else { - $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[0]->account->id); + $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[0]->account->id); $opposingAccountName = $transaction->transactionJournal->transactions[0]->account->name; } if (isset($transaction->transactionJournal->budgets[0])) { $budgetURL = route('budgets.show', $transaction->transactionJournal->budgets[0]->id); - $budget = $transaction->transactionJournal->budgets[0]->name; + $budget = $transaction->transactionJournal->budgets[0]->name; } else { $budgetURL = ''; - $budget = ''; + $budget = ''; } if (isset($transaction->transactionJournal->categories[0])) { $categoryURL = route('categories.show', $transaction->transactionJournal->categories[0]->id); - $category = $transaction->transactionJournal->categories[0]->name; + $category = $transaction->transactionJournal->categories[0]->name; } else { $categoryURL = ''; - $category = ''; + $category = ''; } if ($amount < 0) { - $from = $account->name; + $from = $account->name; $fromURL = route('accounts.show', $account->id); - $to = $opposingAccountName; + $to = $opposingAccountName; $toURL = $opposingAccountURI; } else { - $to = $account->name; + $to = $account->name; $toURL = route('accounts.show', $account->id); - $from = $opposingAccountName; + $from = $opposingAccountName; $fromURL = $opposingAccountURI; } - $id = $transaction->transactionJournal->id; - $edit = route('transactions.edit', $transaction->transactionJournal->id); + $id = $transaction->transactionJournal->id; + $edit = route('transactions.edit', $transaction->transactionJournal->id); $delete = route('transactions.delete', $transaction->transactionJournal->id); $chart->addRow( $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $budget, $categoryURL, $category diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 1f6bb3008a..32af9b1acc 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -301,7 +301,7 @@ class TransactionController extends BaseController if ($data['post_submit_action'] == 'create_another') { return Redirect::route('transactions.create', $what); } else { - return Redirect::route('transactions.index'); + return Redirect::route('transactions.index',$what); } break; case 'validate_only': diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index 60726af53c..015ed63cf1 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -6,9 +6,9 @@ use Carbon\Carbon; use FireflyIII\Database\Ifaces\AccountInterface; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; +use Illuminate\Support\Collection; use Illuminate\Support\MessageBag; use LaravelBook\Ardent\Ardent; -use Illuminate\Support\Collection; /** * Class Account @@ -29,13 +29,13 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface /** * @param Ardent $model - * @param array $data + * @param array $data * * @return bool */ public function update(Ardent $model, array $data) { - $model->name = $data['name']; + $model->name = $data['name']; $model->active = isset($data['active']) ? intval($data['active']) : 0; $model->save(); @@ -58,6 +58,23 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface return true; } + /** + * @param \Account $account + * + * @return \TransactionJournal|null + */ + public function openingBalanceTransaction(\Account $account) + { + return \TransactionJournal::withRelevantData() + ->accountIs($account) + ->leftJoin( + 'transaction_types', 'transaction_types.id', '=', + 'transaction_journals.transaction_type_id' + ) + ->where('transaction_types.type', 'Opening balance') + ->first(['transaction_journals.*']); + } + /** * Get all asset accounts. Optional JSON based parameters. * @@ -71,21 +88,6 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } - /** - * @param \Account $account - * - * @return \Account|null - */ - public function findInitialBalanceAccount(\Account $account) - { - /** @var \FireflyIII\Database\AccountType $acctType */ - $acctType = \App::make('FireflyIII\Database\AccountType'); - - $accountType = $acctType->findByWhat('initial'); - - return $this->getUser()->accounts()->where('account_type_id', $accountType->id)->where('name', 'LIKE', $account->name . '%')->first(); - } - /** * @param array $types * @param array $parameters @@ -146,19 +148,26 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } /** - * @return int + * @param \Account $account + * + * @return \Account|null */ - public function countAssetAccounts() + public function findInitialBalanceAccount(\Account $account) { - return $this->countAccountsByType(['Default account', 'Asset account']); + /** @var \FireflyIII\Database\AccountType $acctType */ + $acctType = \App::make('FireflyIII\Database\AccountType'); + + $accountType = $acctType->findByWhat('initial'); + + return $this->getUser()->accounts()->where('account_type_id', $accountType->id)->where('name', 'LIKE', $account->name . '%')->first(); } /** * @return int */ - public function countExpenseAccounts() + public function countAssetAccounts() { - return $this->countAccountsByType(['Expense account', 'Beneficiary account']); + return $this->countAccountsByType(['Default account', 'Asset account']); } /** @@ -171,6 +180,14 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface return $this->getUser()->accounts()->accountTypeIn($types)->count(); } + /** + * @return int + */ + public function countExpenseAccounts() + { + return $this->countAccountsByType(['Expense account', 'Beneficiary account']); + } + /** * @param array $parameters * @@ -200,7 +217,24 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface */ public function find($id) { - // TODO: Implement find() method. + return $this->getUser()->accounts()->find($id); + } + + public function firstExpenseAccountOrCreate($name) + { + /** @var \FireflyIII\Database\AccountType $accountTypeRepos */ + $accountTypeRepos = \App::make('FireflyIII\Database\AccountType'); + + $accountType = $accountTypeRepos->findByWhat('expense'); + + $data = [ + 'user_id' => $this->getUser()->id, + 'account_type_id' => $accountType->id, + 'name' => $name, + 'active' => 1 + ]; + return \Account::firstOrCreate($data); + } /** @@ -247,23 +281,6 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } - /** - * @param \Account $account - * - * @return \TransactionJournal|null - */ - public function openingBalanceTransaction(\Account $account) - { - return \TransactionJournal::withRelevantData() - ->accountIs($account) - ->leftJoin( - 'transaction_types', 'transaction_types.id', '=', - 'transaction_journals.transaction_type_id' - ) - ->where('transaction_types.type', 'Opening balance') - ->first(['transaction_journals.*']); - } - /** * Validates a model. Returns an array containing MessageBags * errors/warnings/successes. @@ -287,9 +304,9 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface */ public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; /* * Name validation: @@ -343,8 +360,8 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface $successes->add('openingbalancedate', 'OK'); } return [ - 'errors' => $errors, - 'warnings' => $warnings, + 'errors' => $errors, + 'warnings' => $warnings, 'successes' => $successes ]; } @@ -365,12 +382,12 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface $accountType = $acctType->findByWhat($data['what']); - $data['user_id'] = $this->getUser()->id; + $data['user_id'] = $this->getUser()->id; $data['account_type_id'] = $accountType->id; - $data['active'] = isset($data['active']) && $data['active'] === '1' ? 1 : 0; + $data['active'] = isset($data['active']) && $data['active'] === '1' ? 1 : 0; - $data = array_except($data, array('_token', 'what')); + $data = array_except($data, array('_token', 'what')); $account = new \Account($data); if (!$account->validate()) { var_dump($account->errors()->all()); @@ -391,16 +408,16 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface /** * @param \Account $account - * @param array $data + * @param array $data * * @return bool */ public function storeInitialBalance(\Account $account, array $data) { - $opposingData = [ - 'name' => $account->name . ' Initial Balance', + $opposingData = [ + 'name' => $account->name . ' Initial Balance', 'active' => 0, - 'what' => 'initial' + 'what' => 'initial' ]; $opposingAccount = $this->store($opposingData); @@ -408,28 +425,28 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface * Create a journal from opposing to account or vice versa. */ $balance = floatval($data['openingbalance']); - $date = new Carbon($data['openingbalancedate']); + $date = new Carbon($data['openingbalancedate']); /** @var \FireflyIII\Database\TransactionJournal $tj */ $tj = \App::make('FireflyIII\Database\TransactionJournal'); if ($balance < 0) { // first transaction draws money from the new account to the opposing $from = $account; - $to = $opposingAccount; + $to = $opposingAccount; } else { // first transaction puts money into account $from = $opposingAccount; - $to = $account; + $to = $account; } // data for transaction journal: $balance = $balance < 0 ? $balance * -1 : $balance; $opening = [ - 'what' => 'opening', - 'currency' => 'EUR', - 'amount' => $balance, - 'from' => $from, - 'to' => $to, - 'date' => $date, + 'what' => 'opening', + 'currency' => 'EUR', + 'amount' => $balance, + 'from' => $from, + 'to' => $to, + 'date' => $date, 'description' => 'Opening balance for new account ' . $account->name, ]; diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index b97de82083..1603f3386d 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -240,7 +240,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $errors->add('account_to_id', 'Invalid account selected.'); } else { - if (intval($model['account_from_id']) == intval($model['account_from_id'])) { + if (intval($model['account_from_id']) == intval($model['account_to_id'])) { $errors->add('account_to_id', 'Cannot be the same as "from" account.'); $errors->add('account_from_id', 'Cannot be the same as "to" account.'); } else { @@ -319,6 +319,9 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData /** @var \FireflyIII\Database\TransactionType $typeRepository */ $typeRepository = \App::make('FireflyIII\Database\TransactionType'); + /** @var \FireflyIII\Database\Account $accountRepository */ + $accountRepository = \App::make('FireflyIII\Database\Account'); + /** @var \FireflyIII\Database\TransactionCurrency $currencyRepository */ $currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency'); @@ -335,17 +338,33 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $journal->description = $data['description']; $journal->date = $data['date']; $journal->completed = 0; - //$journal->user_id = $this->getUser()->id; /* * This must be enough to store the journal: */ if (!$journal->validate()) { \Log::error($journal->errors()->all()); - throw new FireflyException('store() transactionjournal failed, but it should not!'); + throw new FireflyException('store() transaction journal failed, but it should not!'); } $journal->save(); + /* + * Still need to find the accounts related to the transactions. + * This depends on the type of transaction. + */ + switch ($data['what']) { + case 'withdrawal': + $data['from'] = $accountRepository->find($data['account_id']); + $data['to'] = $accountRepository->firstExpenseAccountOrCreate($data['expense_account']); + break; + case 'opening': + break; + + default: + throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".'); + break; + } + /* * Then store both transactions. */ diff --git a/app/lib/FireflyIII/Database/TransactionType.php b/app/lib/FireflyIII/Database/TransactionType.php index 0022ec36fb..0abf5e9308 100644 --- a/app/lib/FireflyIII/Database/TransactionType.php +++ b/app/lib/FireflyIII/Database/TransactionType.php @@ -3,11 +3,12 @@ namespace FireflyIII\Database; -use Illuminate\Support\Collection; -use LaravelBook\Ardent\Ardent; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\TransactionTypeInterface; +use FireflyIII\Exception\FireflyException; +use Illuminate\Support\Collection; +use LaravelBook\Ardent\Ardent; /** * Class TransactionType @@ -98,10 +99,17 @@ class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCa case 'opening': return \TransactionType::whereType('Opening balance')->first(); break; + case 'transfer': + return \TransactionType::whereType('Transfer')->first(); + break; + case 'withdrawal': + return \TransactionType::whereType('Withdrawal')->first(); + break; default: throw new FireflyException('Cannot find transaction type described as "' . e($what) . '".'); break; + } return null; } @@ -118,7 +126,7 @@ class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCa /** * @param Ardent $model - * @param array $data + * @param array $data * * @return bool */ From 2e2c12d6a421c3a81953072088c597b369bed491 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 12 Nov 2014 22:21:48 +0100 Subject: [PATCH 017/193] General clean up. --- app/controllers/BudgetController.php | 10 +- app/controllers/GoogleTableController.php | 1 - app/controllers/PiggybankController.php | 2 - .../Piggybanks/EloquentPiggybankTrigger.php | 11 -- app/lib/FireflyIII/Database/Account.php | 79 ++++----- app/lib/FireflyIII/Database/AccountType.php | 31 ++-- app/lib/FireflyIII/Database/Budget.php | 138 ++++++++-------- app/lib/FireflyIII/Database/Category.php | 141 ++++++++-------- app/lib/FireflyIII/Database/Piggybank.php | 146 +++++++++-------- app/lib/FireflyIII/Database/Recurring.php | 52 +++--- .../Database/RecurringTransaction.php | 29 ++-- app/lib/FireflyIII/Database/Transaction.php | 111 +++++++------ .../Database/TransactionCurrency.php | 75 +++++---- .../Database/TransactionJournal.php | 72 +++++---- .../FireflyIII/Database/TransactionType.php | 153 +++++++++--------- app/lib/FireflyIII/Database/User.php | 6 +- 16 files changed, 562 insertions(+), 495 deletions(-) diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php index 02a108a14e..99522d1ef2 100644 --- a/app/controllers/BudgetController.php +++ b/app/controllers/BudgetController.php @@ -51,13 +51,19 @@ class BudgetController extends BaseController $limit->repeat_freq = 'monthly'; $limit->repeats = 0; $limit->save(); - Event::fire('limits.store', [$limit]); + /* + * A newly stored limit also created a limit repetition. + */ + Event::fire('limits.store', [$limit]); // Still in use. } else { if ($amount > 0) { $limit->amount = $amount; $limit->save(); - Event::fire('limits.update', [$limit]); + /* + * An updated limit also updates the associated limit repetitions. + */ + Event::fire('limits.update', [$limit]); // Still in use. } else { $limit->delete(); } diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php index a3a26d673e..18c45283d5 100644 --- a/app/controllers/GoogleTableController.php +++ b/app/controllers/GoogleTableController.php @@ -264,7 +264,6 @@ class GoogleTableController extends BaseController $date = $journal->date; $descriptionURL = route('transactions.show', $journal->id); $description = $journal->description; - $amount = floatval(-0.01); // TODO $id = $journal->id; diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index c497a8c6d3..c1e728b063 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -60,8 +60,6 @@ class PiggybankController extends BaseController */ public function destroy(Piggybank $piggyBank) { - Event::fire('piggybanks.destroy', [$piggyBank]); - /** @var \FireflyIII\Database\Piggybank $acct */ $repos = App::make('FireflyIII\Database\Piggybank'); $repos->destroy($piggyBank); diff --git a/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php b/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php index 09e3943099..dec66c2dcf 100644 --- a/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php +++ b/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php @@ -107,16 +107,6 @@ class EloquentPiggybankTrigger return true; } - /** - * @param \Piggybank $piggyBank - * - * @return bool - */ - public function destroy(\Piggybank $piggyBank) - { - return true; - } - /** * @param \Piggybank $piggyBank * @param $amount @@ -175,7 +165,6 @@ class EloquentPiggybankTrigger */ public function subscribe(Dispatcher $events) { - $events->listen('piggybanks.destroy', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@destroy'); $events->listen( 'piggybanks.modifyAmountAdd', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@modifyAmountAdd' ); diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index 015ed63cf1..e345a1c6d0 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -6,6 +6,7 @@ use Carbon\Carbon; use FireflyIII\Database\Ifaces\AccountInterface; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; +use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; use Illuminate\Support\MessageBag; use LaravelBook\Ardent\Ardent; @@ -198,16 +199,6 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface return $this->getAccountsByType(['Expense account', 'Beneficiary account'], $parameters); } - /** - * Get all default accounts. - * - * @return Collection - */ - public function getDefaultAccounts() - { - // TODO: Implement getDefaultAccounts() method. - } - /** * Returns an object with id $id. * @@ -237,16 +228,6 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - // TODO: Implement get() method. - } - /** * Counts the number of total revenue accounts. Useful for DataTables. * @@ -281,19 +262,6 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - die('No impl'); - } - /** * Validates a model. Returns an array containing MessageBags * errors/warnings/successes. @@ -462,6 +430,38 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface return false; } + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + return $this->getUser()->accounts()->whereIn('id', $ids)->get(); + } + + /** + * Get all default accounts. + * + * @return Collection + */ + public function getDefaultAccounts() + { + // TODO: Implement getDefaultAccounts() method. + throw new NotImplementedException; + } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + // TODO: Implement get() method. + throw new NotImplementedException; + } + /** * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. * @@ -472,15 +472,20 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface public function findByWhat($what) { // TODO: Implement findByWhat() method. + throw new NotImplementedException; } /** - * @param array $ids + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. * - * @return Collection + * @param Ardent $model + * + * @return array */ - public function getByIds(array $ids) + public function validateObject(Ardent $model) { - return $this->getUser()->accounts()->whereIn('id', $ids)->get(); + // TODO: Implement validateObject() method. + throw new NotImplementedException; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/AccountType.php b/app/lib/FireflyIII/Database/AccountType.php index 8a4e13f1dc..5d101c1653 100644 --- a/app/lib/FireflyIII/Database/AccountType.php +++ b/app/lib/FireflyIII/Database/AccountType.php @@ -3,6 +3,7 @@ namespace FireflyIII\Database; use Firefly\Exception\FireflyException; +use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; use LaravelBook\Ardent\Ardent; use FireflyIII\Database\Ifaces\AccountTypeInterface; @@ -56,6 +57,7 @@ class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls public function destroy(Ardent $model) { // TODO: Implement destroy() method. + throw new NotImplementedException; } /** @@ -69,6 +71,7 @@ class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls public function validateObject(Ardent $model) { // TODO: Implement validateObject() method. + throw new NotImplementedException; } /** @@ -82,6 +85,7 @@ class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls public function validate(array $model) { // TODO: Implement validate() method. + throw new NotImplementedException; } /** @@ -92,6 +96,19 @@ class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls public function store(array $data) { // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. + throw new NotImplementedException; } /** @@ -104,6 +121,7 @@ class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls public function find($id) { // TODO: Implement find() method. + throw new NotImplementedException; } /** @@ -114,6 +132,7 @@ class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls public function get() { // TODO: Implement get() method. + throw new NotImplementedException; } /** @@ -124,16 +143,6 @@ class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls public function getByIds(array $ids) { // TODO: Implement getByIds() method. - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - // TODO: Implement update() method. + throw new NotImplementedException; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Budget.php b/app/lib/FireflyIII/Database/Budget.php index 934941adf7..0d0eda4be3 100644 --- a/app/lib/FireflyIII/Database/Budget.php +++ b/app/lib/FireflyIII/Database/Budget.php @@ -2,13 +2,13 @@ namespace FireflyIII\Database; use Carbon\Carbon; -use FireflyIII\Exception\NotImplementedException; -use Illuminate\Support\MessageBag; -use LaravelBook\Ardent\Ardent; -use Illuminate\Support\Collection; +use FireflyIII\Database\Ifaces\BudgetInterface; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; -use FireflyIII\Database\Ifaces\BudgetInterface; +use FireflyIII\Exception\NotImplementedException; +use Illuminate\Support\Collection; +use Illuminate\Support\MessageBag; +use LaravelBook\Ardent\Ardent; /** * Class Budget @@ -29,7 +29,7 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface /** * @param \Budget $budget - * @param Carbon $date + * @param Carbon $date * * @return \LimitRepetition|null */ @@ -54,18 +54,6 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface return true; } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - } /** * Validates an array. Returns an array containing MessageBags @@ -77,9 +65,9 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface */ public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; if (isset($model['name'])) { if (strlen($model['name']) < 1) { @@ -104,8 +92,8 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface } return [ - 'errors' => $errors, - 'warnings' => $warnings, + 'errors' => $errors, + 'warnings' => $warnings, 'successes' => $successes ]; } @@ -119,7 +107,7 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface { $data['user_id'] = $this->getUser()->id; - $budget = new \Budget($data); + $budget = new \Budget($data); $budget->class = 'Budget'; if (!$budget->validate()) { @@ -130,18 +118,6 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface return $budget; } - /** - * Returns an object with id $id. - * - * @param int $id - * - * @return Ardent - */ - public function find($id) - { - // TODO: Implement find() method. - } - /** * Returns all objects. * @@ -156,7 +132,7 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface /** * @param \Budget $budget - * @param Carbon $date + * @param Carbon $date * * @return float */ @@ -169,27 +145,6 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface return $sum; } - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. - } - - /** - * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. - * - * @param $what - * - * @return \AccountType|null - */ - public function findByWhat($what) - { - // TODO: Implement findByWhat() method. - } /** * @param Carbon $start @@ -203,21 +158,21 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface return \Auth::user()->transactionjournals()->whereNotIn( 'transaction_journals.id', function ($query) use ($start, $end) { $query->select('transaction_journals.id')->from('transaction_journals') - ->leftJoin( - 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', - 'transaction_journals.id' - ) - ->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) - ->where('components.class', 'Budget'); + ->leftJoin( + 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', + 'transaction_journals.id' + ) + ->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id') + ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) + ->where('components.class', 'Budget'); } )->before($end)->after($start)->lessThan(0)->transactionTypes(['Withdrawal'])->get(); } /** * @param Ardent $model - * @param array $data + * @param array $data * * @return bool */ @@ -234,4 +189,55 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface return true; } + + /** + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param Ardent $model + * + * @return array + */ + public function validateObject(Ardent $model) + { + // TODO: Implement validateObject() method. + throw new NotImplementedException; + } + + /** + * Returns an object with id $id. + * + * @param int $id + * + * @return Ardent + */ + public function find($id) + { + // TODO: Implement find() method. + throw new NotImplementedException; + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } + + /** + * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. + * + * @param $what + * + * @return \AccountType|null + */ + public function findByWhat($what) + { + // TODO: Implement findByWhat() method. + throw new NotImplementedException; + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Category.php b/app/lib/FireflyIII/Database/Category.php index 7599acfe57..5c378a2704 100644 --- a/app/lib/FireflyIII/Database/Category.php +++ b/app/lib/FireflyIII/Database/Category.php @@ -2,13 +2,13 @@ namespace FireflyIII\Database; use Carbon\Carbon; -use FireflyIII\Exception\NotImplementedException; -use Illuminate\Support\MessageBag; -use LaravelBook\Ardent\Ardent; -use Illuminate\Support\Collection; +use FireflyIII\Database\Ifaces\CategoryInterface; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; -use FireflyIII\Database\Ifaces\CategoryInterface; +use FireflyIII\Exception\NotImplementedException; +use Illuminate\Support\Collection; +use Illuminate\Support\MessageBag; +use LaravelBook\Ardent\Ardent; /** * Class Category @@ -38,18 +38,6 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface return true; } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - } /** * Validates an array. Returns an array containing MessageBags @@ -61,9 +49,9 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface */ public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; if (isset($model['name'])) { if (strlen($model['name']) < 1) { @@ -88,34 +76,12 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface } return [ - 'errors' => $errors, - 'warnings' => $warnings, + 'errors' => $errors, + 'warnings' => $warnings, 'successes' => $successes ]; } - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - // TODO: Implement store() method. - } - - /** - * Returns an object with id $id. - * - * @param int $id - * - * @return Ardent - */ - public function find($id) - { - // TODO: Implement find() method. - } - /** * Returns all objects. * @@ -126,31 +92,10 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface return $this->getUser()->categories()->orderBy('name', 'ASC')->get(); } - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. - } - - /** - * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. - * - * @param $what - * - * @return \AccountType|null - */ - public function findByWhat($what) - { - // TODO: Implement findByWhat() method. - } /** * @param \Category $budget - * @param Carbon $date + * @param Carbon $date * * @return null */ @@ -161,7 +106,7 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface /** * @param \Category $category - * @param Carbon $date + * @param Carbon $date * * @return float */ @@ -176,7 +121,7 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface /** * @param Ardent $model - * @param array $data + * @param array $data * * @return bool */ @@ -193,4 +138,66 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface return true; } + + /** + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param Ardent $model + * + * @return array + */ + public function validateObject(Ardent $model) + { + // TODO: Implement validateObject() method. + throw new NotImplementedException; + } + + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * Returns an object with id $id. + * + * @param int $id + * + * @return Ardent + */ + public function find($id) + { + // TODO: Implement find() method. + throw new NotImplementedException; + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } + + /** + * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. + * + * @param $what + * + * @return \AccountType|null + */ + public function findByWhat($what) + { + // TODO: Implement findByWhat() method. + throw new NotImplementedException; + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Piggybank.php b/app/lib/FireflyIII/Database/Piggybank.php index f99aa14040..66575fcfb3 100644 --- a/app/lib/FireflyIII/Database/Piggybank.php +++ b/app/lib/FireflyIII/Database/Piggybank.php @@ -2,13 +2,13 @@ namespace FireflyIII\Database; use Carbon\Carbon; -use FireflyIII\Exception\NotImplementedException; -use Illuminate\Support\MessageBag; -use LaravelBook\Ardent\Ardent; -use Illuminate\Support\Collection; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\PiggybankInterface; +use FireflyIII\Exception\NotImplementedException; +use Illuminate\Support\Collection; +use Illuminate\Support\MessageBag; +use LaravelBook\Ardent\Ardent; /** * Class Piggybank @@ -19,6 +19,14 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface { use SwitchUser; + /** + * + */ + public function __construct() + { + $this->setUser(\Auth::user()); + } + /** * @param \Account $account * @@ -36,14 +44,6 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface } - /** - * - */ - public function __construct() - { - $this->setUser(\Auth::user()); - } - /** * @param Ardent $model * @@ -54,18 +54,6 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface $model->delete(); } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - } /** * Validates an array. Returns an array containing MessageBags @@ -77,9 +65,9 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface */ public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; /* * Name validation: @@ -116,7 +104,7 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface } // check period. if (!$errors->has('reminder') && !$errors->has('targetdate') && isset($model['remind_me']) && intval($model['remind_me']) == 1) { - $today = new Carbon; + $today = new Carbon; $target = new Carbon($model['targetdate']); switch ($model['reminder']) { case 'week': @@ -148,8 +136,8 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface } return [ - 'errors' => $errors, - 'warnings' => $warnings, + 'errors' => $errors, + 'warnings' => $warnings, 'successes' => $successes ]; } @@ -161,12 +149,12 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface */ public function store(array $data) { - $data['rep_every'] = isset($data['rep_every']) ? $data['rep_every'] : 0; + $data['rep_every'] = isset($data['rep_every']) ? $data['rep_every'] : 0; $data['reminder_skip'] = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0; - $data['order'] = isset($data['order']) ? $data['order'] : 0; - $data['remind_me'] = isset($data['remind_me']) ? intval($data['remind_me']) : 0; - $data['startdate'] = isset($data['startdate']) ? $data['startdate'] : Carbon::now()->format('Y-m-d'); - $data['targetdate'] = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null; + $data['order'] = isset($data['order']) ? $data['order'] : 0; + $data['remind_me'] = isset($data['remind_me']) ? intval($data['remind_me']) : 0; + $data['startdate'] = isset($data['startdate']) ? $data['startdate'] : Carbon::now()->format('Y-m-d'); + $data['targetdate'] = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null; $piggybank = new \Piggybank($data); @@ -179,17 +167,6 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface $piggybank->save(); } - /** - * Returns an object with id $id. - * - * @param int $id - * - * @return Ardent - */ - public function find($id) - { - // TODO: Implement find() method. - } /** * Returns all objects. @@ -201,6 +178,58 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface return $this->getUser()->piggybanks()->where('repeats', 0)->get(); } + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + /** @var \Piggybank $model */ + $model->name = $data['name']; + $model->account_id = intval($data['account_id']); + $model->targetamount = floatval($data['targetamount']); + $model->targetdate = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null; + $model->rep_every = isset($data['rep_every']) ? $data['rep_every'] : 0; + $model->reminder_skip = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0; + $model->order = isset($data['order']) ? $data['order'] : 0; + $model->remind_me = isset($data['remind_me']) ? intval($data['remind_me']) : 0; + if (!$model->validate()) { + var_dump($model->errors()); + exit(); + } + $model->save(); + return true; + } + + /** + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param Ardent $model + * + * @return array + */ + public function validateObject(Ardent $model) + { + // TODO: Implement validateObject() method. + throw new NotImplementedException; + } + + /** + * Returns an object with id $id. + * + * @param int $id + * + * @return Ardent + */ + public function find($id) + { + // TODO: Implement find() method. + throw new NotImplementedException; + } + /** * @param array $ids * @@ -209,6 +238,7 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface public function getByIds(array $ids) { // TODO: Implement getByIds() method. + throw new NotImplementedException; } /** @@ -221,30 +251,6 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface public function findByWhat($what) { // TODO: Implement findByWhat() method. - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - /** @var \Piggybank $model */ - $model->name = $data['name']; - $model->account_id = intval($data['account_id']); - $model->targetamount = floatval($data['targetamount']); - $model->targetdate = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null; - $model->rep_every = isset($data['rep_every']) ? $data['rep_every'] : 0; - $model->reminder_skip = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0; - $model->order = isset($data['order']) ? $data['order'] : 0; - $model->remind_me = isset($data['remind_me']) ? intval($data['remind_me']) : 0; - if(!$model->validate()) { - var_dump($model->errors()); - exit(); - } - $model->save(); - return true; + throw new NotImplementedException; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Recurring.php b/app/lib/FireflyIII/Database/Recurring.php index b8cb6ba29f..410de6a3a6 100644 --- a/app/lib/FireflyIII/Database/Recurring.php +++ b/app/lib/FireflyIII/Database/Recurring.php @@ -4,6 +4,7 @@ namespace FireflyIII\Database; use Carbon\Carbon; +use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; use LaravelBook\Ardent\Ardent; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; @@ -40,6 +41,17 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + return $this->getUser()->recurringtransactions()->get(); + } + /** * @param Ardent $model * @@ -48,6 +60,7 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface public function destroy(Ardent $model) { // TODO: Implement destroy() method. + throw new NotImplementedException; } /** @@ -61,6 +74,7 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface public function validateObject(Ardent $model) { // TODO: Implement validateObject() method. + throw new NotImplementedException; } /** @@ -74,6 +88,7 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface public function validate(array $model) { // TODO: Implement validate() method. + throw new NotImplementedException; } /** @@ -84,6 +99,19 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface public function store(array $data) { // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. + throw new NotImplementedException; } /** @@ -96,16 +124,7 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface public function find($id) { // TODO: Implement find() method. - } - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - return $this->getUser()->recurringtransactions()->get(); + throw new NotImplementedException; } /** @@ -116,6 +135,7 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface public function getByIds(array $ids) { // TODO: Implement getByIds() method. + throw new NotImplementedException; } /** @@ -128,16 +148,6 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface public function findByWhat($what) { // TODO: Implement findByWhat() method. - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - // TODO: Implement update() method. + throw new NotImplementedException; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/RecurringTransaction.php b/app/lib/FireflyIII/Database/RecurringTransaction.php index 8dc570c49f..6eb8cac8f1 100644 --- a/app/lib/FireflyIII/Database/RecurringTransaction.php +++ b/app/lib/FireflyIII/Database/RecurringTransaction.php @@ -2,14 +2,12 @@ namespace FireflyIII\Database; -use Carbon\Carbon; -use FireflyIII\Database\Ifaces\RecurringTransactionInterface; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; +use FireflyIII\Database\Ifaces\RecurringTransactionInterface; use FireflyIII\Exception\NotImplementedException; -use Illuminate\Support\MessageBag; -use LaravelBook\Ardent\Ardent; use Illuminate\Support\Collection; +use LaravelBook\Ardent\Ardent; /** * Class Account @@ -28,6 +26,17 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac $this->setUser(\Auth::user()); } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + return $this->getUser()->recurringtransactions()->get(); + } + /** * @param Ardent $model * @@ -80,7 +89,7 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac /** * @param Ardent $model - * @param array $data + * @param array $data * * @return bool */ @@ -103,16 +112,6 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac throw new NotImplementedException; } - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - return $this->getUser()->recurringtransactions()->get(); - } - /** * @param array $ids * diff --git a/app/lib/FireflyIII/Database/Transaction.php b/app/lib/FireflyIII/Database/Transaction.php index 744880dd73..09d88c00c5 100644 --- a/app/lib/FireflyIII/Database/Transaction.php +++ b/app/lib/FireflyIII/Database/Transaction.php @@ -3,13 +3,14 @@ namespace FireflyIII\Database; use Firefly\Exception\FireflyException; +use FireflyIII\Database\Ifaces\CommonDatabaseCalls; +use FireflyIII\Database\Ifaces\CUD; +use FireflyIII\Database\Ifaces\TransactionInterface; use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; use Illuminate\Support\MessageBag; use LaravelBook\Ardent\Ardent; -use FireflyIII\Database\Ifaces\CommonDatabaseCalls; -use FireflyIII\Database\Ifaces\CUD; -use FireflyIII\Database\Ifaces\TransactionInterface; + /** * Class Transaction * @@ -19,29 +20,6 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls { use SwitchUser; - /** - * @param Ardent $model - * - * @return bool - */ - public function destroy(Ardent $model) - { - // TODO: Implement destroy() method. - } - - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - } - /** * Validates an array. Returns an array containing MessageBags * errors/warnings/successes. @@ -52,9 +30,9 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls */ public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; if (!isset($model['account_id']) && !isset($model['account'])) { @@ -106,8 +84,8 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls } return [ - 'errors' => $errors, - 'warnings' => $warnings, + 'errors' => $errors, + 'warnings' => $warnings, 'successes' => $successes ]; } @@ -119,7 +97,6 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls */ public function store(array $data) { - // TODO: Implement store() method. $transaction = new \Transaction; $transaction->account()->associate($data['account']); $transaction->transactionJournal()->associate($data['transaction_journal']); @@ -138,6 +115,43 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls return $transaction; } + /** + * @param Ardent $model + * + * @return bool + */ + public function destroy(Ardent $model) + { + // TODO: Implement destroy() method. + throw new NotImplementedException; + } + + /** + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param Ardent $model + * + * @return array + */ + public function validateObject(Ardent $model) + { + // TODO: Implement validateObject() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. + throw new NotImplementedException; + } + /** * Returns an object with id $id. * @@ -148,6 +162,7 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls public function find($id) { // TODO: Implement find() method. + throw new NotImplementedException; } /** @@ -158,6 +173,18 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls public function get() { // TODO: Implement get() method. + throw new NotImplementedException; + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; } /** @@ -170,26 +197,6 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls public function findByWhat($what) { // TODO: Implement findByWhat() method. - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - // TODO: Implement update() method. - } - - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. + throw new NotImplementedException; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/TransactionCurrency.php b/app/lib/FireflyIII/Database/TransactionCurrency.php index 9e46efb207..91cb15a869 100644 --- a/app/lib/FireflyIII/Database/TransactionCurrency.php +++ b/app/lib/FireflyIII/Database/TransactionCurrency.php @@ -3,6 +3,7 @@ namespace FireflyIII\Database; +use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; use LaravelBook\Ardent\Ardent; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; @@ -17,6 +18,17 @@ use FireflyIII\Database\Ifaces\TransactionCurrencyInterface; class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDatabaseCalls { + + /** + * @param string $code + * + * @return \TransactionCurrency|null + */ + public function findByCode($code) + { + return \TransactionCurrency::whereCode($code)->first(); + } + /** * @param Ardent $model * @@ -25,6 +37,7 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa public function destroy(Ardent $model) { // TODO: Implement destroy() method. + throw new NotImplementedException; } /** @@ -38,6 +51,7 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa public function validateObject(Ardent $model) { // TODO: Implement validateObject() method. + throw new NotImplementedException; } /** @@ -51,6 +65,7 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa public function validate(array $model) { // TODO: Implement validate() method. + throw new NotImplementedException; } /** @@ -61,6 +76,19 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa public function store(array $data) { // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. + throw new NotImplementedException; } /** @@ -73,6 +101,7 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa public function find($id) { // TODO: Implement find() method. + throw new NotImplementedException; } /** @@ -83,6 +112,18 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa public function get() { // TODO: Implement get() method. + throw new NotImplementedException; + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; } /** @@ -94,37 +135,7 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa */ public function findByWhat($what) { - // TODO: Implement get() method. - } - - /** - * @param string $code - * - * @return \TransactionCurrency|null - */ - public function findByCode($code) - { - return \TransactionCurrency::whereCode($code)->first(); - } - - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - // TODO: Implement update() method. + // TODO: Implement findByWhat() method. + throw new NotImplementedException; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 1603f3386d..c9291faf98 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -8,6 +8,7 @@ use Firefly\Exception\FireflyException; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\TransactionJournalInterface; +use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; use Illuminate\Support\MessageBag; use LaravelBook\Ardent\Ardent; @@ -121,29 +122,6 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData } - /** - * @param Ardent $model - * - * @return bool - */ - public function destroy(Ardent $model) - { - // TODO: Implement destroy() method. - } - - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - } - /** * Validates an array. Returns an array containing MessageBags * errors/warnings/successes. @@ -452,25 +430,28 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData /** - * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. + * @param Ardent $model * - * @param $what - * - * @return \AccountType|null + * @return bool */ - public function findByWhat($what) + public function destroy(Ardent $model) { - // TODO: Implement findByWhat() method. + // TODO: Implement destroy() method. + throw new NotImplementedException; } /** - * @param array $ids + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. * - * @return Collection + * @param Ardent $model + * + * @return array */ - public function getByIds(array $ids) + public function validateObject(Ardent $model) { - // TODO: Implement getByIds() method. + // TODO: Implement validateObject() method. + throw new NotImplementedException; } /** @@ -482,5 +463,30 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData public function update(Ardent $model, array $data) { // TODO: Implement update() method. + throw new NotImplementedException; + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } + + /** + * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. + * + * @param $what + * + * @return \AccountType|null + */ + public function findByWhat($what) + { + // TODO: Implement findByWhat() method. + throw new NotImplementedException; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/TransactionType.php b/app/lib/FireflyIII/Database/TransactionType.php index 0abf5e9308..c6cc1c59dd 100644 --- a/app/lib/FireflyIII/Database/TransactionType.php +++ b/app/lib/FireflyIII/Database/TransactionType.php @@ -7,6 +7,7 @@ use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\TransactionTypeInterface; use FireflyIII\Exception\FireflyException; +use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; use LaravelBook\Ardent\Ardent; @@ -18,74 +19,6 @@ use LaravelBook\Ardent\Ardent; class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCalls { - /** - * @param Ardent $model - * - * @return bool - */ - public function destroy(Ardent $model) - { - // TODO: Implement destroy() method. - } - - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - } - - /** - * Validates an array. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param array $model - * - * @return array - */ - public function validate(array $model) - { - // TODO: Implement validate() method. - } - - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - // TODO: Implement store() method. - } - - /** - * Returns an object with id $id. - * - * @param int $id - * - * @return Ardent - */ - public function find($id) - { - // TODO: Implement find() method. - } - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - // TODO: Implement get() method. - } - /** * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. * @@ -115,13 +48,53 @@ class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCa } /** - * @param array $ids + * @param Ardent $model * - * @return Collection + * @return bool */ - public function getByIds(array $ids) + public function destroy(Ardent $model) { - // TODO: Implement getByIds() method. + // TODO: Implement destroy() method. + throw new NotImplementedException; + } + + /** + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param Ardent $model + * + * @return array + */ + public function validateObject(Ardent $model) + { + // TODO: Implement validateObject() method. + throw new NotImplementedException; + } + + /** + * Validates an array. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param array $model + * + * @return array + */ + public function validate(array $model) + { + // TODO: Implement validate() method. + throw new NotImplementedException; + } + + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + // TODO: Implement store() method. + throw new NotImplementedException; } /** @@ -133,5 +106,41 @@ class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCa public function update(Ardent $model, array $data) { // TODO: Implement update() method. + throw new NotImplementedException; + } + + /** + * Returns an object with id $id. + * + * @param int $id + * + * @return Ardent + */ + public function find($id) + { + // TODO: Implement find() method. + throw new NotImplementedException; + } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + // TODO: Implement get() method. + throw new NotImplementedException; + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/User.php b/app/lib/FireflyIII/Database/User.php index f72a26d415..1796ab8468 100644 --- a/app/lib/FireflyIII/Database/User.php +++ b/app/lib/FireflyIII/Database/User.php @@ -18,10 +18,10 @@ class User */ public function register(array $data) { - $user = new \User; - $user->email = isset($data['email']) ? $data['email'] : null; + $user = new \User; + $user->email = isset($data['email']) ? $data['email'] : null; $user->migrated = 0; - $user->reset = \Str::random(32); + $user->reset = \Str::random(32); $user->password = \Hash::make(\Str::random(12)); if (!$user->save()) { From 258d6a168874b7ee4e52ae41f22f0a7da3380696 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 12 Nov 2014 22:36:02 +0100 Subject: [PATCH 018/193] Code clean up and reformat. --- app/controllers/AccountController.php | 96 ++-- app/controllers/BudgetController.php | 128 +++-- app/controllers/CategoryController.php | 6 +- app/controllers/GoogleChartController.php | 635 +++++++++++----------- app/controllers/GoogleTableController.php | 419 +++++++------- app/controllers/HomeController.php | 102 ++-- app/controllers/JsonController.php | 12 +- app/controllers/PiggybankController.php | 140 +++-- app/controllers/PreferencesController.php | 9 +- app/controllers/ProfileController.php | 18 +- app/controllers/RecurringController.php | 40 +- app/controllers/ReportController.php | 6 +- app/controllers/SearchController.php | 12 +- app/controllers/TransactionController.php | 81 ++- app/controllers/UserController.php | 79 ++- 15 files changed, 882 insertions(+), 901 deletions(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index f05d11623a..0347ca71a5 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -18,38 +18,6 @@ class AccountController extends BaseController View::share('title', 'Accounts'); } - /** - * @param string $what - * - * @return View - * @throws FireflyException - */ - public function index($what = 'default') - { - switch ($what) { - default: - throw new FireflyException('Cannot handle account type "' . e($what) . '".'); - break; - case 'asset': - $subTitleIcon = 'fa-money'; - $subTitle = 'Asset accounts'; - break; - case 'expense': - $subTitleIcon = 'fa-shopping-cart'; - $subTitle = 'Expense accounts'; - break; - case 'revenue': - $subTitleIcon = 'fa-download'; - $subTitle = 'Revenue accounts'; - break; - } - return View::make('accounts.index') - ->with('what', $what) - ->with(compact('subTitleIcon')) - ->with(compact('subTitle')); - } - - /** * @return \Illuminate\View\View */ @@ -67,10 +35,7 @@ class AccountController extends BaseController break; } - return View::make('accounts.create') - ->with('subTitle', 'Create a new ' . $what . ' account') - ->with('what', $what) - ->with(compact('subTitleIcon')); + return View::make('accounts.create')->with('subTitle', 'Create a new ' . $what . ' account')->with('what', $what)->with(compact('subTitleIcon')); } /** @@ -80,10 +45,9 @@ class AccountController extends BaseController */ public function delete(Account $account) { - return View::make('accounts.delete')->with('account', $account) - ->with( - 'subTitle', 'Delete ' . strtolower($account->accountType->type) . ' "' . $account->name . '"' - ); + return View::make('accounts.delete')->with('account', $account)->with( + 'subTitle', 'Delete ' . strtolower($account->accountType->type) . ' "' . $account->name . '"' + ); } /** @@ -193,11 +157,40 @@ class AccountController extends BaseController Session::flash('prefilled', $prefilled); } - return View::make('accounts.edit') - ->with('account', $account) - ->with('openingBalance', $openingBalance) - ->with(compact('subTitleIcon')) - ->with('subTitle', 'Edit ' . strtolower($account->accountType->type) . ' "' . $account->name . '"'); + return View::make('accounts.edit')->with('account', $account)->with('openingBalance', $openingBalance)->with(compact('subTitleIcon'))->with( + 'subTitle', 'Edit ' . strtolower( + $account->accountType->type + ) . ' "' . $account->name . '"' + ); + } + + /** + * @param string $what + * + * @return View + * @throws FireflyException + */ + public function index($what = 'default') + { + switch ($what) { + default: + throw new FireflyException('Cannot handle account type "' . e($what) . '".'); + break; + case 'asset': + $subTitleIcon = 'fa-money'; + $subTitle = 'Asset accounts'; + break; + case 'expense': + $subTitleIcon = 'fa-shopping-cart'; + $subTitle = 'Expense accounts'; + break; + case 'revenue': + $subTitleIcon = 'fa-download'; + $subTitle = 'Revenue accounts'; + break; + } + + return View::make('accounts.index')->with('what', $what)->with(compact('subTitleIcon'))->with(compact('subTitle')); } /** @@ -223,10 +216,9 @@ class AccountController extends BaseController //$data = $this->_accounts->show($account, 40); - return View::make('accounts.show') - ->with('account', $account) - ->with('subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"') - ->with(compact('subTitleIcon')); + return View::make('accounts.show')->with('account', $account)->with( + 'subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"' + )->with(compact('subTitleIcon')); } /** @@ -236,7 +228,7 @@ class AccountController extends BaseController public function store() { - $data = Input::all(); + $data = Input::all(); $data['what'] = isset($data['what']) && $data['what'] != '' ? $data['what'] : 'asset'; /** @var \FireflyIII\Database\Account $acct */ $acct = App::make('FireflyIII\Database\Account'); @@ -253,6 +245,7 @@ class AccountController extends BaseController Session::flash('warnings', $messages['warnings']); Session::flash('successes', $messages['successes']); Session::flash('error', 'Could not save account: ' . $messages['errors']->first()); + return Redirect::route('accounts.create', $data['what'])->withInput()->withErrors($messages['errors']); } // store! @@ -270,6 +263,7 @@ class AccountController extends BaseController Session::flash('warnings', $messageBags['warnings']); Session::flash('successes', $messageBags['successes']); Session::flash('errors', $messageBags['errors']); + return Redirect::route('accounts.create', $data['what'])->withInput(); break; } @@ -315,6 +309,7 @@ class AccountController extends BaseController Session::flash('warnings', $messages['warnings']); Session::flash('successes', $messages['successes']); Session::flash('error', 'Could not save account: ' . $messages['errors']->first()); + return Redirect::route('accounts.edit', $account->id)->withInput()->withErrors($messages['errors']); } // store! @@ -331,6 +326,7 @@ class AccountController extends BaseController Session::flash('warnings', $messageBags['warnings']); Session::flash('successes', $messageBags['successes']); Session::flash('errors', $messageBags['errors']); + return Redirect::route('accounts.edit', $account->id)->withInput(); break; } diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php index 99522d1ef2..977cfcdb0d 100644 --- a/app/controllers/BudgetController.php +++ b/app/controllers/BudgetController.php @@ -17,20 +17,6 @@ class BudgetController extends BaseController View::share('mainTitleIcon', 'fa-tasks'); } - /** - * @return \Illuminate\Http\RedirectResponse - */ - public function postUpdateIncome() - { - /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ - $preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); - $date = Session::get('start'); - - $value = intval(Input::get('amount')); - $preferences->set('budgetIncomeTotal' . $date->format('FY'), $value); - return Redirect::route('budgets.index'); - } - /** * Update the amount for a budget's limitrepetition and/or create it. * @@ -78,6 +64,49 @@ class BudgetController extends BaseController } + /** + * @return $this + */ + public function create() + { + return View::make('budgets.create')->with('subTitle', 'Create a new budget'); + } + + /** + * @param Budget $budget + * + * @return $this + */ + public function delete(Budget $budget) + { + return View::make('budgets.delete')->with('budget', $budget)->with('subTitle', 'Delete budget "' . $budget->name . '"'); + } + + public function destroy(Budget $budget) + { + /** @var \FireflyIII\Database\Budget $repos */ + $repos = App::make('FireflyIII\Database\Budget'); + // remove budget + $repos->destroy($budget); + Session::flash('success', 'The budget was deleted.'); + + return Redirect::route('budgets.index'); + + } + + /** + * @param Budget $budget + * + * @return $this + */ + public function edit(Budget $budget) + { + Session::flash('prefilled', ['name' => $budget->name]); + + return View::make('budgets.edit')->with('budget', $budget)->with('subTitle', 'Edit budget "' . $budget->name . '"'); + + } + /** * @return $this */ @@ -137,15 +166,18 @@ class BudgetController extends BaseController } /** - * @return $this + * @return \Illuminate\Http\RedirectResponse */ - public function updateIncome() + public function postUpdateIncome() { - $date = Session::get('start'); /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ $preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); - $budgetAmount = $preferences->get('budgetIncomeTotal' . $date->format('FY'), 1000); - return View::make('budgets.income')->with('amount', $budgetAmount)->with('date', $date); + $date = Session::get('start'); + + $value = intval(Input::get('amount')); + $preferences->set('budgetIncomeTotal' . $date->format('FY'), $value); + + return Redirect::route('budgets.index'); } /** @@ -172,47 +204,6 @@ class BudgetController extends BaseController return View::make('budgets.show', compact('limits', 'budget', 'repetition')); } - /** - * @return $this - */ - public function create() - { - return View::make('budgets.create')->with('subTitle', 'Create a new budget'); - } - - /** - * @param Budget $budget - * - * @return $this - */ - public function delete(Budget $budget) - { - return View::make('budgets.delete')->with('budget', $budget)->with('subTitle', 'Delete budget "' . $budget->name . '"'); - } - - public function destroy(Budget $budget) - { - /** @var \FireflyIII\Database\Budget $repos */ - $repos = App::make('FireflyIII\Database\Budget'); - // remove budget - $repos->destroy($budget); - Session::flash('success', 'The budget was deleted.'); - return Redirect::route('budgets.index'); - - } - - /** - * @param Budget $budget - * - * @return $this - */ - public function edit(Budget $budget) - { - Session::flash('prefilled', ['name' => $budget->name]); - return View::make('budgets.edit')->with('budget', $budget)->with('subTitle', 'Edit budget "' . $budget->name . '"'); - - } - /** * @return \Illuminate\Http\RedirectResponse */ @@ -234,6 +225,7 @@ class BudgetController extends BaseController Session::flash('warnings', $messages['warnings']); Session::flash('successes', $messages['successes']); Session::flash('error', 'Could not save budget: ' . $messages['errors']->first()); + return Redirect::route('budgets.create')->withInput()->withErrors($messages['errors']); } // store! @@ -251,6 +243,7 @@ class BudgetController extends BaseController Session::flash('warnings', $messageBags['warnings']); Session::flash('successes', $messageBags['successes']); Session::flash('errors', $messageBags['errors']); + return Redirect::route('budgets.create')->withInput(); break; } @@ -280,6 +273,7 @@ class BudgetController extends BaseController Session::flash('warnings', $messages['warnings']); Session::flash('successes', $messages['successes']); Session::flash('error', 'Could not save budget: ' . $messages['errors']->first()); + return Redirect::route('budgets.edit', $budget->id)->withInput()->withErrors($messages['errors']); } // store! @@ -296,8 +290,22 @@ class BudgetController extends BaseController Session::flash('warnings', $messageBags['warnings']); Session::flash('successes', $messageBags['successes']); Session::flash('errors', $messageBags['errors']); + return Redirect::route('budgets.edit', $budget->id)->withInput(); break; } } + + /** + * @return $this + */ + public function updateIncome() + { + $date = Session::get('start'); + /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ + $preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); + $budgetAmount = $preferences->get('budgetIncomeTotal' . $date->format('FY'), 1000); + + return View::make('budgets.income')->with('amount', $budgetAmount)->with('date', $date); + } } \ No newline at end of file diff --git a/app/controllers/CategoryController.php b/app/controllers/CategoryController.php index d655245a3e..220f476dcb 100644 --- a/app/controllers/CategoryController.php +++ b/app/controllers/CategoryController.php @@ -46,6 +46,7 @@ class CategoryController extends BaseController $repos->destroy($category); Session::flash('success', 'The category was deleted.'); + return Redirect::route('categories.index'); } @@ -56,8 +57,7 @@ class CategoryController extends BaseController */ public function edit(Category $category) { - return View::make('categories.edit')->with('category', $category) - ->with('subTitle', 'Edit category "' . $category->name . '"'); + return View::make('categories.edit')->with('category', $category)->with('subTitle', 'Edit category "' . $category->name . '"'); } /** @@ -122,6 +122,7 @@ class CategoryController extends BaseController Session::flash('warnings', $messages['warnings']); Session::flash('successes', $messages['successes']); Session::flash('error', 'Could not save category: ' . $messages['errors']->first()); + return Redirect::route('categories.edit', $category->id)->withInput()->withErrors($messages['errors']); } // store! @@ -138,6 +139,7 @@ class CategoryController extends BaseController Session::flash('warnings', $messageBags['warnings']); Session::flash('successes', $messageBags['successes']); Session::flash('errors', $messageBags['errors']); + return Redirect::route('categories.edit', $category->id)->withInput(); break; } diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index 281bc124db..61c520089b 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -7,6 +7,162 @@ use Carbon\Carbon; class GoogleChartController extends BaseController { + /** + * @param Account $account + */ + public function accountBalanceChart(Account $account) + { + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('Day of month', 'date'); + $chart->addColumn('Balance for ' . $account->name, 'number'); + + /* + * Loop the date, then loop the accounts, then add balance. + */ + $start = Session::get('start'); + $end = Session::get('end'); + $current = clone $start; + + while ($end >= $current) { + $row = [clone $current]; + if ($current > Carbon::now()) { + $row[] = null; + } else { + $row[] = $account->balance($current); + } + + $chart->addRowArray($row); + $current->addDay(); + } + + + $chart->generate(); + + return Response::json($chart->getData()); + } + + /** + * @param Account $account + * + * @return \Illuminate\Http\JsonResponse + */ + public function accountSankeyInChart(Account $account) + { + // collect all relevant entries. + $set = []; + + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('From', 'string'); + $chart->addColumn('To', 'string', 'domain'); + $chart->addColumn('Weight', 'number'); + + $transactions = $account->transactions()->with( + ['transactionjournal', 'transactionjournal.transactions' => function ($q) { + $q->where('amount', '<', 0); + }, 'transactionjournal.budgets', 'transactionjournal.transactiontype', 'transactionjournal.categories'] + )->before(Session::get('end'))->after( + Session::get('start') + )->get(); + + /** @var Transaction $transaction */ + foreach ($transactions as $transaction) { + $amount = floatval($transaction->amount); + $type = $transaction->transactionJournal->transactionType->type; + + if ($amount > 0 && $type != 'Transfer') { + + $otherAccount = $transaction->transactionJournal->transactions[0]->account->name; + $categoryName = isset($transaction->transactionJournal->categories[0]) ? $transaction->transactionJournal->categories[0]->name : '(no cat)'; + $set[] = [$otherAccount, $categoryName, $amount]; + $set[] = [$categoryName, $account->name, $amount]; + } + } + // loop the set, group everything together: + $grouped = []; + foreach ($set as $entry) { + $key = $entry[0] . $entry[1]; + if (isset($grouped[$key])) { + $grouped[$key][2] += $entry[2]; + } else { + $grouped[$key] = $entry; + } + } + + // add rows to the chart: + foreach ($grouped as $entry) { + $chart->addRow($entry[0], $entry[1], $entry[2]); + } + + $chart->generate(); + + return Response::json($chart->getData()); + + } + + /** + * @param Account $account + * + * @return \Illuminate\Http\JsonResponse + */ + public function accountSankeyOutChart(Account $account) + { + // collect all relevant entries. + $set = []; + + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('From', 'string'); + $chart->addColumn('To', 'string', 'domain'); + $chart->addColumn('Weight', 'number'); + + $transactions = $account->transactions()->with( + ['transactionjournal', 'transactionjournal.transactions', 'transactionjournal.budgets', 'transactionjournal.transactiontype', + 'transactionjournal.categories'] + )->before(Session::get('end'))->after( + Session::get('start') + )->get(); + + /** @var Transaction $transaction */ + foreach ($transactions as $transaction) { + $amount = floatval($transaction->amount); + $type = $transaction->transactionJournal->transactionType->type; + + if ($amount < 0 && $type != 'Transfer') { + + // from account to a budget (if present). + $budgetName = isset($transaction->transactionJournal->budgets[0]) ? $transaction->transactionJournal->budgets[0]->name : '(no budget)'; + $set[] = [$account->name, $budgetName, $amount * -1]; + + // from budget to category. + $categoryName = isset($transaction->transactionJournal->categories[0]) ? ' ' . $transaction->transactionJournal->categories[0]->name + : '(no cat)'; + $set[] = [$budgetName, $categoryName, $amount * -1]; + } + } + // loop the set, group everything together: + $grouped = []; + foreach ($set as $entry) { + $key = $entry[0] . $entry[1]; + if (isset($grouped[$key])) { + $grouped[$key][2] += $entry[2]; + } else { + $grouped[$key] = $entry; + } + } + + // add rows to the chart: + foreach ($grouped as $entry) { + $chart->addRow($entry[0], $entry[1], $entry[2]); + } + + $chart->generate(); + + return Response::json($chart->getData()); + + } + /** * This method renders the b */ @@ -60,202 +216,11 @@ class GoogleChartController extends BaseController } $chart->generate(); + return Response::json($chart->getData()); } - /** - * @param $year - * - * @return \Illuminate\Http\JsonResponse - */ - public function yearInExp($year) - { - try { - $start = new Carbon('01-01-' . $year); - } catch (Exception $e) { - App::abort(500); - } - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('Month', 'date'); - $chart->addColumn('Income', 'number'); - $chart->addColumn('Expenses', 'number'); - - /** @var \FireflyIII\Database\TransactionJournal $tj */ - $tj = App::make('FireflyIII\Database\TransactionJournal'); - - $end = clone $start; - $end->endOfYear(); - while ($start < $end) { - - // total income: - $income = $tj->getSumOfIncomesByMonth($start); - $expense = $tj->getSumOfExpensesByMonth($start); - - $chart->addRow(clone $start, $income, $expense); - $start->addMonth(); - } - - - $chart->generate(); - return Response::json($chart->getData()); - - } - - /** - * @param $year - * - * @return \Illuminate\Http\JsonResponse - */ - public function yearInExpSum($year) - { - try { - $start = new Carbon('01-01-' . $year); - } catch (Exception $e) { - App::abort(500); - } - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('Summary', 'string'); - $chart->addColumn('Income', 'number'); - $chart->addColumn('Expenses', 'number'); - - /** @var \FireflyIII\Database\TransactionJournal $tj */ - $tj = App::make('FireflyIII\Database\TransactionJournal'); - - $end = clone $start; - $end->endOfYear(); - $income = 0; - $expense = 0; - $count = 0; - while ($start < $end) { - - // total income: - $income += $tj->getSumOfIncomesByMonth($start); - $expense += $tj->getSumOfExpensesByMonth($start); - $count++; - - $start->addMonth(); - } - $chart->addRow('Sum', $income, $expense); - $count = $count > 0 ? $count : 1; - $chart->addRow('Average', ($income / $count), ($expense / $count)); - - - $chart->generate(); - return Response::json($chart->getData()); - - } - - - /** - * @return \Illuminate\Http\JsonResponse - */ - public function budgetsReportChart($year) - { - - try { - $start = new Carbon('01-01-' . $year); - } catch (Exception $e) { - App::abort(500); - } - - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - - /** @var \FireflyIII\Database\Budget $bdt */ - $bdt = App::make('FireflyIII\Database\Budget'); - $budgets = $bdt->get(); - - $chart->addColumn('Month', 'date'); - /** @var \Budget $budget */ - foreach ($budgets as $budget) { - $chart->addColumn($budget->name, 'number'); - } - $chart->addColumn('No budget', 'number'); - - /* - * Loop budgets this year. - */ - $end = clone $start; - $end->endOfYear(); - while ($start <= $end) { - $row = [clone $start]; - - foreach ($budgets as $budget) { - $row[] = $bdt->spentInMonth($budget, $start); - } - - /* - * Without a budget: - */ - $endOfMonth = clone $start; - $endOfMonth->endOfMonth(); - $set = $bdt->transactionsWithoutBudgetInDateRange($start, $endOfMonth); - $row[] = floatval($set->sum('amount')) * -1; - - $chart->addRowArray($row); - $start->addMonth(); - } - - - $chart->generate(); - return Response::json($chart->getData()); - } - - /** - * @param Component $component - * @param $year - * - * @return \Illuminate\Http\JsonResponse - */ - public function componentsAndSpending(Component $component, $year) - { - try { - $start = new Carbon('01-01-' . $year); - } catch (Exception $e) { - App::abort(500); - } - - if ($component->class == 'Budget') { - /** @var \FireflyIII\Database\Budget $repos */ - $repos = App::make('FireflyIII\Database\Budget'); - } else { - /** @var \FireflyIII\Database\Category $repos */ - $repos = App::make('FireflyIII\Database\Category'); - } - - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('Month', 'date'); - $chart->addColumn('Budgeted', 'number'); - $chart->addColumn('Spent', 'number'); - - $end = clone $start; - $end->endOfYear(); - while ($start <= $end) { - - $spent = $repos->spentInMonth($component, $start); - $repetition = $repos->repetitionOnStartingOnDate($component, $start); - if ($repetition) { - $budgeted = floatval($repetition->amount); - } else { - $budgeted = null; - } - - $chart->addRow(clone $start, $budgeted, $spent); - - $start->addMonth(); - } - - - $chart->generate(); - return Response::json($chart->getData()); - - - } - /** * @return \Illuminate\Http\JsonResponse */ @@ -321,6 +286,7 @@ class GoogleChartController extends BaseController $chart->generate(); + return Response::json($chart->getData()); } @@ -365,10 +331,120 @@ class GoogleChartController extends BaseController $chart->generate(); + return Response::json($chart->getData()); } + /** + * @return \Illuminate\Http\JsonResponse + */ + public function budgetsReportChart($year) + { + + try { + $start = new Carbon('01-01-' . $year); + } catch (Exception $e) { + App::abort(500); + } + + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + + /** @var \FireflyIII\Database\Budget $bdt */ + $bdt = App::make('FireflyIII\Database\Budget'); + $budgets = $bdt->get(); + + $chart->addColumn('Month', 'date'); + /** @var \Budget $budget */ + foreach ($budgets as $budget) { + $chart->addColumn($budget->name, 'number'); + } + $chart->addColumn('No budget', 'number'); + + /* + * Loop budgets this year. + */ + $end = clone $start; + $end->endOfYear(); + while ($start <= $end) { + $row = [clone $start]; + + foreach ($budgets as $budget) { + $row[] = $bdt->spentInMonth($budget, $start); + } + + /* + * Without a budget: + */ + $endOfMonth = clone $start; + $endOfMonth->endOfMonth(); + $set = $bdt->transactionsWithoutBudgetInDateRange($start, $endOfMonth); + $row[] = floatval($set->sum('amount')) * -1; + + $chart->addRowArray($row); + $start->addMonth(); + } + + + $chart->generate(); + + return Response::json($chart->getData()); + } + + /** + * @param Component $component + * @param $year + * + * @return \Illuminate\Http\JsonResponse + */ + public function componentsAndSpending(Component $component, $year) + { + try { + $start = new Carbon('01-01-' . $year); + } catch (Exception $e) { + App::abort(500); + } + + if ($component->class == 'Budget') { + /** @var \FireflyIII\Database\Budget $repos */ + $repos = App::make('FireflyIII\Database\Budget'); + } else { + /** @var \FireflyIII\Database\Category $repos */ + $repos = App::make('FireflyIII\Database\Category'); + } + + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('Month', 'date'); + $chart->addColumn('Budgeted', 'number'); + $chart->addColumn('Spent', 'number'); + + $end = clone $start; + $end->endOfYear(); + while ($start <= $end) { + + $spent = $repos->spentInMonth($component, $start); + $repetition = $repos->repetitionOnStartingOnDate($component, $start); + if ($repetition) { + $budgeted = floatval($repetition->amount); + } else { + $budgeted = null; + } + + $chart->addRow(clone $start, $budgeted, $spent); + + $start->addMonth(); + } + + + $chart->generate(); + + return Response::json($chart->getData()); + + + } + /** * @return \Illuminate\Http\JsonResponse * @throws \FireflyIII\Exception\FireflyException @@ -380,14 +456,8 @@ class GoogleChartController extends BaseController * Set of paid transaction journals. * Set of unpaid recurring transactions. */ - $paid = [ - 'items' => [], - 'amount' => 0 - ]; - $unpaid = [ - 'items' => [], - 'amount' => 0 - ]; + $paid = ['items' => [], 'amount' => 0]; + $unpaid = ['items' => [], 'amount' => 0]; /** @var \Grumpydictator\Gchart\GChart $chart */ $chart = App::make('gchart'); @@ -455,160 +525,93 @@ class GoogleChartController extends BaseController $chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']); $chart->generate(); + return Response::json($chart->getData()); } /** - * @param Account $account - */ - public function accountBalanceChart(Account $account) - { - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('Day of month', 'date'); - $chart->addColumn('Balance for ' . $account->name, 'number'); - - /* - * Loop the date, then loop the accounts, then add balance. - */ - $start = Session::get('start'); - $end = Session::get('end'); - $current = clone $start; - - while ($end >= $current) { - $row = [clone $current]; - if ($current > Carbon::now()) { - $row[] = null; - } else { - $row[] = $account->balance($current); - } - - $chart->addRowArray($row); - $current->addDay(); - } - - - $chart->generate(); - return Response::json($chart->getData()); - } - - /** - * @param Account $account + * @param $year * * @return \Illuminate\Http\JsonResponse */ - public function accountSankeyOutChart(Account $account) + public function yearInExp($year) { - // collect all relevant entries. - $set = []; - + try { + $start = new Carbon('01-01-' . $year); + } catch (Exception $e) { + App::abort(500); + } /** @var \Grumpydictator\Gchart\GChart $chart */ $chart = App::make('gchart'); - $chart->addColumn('From', 'string'); - $chart->addColumn('To', 'string', 'domain'); - $chart->addColumn('Weight', 'number'); + $chart->addColumn('Month', 'date'); + $chart->addColumn('Income', 'number'); + $chart->addColumn('Expenses', 'number'); - $transactions = $account->transactions()->with( - ['transactionjournal', 'transactionjournal.transactions', 'transactionjournal.budgets', 'transactionjournal.transactiontype', - 'transactionjournal.categories'] - )->before(Session::get('end'))->after( - Session::get('start') - )->get(); + /** @var \FireflyIII\Database\TransactionJournal $tj */ + $tj = App::make('FireflyIII\Database\TransactionJournal'); - /** @var Transaction $transaction */ - foreach ($transactions as $transaction) { - $amount = floatval($transaction->amount); - $type = $transaction->transactionJournal->transactionType->type; + $end = clone $start; + $end->endOfYear(); + while ($start < $end) { - if ($amount < 0 && $type != 'Transfer') { + // total income: + $income = $tj->getSumOfIncomesByMonth($start); + $expense = $tj->getSumOfExpensesByMonth($start); - // from account to a budget (if present). - $budgetName = isset($transaction->transactionJournal->budgets[0]) ? $transaction->transactionJournal->budgets[0]->name : '(no budget)'; - $set[] = [$account->name, $budgetName, $amount * -1]; - - // from budget to category. - $categoryName = isset($transaction->transactionJournal->categories[0]) ? ' ' . $transaction->transactionJournal->categories[0]->name - : '(no cat)'; - $set[] = [$budgetName, $categoryName, $amount * -1]; - } - } - // loop the set, group everything together: - $grouped = []; - foreach ($set as $entry) { - $key = $entry[0] . $entry[1]; - if (isset($grouped[$key])) { - $grouped[$key][2] += $entry[2]; - } else { - $grouped[$key] = $entry; - } + $chart->addRow(clone $start, $income, $expense); + $start->addMonth(); } - // add rows to the chart: - foreach ($grouped as $entry) { - $chart->addRow($entry[0], $entry[1], $entry[2]); - } $chart->generate(); + return Response::json($chart->getData()); } /** - * @param Account $account + * @param $year * * @return \Illuminate\Http\JsonResponse */ - public function accountSankeyInChart(Account $account) + public function yearInExpSum($year) { - // collect all relevant entries. - $set = []; - + try { + $start = new Carbon('01-01-' . $year); + } catch (Exception $e) { + App::abort(500); + } /** @var \Grumpydictator\Gchart\GChart $chart */ $chart = App::make('gchart'); - $chart->addColumn('From', 'string'); - $chart->addColumn('To', 'string', 'domain'); - $chart->addColumn('Weight', 'number'); + $chart->addColumn('Summary', 'string'); + $chart->addColumn('Income', 'number'); + $chart->addColumn('Expenses', 'number'); - $transactions = $account->transactions()->with( - ['transactionjournal', 'transactionjournal.transactions' => function ($q) { - $q->where('amount', '<', 0); - }, 'transactionjournal.budgets', 'transactionjournal.transactiontype', 'transactionjournal.categories'] - )->before(Session::get('end'))->after( - Session::get('start') - )->get(); + /** @var \FireflyIII\Database\TransactionJournal $tj */ + $tj = App::make('FireflyIII\Database\TransactionJournal'); - /** @var Transaction $transaction */ - foreach ($transactions as $transaction) { - $amount = floatval($transaction->amount); - $type = $transaction->transactionJournal->transactionType->type; + $end = clone $start; + $end->endOfYear(); + $income = 0; + $expense = 0; + $count = 0; + while ($start < $end) { - if ($amount > 0 && $type != 'Transfer') { + // total income: + $income += $tj->getSumOfIncomesByMonth($start); + $expense += $tj->getSumOfExpensesByMonth($start); + $count++; - $otherAccount = $transaction->transactionJournal->transactions[0]->account->name; - $categoryName = isset($transaction->transactionJournal->categories[0]) ? $transaction->transactionJournal->categories[0]->name - : '(no cat)'; - $set[] = [$otherAccount, $categoryName, $amount]; - $set[] = [$categoryName, $account->name, $amount]; - } - } - // loop the set, group everything together: - $grouped = []; - foreach ($set as $entry) { - $key = $entry[0] . $entry[1]; - if (isset($grouped[$key])) { - $grouped[$key][2] += $entry[2]; - } else { - $grouped[$key] = $entry; - } + $start->addMonth(); } + $chart->addRow('Sum', $income, $expense); + $count = $count > 0 ? $count : 1; + $chart->addRow('Average', ($income / $count), ($expense / $count)); - // add rows to the chart: - foreach ($grouped as $entry) { - $chart->addRow($entry[0], $entry[1], $entry[2]); - } $chart->generate(); + return Response::json($chart->getData()); } diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php index 18c45283d5..9b5cfeccba 100644 --- a/app/controllers/GoogleTableController.php +++ b/app/controllers/GoogleTableController.php @@ -7,38 +7,6 @@ use FireflyIII\Exception\FireflyException; class GoogleTableController extends BaseController { - /** - * @return \Illuminate\Http\JsonResponse - */ - public function categoryList() - { - - /** @var \FireflyIII\Database\Category $repos */ - $repos = App::make('FireflyIII\Database\Category'); - - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('ID', 'number'); - $chart->addColumn('ID_Edit', 'string'); - $chart->addColumn('ID_Delete', 'string'); - $chart->addColumn('Name_URL', 'string'); - $chart->addColumn('Name', 'string'); - - $list = $repos->get(); - - /** @var Category $entry */ - foreach ($list as $entry) { - $chart->addRow( - $entry->id, route('categories.edit', $entry->id), route('categories.delete', $entry->id), route('categories.show', $entry->id), $entry->name - ); - } - - - $chart->generate(); - return Response::json($chart->getData()); - - } - /** * @param $what * @@ -76,20 +44,197 @@ class GoogleTableController extends BaseController /** @var \Account $entry */ foreach ($list as $entry) { - $edit = route('accounts.edit', $entry->id); + $edit = route('accounts.edit', $entry->id); $delete = route('accounts.delete', $entry->id); - $show = route('accounts.show', $entry->id); + $show = route('accounts.show', $entry->id); $chart->addRow($entry->id, $edit, $delete, $show, $entry->name, $entry->balance()); } $chart->generate(); + return Response::json($chart->getData()); } /** - * @param Component $component + * @return \Illuminate\Http\JsonResponse + */ + public function categoryList() + { + + /** @var \FireflyIII\Database\Category $repos */ + $repos = App::make('FireflyIII\Database\Category'); + + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('ID', 'number'); + $chart->addColumn('ID_Edit', 'string'); + $chart->addColumn('ID_Delete', 'string'); + $chart->addColumn('Name_URL', 'string'); + $chart->addColumn('Name', 'string'); + + $list = $repos->get(); + + /** @var Category $entry */ + foreach ($list as $entry) { + $chart->addRow( + $entry->id, route('categories.edit', $entry->id), route('categories.delete', $entry->id), route('categories.show', $entry->id), $entry->name + ); + } + + + $chart->generate(); + + return Response::json($chart->getData()); + + } + + public function recurringList() + { + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('ID', 'number'); + $chart->addColumn('ID_Edit', 'string'); + $chart->addColumn('ID_Delete', 'string'); + $chart->addColumn('Name_URL', 'string'); + $chart->addColumn('Name', 'string'); + + /** @var \FireflyIII\Database\RecurringTransaction $repository */ + $repository = App::make('FireflyIII\Database\RecurringTransaction'); + + $set = $repository->get(); + + /** @var \RecurringTransaction $entry */ + foreach ($set as $entry) { + $row = [$entry->id, route('recurring.edit', $entry->id), route('recurring.delete', $entry->id), route('recurring.show', $entry->id), $entry->name]; + $chart->addRowArray($row); + + } + + + /* + *
+ + + + + + + + + + */ + $chart->generate(); + + return Response::json($chart->getData()); + } + + /** + * @param Account $account + */ + public function transactionsByAccount(Account $account) + { + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('ID', 'number'); + $chart->addColumn('ID_Edit', 'string'); + $chart->addColumn('ID_Delete', 'string'); + $chart->addColumn('Date', 'date'); + $chart->addColumn('Description_URL', 'string'); + $chart->addColumn('Description', 'string'); + $chart->addColumn('Amount', 'number'); + $chart->addColumn('From_URL', 'string'); + $chart->addColumn('From', 'string'); + $chart->addColumn('To_URL', 'string'); + $chart->addColumn('To', 'string'); + $chart->addColumn('Budget_URL', 'string'); + $chart->addColumn('Budget', 'string'); + $chart->addColumn('Category_URL', 'string'); + $chart->addColumn('Category', 'string'); + + + /* + * Find transactions: + */ + $accountID = $account->id; + $transactions = $account->transactions()->with( + ['transactionjournal', 'transactionjournal.transactions' => function ($q) use ($accountID) { + $q->where('account_id', '!=', $accountID); + }, 'transactionjournal.budgets', 'transactionjournal.transactiontype', 'transactionjournal.categories'] + )->before(Session::get('end'))->after( + Session::get('start') + )->orderBy('date', 'DESC')->get(); + + /** @var Transaction $transaction */ + foreach ($transactions as $transaction) { + $date = $transaction->transactionJournal->date; + $descriptionURL = route('transactions.show', $transaction->transaction_journal_id); + $description = $transaction->transactionJournal->description; + $amount = floatval($transaction->amount); + + if ($transaction->transactionJournal->transactions[0]->account->id == $account->id) { + $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[1]->account->id); + $opposingAccountName = $transaction->transactionJournal->transactions[1]->account->name; + } else { + $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[0]->account->id); + $opposingAccountName = $transaction->transactionJournal->transactions[0]->account->name; + } + if (isset($transaction->transactionJournal->budgets[0])) { + $budgetURL = route('budgets.show', $transaction->transactionJournal->budgets[0]->id); + $budget = $transaction->transactionJournal->budgets[0]->name; + } else { + $budgetURL = ''; + $budget = ''; + } + + if (isset($transaction->transactionJournal->categories[0])) { + $categoryURL = route('categories.show', $transaction->transactionJournal->categories[0]->id); + $category = $transaction->transactionJournal->categories[0]->name; + } else { + $categoryURL = ''; + $category = ''; + } + + + if ($amount < 0) { + $from = $account->name; + $fromURL = route('accounts.show', $account->id); + + $to = $opposingAccountName; + $toURL = $opposingAccountURI; + } else { + $to = $account->name; + $toURL = route('accounts.show', $account->id); + + $from = $opposingAccountName; + $fromURL = $opposingAccountURI; + } + + $id = $transaction->transactionJournal->id; + $edit = route('transactions.edit', $transaction->transactionJournal->id); + $delete = route('transactions.delete', $transaction->transactionJournal->id); + $chart->addRow( + $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $budget, $categoryURL, $category + ); + } + + // + // + // + // + // + // + // + + + $chart->generate(); + + return Response::json($chart->getData()); + } + + /** + * @param Component $component * @param LimitRepetition $repetition */ public function transactionsByComponent(Component $component, LimitRepetition $repetition = null) @@ -114,26 +259,25 @@ class GoogleTableController extends BaseController if (is_null($repetition)) { $journals = $component->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->orderBy('date', 'DESC') - ->get(); + ->get(); } else { $journals = $component->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->after( $repetition->startdate - ) - ->before($repetition->enddate)->orderBy('date', 'DESC')->get(); + )->before($repetition->enddate)->orderBy('date', 'DESC')->get(); } /** @var TransactionJournal $transaction */ foreach ($journals as $journal) { - $date = $journal->date; + $date = $journal->date; $descriptionURL = route('transactions.show', $journal->id); - $description = $journal->description; + $description = $journal->description; /** @var Transaction $transaction */ foreach ($journal->transactions as $transaction) { if (floatval($transaction->amount) > 0) { $amount = floatval($transaction->amount); - $to = $transaction->account->name; - $toURL = route('accounts.show', $transaction->account->id); + $to = $transaction->account->name; + $toURL = route('accounts.show', $transaction->account->id); } else { - $from = $transaction->account->name; + $from = $transaction->account->name; $fromURL = route('accounts.show', $transaction->account->id); } @@ -148,15 +292,15 @@ class GoogleTableController extends BaseController if (isset($journal->categories[0])) { $categoryURL = route('categories.show', $journal->categories[0]->id); - $category = $journal->categories[0]->name; + $category = $journal->categories[0]->name; } else { $categoryURL = ''; - $category = ''; + $category = ''; } - $id = $journal->id; - $edit = route('transactions.edit', $journal->id); + $id = $journal->id; + $edit = route('transactions.edit', $journal->id); $delete = route('transactions.delete', $journal->id); $chart->addRow( $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $component, $categoryURL, @@ -166,55 +310,11 @@ class GoogleTableController extends BaseController $chart->generate(); + return Response::json($chart->getData()); } - public function recurringList() - { - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('ID', 'number'); - $chart->addColumn('ID_Edit', 'string'); - $chart->addColumn('ID_Delete', 'string'); - $chart->addColumn('Name_URL', 'string'); - $chart->addColumn('Name', 'string'); - - /** @var \FireflyIII\Database\RecurringTransaction $repository */ - $repository = App::make('FireflyIII\Database\RecurringTransaction'); - - $set = $repository->get(); - - /** @var \RecurringTransaction $entry */ - foreach ($set as $entry) { - $row = [ - $entry->id, - route('recurring.edit', $entry->id), - route('recurring.delete', $entry->id), - route('recurring.show', $entry->id), - $entry->name - ]; - $chart->addRowArray($row); - - } - - - /* - * - - - - - - - - - - */ - $chart->generate(); - return Response::json($chart->getData()); - } - /** * @param $what * @@ -261,158 +361,55 @@ class GoogleTableController extends BaseController /** @var TransactionJournal $journal */ foreach ($list as $journal) { - $date = $journal->date; + $date = $journal->date; $descriptionURL = route('transactions.show', $journal->id); - $description = $journal->description; - $id = $journal->id; + $description = $journal->description; + $id = $journal->id; if ($journal->transactions[0]->amount < 0) { - $fromURL = route('accounts.show', $journal->transactions[0]->account->id); + $fromURL = route('accounts.show', $journal->transactions[0]->account->id); $fromName = $journal->transactions[0]->account->name; - $amount = floatval($journal->transactions[0]->amount); + $amount = floatval($journal->transactions[0]->amount); - $toURL = route('accounts.show', $journal->transactions[1]->account->id); + $toURL = route('accounts.show', $journal->transactions[1]->account->id); $toName = $journal->transactions[1]->account->name; } else { - $fromURL = route('accounts.show', $journal->transactions[1]->account->id); + $fromURL = route('accounts.show', $journal->transactions[1]->account->id); $fromName = $journal->transactions[1]->account->name; - $amount = floatval($journal->transactions[1]->amount); + $amount = floatval($journal->transactions[1]->amount); - $toURL = route('accounts.show', $journal->transactions[0]->account->id); + $toURL = route('accounts.show', $journal->transactions[0]->account->id); $toName = $journal->transactions[0]->account->name; } if (isset($journal->budgets[0])) { $budgetURL = route('budgets.show', $journal->budgets[0]->id); - $budget = $journal->budgets[0]->name; + $budget = $journal->budgets[0]->name; } else { $budgetURL = ''; - $budget = ''; + $budget = ''; } if (isset($journal->categories[0])) { $categoryURL = route('categories.show', $journal->categories[0]->id); - $category = $journal->categories[0]->name; + $category = $journal->categories[0]->name; } else { $categoryURL = ''; - $category = ''; + $category = ''; } - $edit = route('transactions.edit', $journal->id); + $edit = route('transactions.edit', $journal->id); $delete = route('transactions.delete', $journal->id); $chart->addRow( - $id, $edit, $delete, $date, $descriptionURL, $description, $amount, - $fromURL, $fromName, $toURL, $toName, - $budgetURL, $budget, $categoryURL, $category + $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $fromName, $toURL, $toName, $budgetURL, $budget, $categoryURL, + $category ); } $chart->generate(); - return Response::json($chart->getData()); - } - /** - * @param Account $account - */ - public function transactionsByAccount(Account $account) - { - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('ID', 'number'); - $chart->addColumn('ID_Edit', 'string'); - $chart->addColumn('ID_Delete', 'string'); - $chart->addColumn('Date', 'date'); - $chart->addColumn('Description_URL', 'string'); - $chart->addColumn('Description', 'string'); - $chart->addColumn('Amount', 'number'); - $chart->addColumn('From_URL', 'string'); - $chart->addColumn('From', 'string'); - $chart->addColumn('To_URL', 'string'); - $chart->addColumn('To', 'string'); - $chart->addColumn('Budget_URL', 'string'); - $chart->addColumn('Budget', 'string'); - $chart->addColumn('Category_URL', 'string'); - $chart->addColumn('Category', 'string'); - - - /* - * Find transactions: - */ - $accountID = $account->id; - $transactions = $account->transactions()->with( - ['transactionjournal', 'transactionjournal.transactions' => function ($q) use ($accountID) { - $q->where('account_id', '!=', $accountID); - }, 'transactionjournal.budgets', 'transactionjournal.transactiontype', - 'transactionjournal.categories'] - )->before(Session::get('end'))->after( - Session::get('start') - )->orderBy('date', 'DESC')->get(); - - /** @var Transaction $transaction */ - foreach ($transactions as $transaction) { - $date = $transaction->transactionJournal->date; - $descriptionURL = route('transactions.show', $transaction->transaction_journal_id); - $description = $transaction->transactionJournal->description; - $amount = floatval($transaction->amount); - - if ($transaction->transactionJournal->transactions[0]->account->id == $account->id) { - $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[1]->account->id); - $opposingAccountName = $transaction->transactionJournal->transactions[1]->account->name; - } else { - $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[0]->account->id); - $opposingAccountName = $transaction->transactionJournal->transactions[0]->account->name; - } - if (isset($transaction->transactionJournal->budgets[0])) { - $budgetURL = route('budgets.show', $transaction->transactionJournal->budgets[0]->id); - $budget = $transaction->transactionJournal->budgets[0]->name; - } else { - $budgetURL = ''; - $budget = ''; - } - - if (isset($transaction->transactionJournal->categories[0])) { - $categoryURL = route('categories.show', $transaction->transactionJournal->categories[0]->id); - $category = $transaction->transactionJournal->categories[0]->name; - } else { - $categoryURL = ''; - $category = ''; - } - - - if ($amount < 0) { - $from = $account->name; - $fromURL = route('accounts.show', $account->id); - - $to = $opposingAccountName; - $toURL = $opposingAccountURI; - } else { - $to = $account->name; - $toURL = route('accounts.show', $account->id); - - $from = $opposingAccountName; - $fromURL = $opposingAccountURI; - } - - $id = $transaction->transactionJournal->id; - $edit = route('transactions.edit', $transaction->transactionJournal->id); - $delete = route('transactions.delete', $transaction->transactionJournal->id); - $chart->addRow( - $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $budget, $categoryURL, $category - ); - } - -// -// -// -// -// -// -// - - - $chart->generate(); return Response::json($chart->getData()); } } \ No newline at end of file diff --git a/app/controllers/HomeController.php b/app/controllers/HomeController.php index 833ea0a044..035400b976 100644 --- a/app/controllers/HomeController.php +++ b/app/controllers/HomeController.php @@ -1,5 +1,4 @@ prev(); - return Redirect::back(); - //return Redirect::route('index'); - } - - /** - * @return \Illuminate\Http\RedirectResponse - */ - public function sessionNext() - { - /** @var \FireflyIII\Shared\Toolkit\Navigation $navigation */ - $navigation = App::make('FireflyIII\Shared\Toolkit\Navigation'); - $navigation->next(); - return Redirect::back(); - //return Redirect::route('index'); - } - - /** - * @param $range - * - * @return \Illuminate\Http\RedirectResponse - */ - public function rangeJump($range) - { - - $valid = ['1D', '1W', '1M', '3M', '6M', '1Y',]; - - /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ - $preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); - - if (in_array($range, $valid)) { - $preferences->set('viewRange', $range); - Session::forget('range'); - } - return Redirect::back(); - } - /** * @return \Illuminate\Http\RedirectResponse */ @@ -66,9 +21,9 @@ class HomeController extends BaseController */ public function index() { -// Event::fire('limits.check'); -// Event::fire('piggybanks.check'); -// Event::fire('recurring.check'); + // Event::fire('limits.check'); + // Event::fire('piggybanks.check'); + // Event::fire('recurring.check'); // count, maybe Firefly needs some introducing text to show: /** @var \FireflyIII\Database\Account $acct */ @@ -103,7 +58,54 @@ class HomeController extends BaseController } // build the home screen: - return View::make('index')->with('count', $count)->with('transactions', $transactions)->with('title', 'Firefly') - ->with('subTitle', 'What\'s playing?')->with('mainTitleIcon', 'fa-fire'); + return View::make('index')->with('count', $count)->with('transactions', $transactions)->with('title', 'Firefly')->with('subTitle', 'What\'s playing?') + ->with('mainTitleIcon', 'fa-fire'); + } + + /** + * @param $range + * + * @return \Illuminate\Http\RedirectResponse + */ + public function rangeJump($range) + { + + $valid = ['1D', '1W', '1M', '3M', '6M', '1Y',]; + + /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ + $preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); + + if (in_array($range, $valid)) { + $preferences->set('viewRange', $range); + Session::forget('range'); + } + + return Redirect::back(); + } + + /** + * @return \Illuminate\Http\RedirectResponse + */ + public function sessionNext() + { + /** @var \FireflyIII\Shared\Toolkit\Navigation $navigation */ + $navigation = App::make('FireflyIII\Shared\Toolkit\Navigation'); + $navigation->next(); + + return Redirect::back(); + //return Redirect::route('index'); + } + + /** + * @return \Illuminate\Http\RedirectResponse + */ + public function sessionPrev() + { + /** @var \FireflyIII\Shared\Toolkit\Navigation $navigation */ + $navigation = App::make('FireflyIII\Shared\Toolkit\Navigation'); + $navigation->prev(); + + return Redirect::back(); + //return Redirect::route('index'); } } \ No newline at end of file diff --git a/app/controllers/JsonController.php b/app/controllers/JsonController.php index 3dbe758b39..9f0512572a 100644 --- a/app/controllers/JsonController.php +++ b/app/controllers/JsonController.php @@ -16,8 +16,8 @@ class JsonController extends BaseController { /** @var \FireflyIII\Database\Category $categories */ $categories = App::make('FireflyIII\Database\Category'); - $list = $categories->get(); - $return = []; + $list = $categories->get(); + $return = []; foreach ($list as $entry) { $return[] = $entry->name; } @@ -36,8 +36,8 @@ class JsonController extends BaseController { /** @var \FireflyIII\Database\Account $accounts */ $accounts = App::make('FireflyIII\Database\Account'); - $list = $accounts->getExpenseAccounts(); - $return = []; + $list = $accounts->getExpenseAccounts(); + $return = []; foreach ($list as $entry) { $return[] = $entry->name; } @@ -53,8 +53,8 @@ class JsonController extends BaseController { /** @var \FireflyIII\Database\Account $accounts */ $accounts = App::make('FireflyIII\Database\Account'); - $list = $accounts->getRevenueAccounts(); - $return = []; + $list = $accounts->getRevenueAccounts(); + $return = []; foreach ($list as $entry) { $return[] = $entry->name; } diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index c1e728b063..8b94de89a7 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -19,6 +19,25 @@ class PiggybankController extends BaseController { } + /** + * @param Piggybank $piggybank + * + * @return $this + */ + public function add(Piggybank $piggybank) + { + /** @var \FireflyIII\Database\Piggybank $acct */ + $repos = App::make('FireflyIII\Database\Piggybank'); + + $leftOnAccount = $repos->leftOnAccount($piggybank->account); + $savedSoFar = $piggybank->currentRelevantRep()->currentamount; + $leftToSave = $piggybank->targetamount - $savedSoFar; + $amount = min($leftOnAccount, $leftToSave); + + + return View::make('piggybanks.add', compact('piggybank'))->with('maxAmount', $amount); + } + /** * @throws NotImplementedException */ @@ -35,8 +54,10 @@ class PiggybankController extends BaseController $accounts = $toolkit->makeSelectList($acct->getAssetAccounts()); - return View::make('piggybanks.create', compact('accounts', 'periods'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc') - ->with('subTitle', 'Create new piggy bank')->with('subTitleIcon', 'fa-plus'); + + return View::make('piggybanks.create', compact('accounts', 'periods'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc')->with( + 'subTitle', 'Create new piggy bank' + )->with('subTitleIcon', 'fa-plus'); } /** @@ -46,11 +67,9 @@ class PiggybankController extends BaseController */ public function delete(Piggybank $piggybank) { - return View::make('piggybanks.delete') - ->with('piggybank', $piggybank) - ->with('subTitle', 'Delete "' . $piggybank->name . '"') - ->with('title', 'Piggy banks') - ->with('mainTitleIcon', 'fa-sort-amount-asc'); + return View::make('piggybanks.delete')->with('piggybank', $piggybank)->with('subTitle', 'Delete "' . $piggybank->name . '"')->with( + 'title', 'Piggy banks' + )->with('mainTitleIcon', 'fa-sort-amount-asc'); } /** @@ -89,38 +108,46 @@ class PiggybankController extends BaseController /* * Flash some data to fill the form. */ - $prefilled = [ - 'name' => $piggybank->name, - 'account_id' => $piggybank->account_id, - 'targetamount' => $piggybank->targetamount, - 'targetdate' => $piggybank->targetdate, - 'remind_me' => intval($piggybank->remind_me) == 1 ? true : false - ]; + $prefilled = ['name' => $piggybank->name, 'account_id' => $piggybank->account_id, 'targetamount' => $piggybank->targetamount, + 'targetdate' => $piggybank->targetdate, 'remind_me' => intval($piggybank->remind_me) == 1 ? true : false]; Session::flash('prefilled', $prefilled); return View::make('piggybanks.edit', compact('piggybank', 'accounts', 'periods', 'prefilled'))->with('title', 'Piggybanks')->with( 'mainTitleIcon', 'fa-sort-amount-asc' - ) - ->with('subTitle', 'Edit piggy bank "' . e($piggybank->name) . '"')->with('subTitleIcon', 'fa-pencil'); + )->with('subTitle', 'Edit piggy bank "' . e($piggybank->name) . '"')->with('subTitleIcon', 'fa-pencil'); } - /** - * @param Piggybank $piggybank - * - * @return $this - */ - public function add(Piggybank $piggybank) + public function index() { - /** @var \FireflyIII\Database\Piggybank $acct */ + /** @var \FireflyIII\Database\Piggybank $repos */ $repos = App::make('FireflyIII\Database\Piggybank'); - $leftOnAccount = $repos->leftOnAccount($piggybank->account); - $savedSoFar = $piggybank->currentRelevantRep()->currentamount; - $leftToSave = $piggybank->targetamount - $savedSoFar; - $amount = min($leftOnAccount, $leftToSave); + /** @var Collection $piggybanks */ + $piggybanks = $repos->get(); + $accounts = []; + /** @var Piggybank $piggybank */ + foreach ($piggybanks as $piggybank) { + $piggybank->savedSoFar = floatval($piggybank->currentRelevantRep()->currentamount); + $piggybank->percentage = intval($piggybank->savedSoFar / $piggybank->targetamount * 100); + $piggybank->leftToSave = $piggybank->targetamount - $piggybank->savedSoFar; - return View::make('piggybanks.add', compact('piggybank'))->with('maxAmount', $amount); + /* + * Fill account information: + */ + $account = $piggybank->account; + if (!isset($accounts[$account->id])) { + $accounts[$account->id] = ['name' => $account->name, 'balance' => $account->balance(), + 'leftForPiggybanks' => $repos->leftOnAccount($account), 'sumOfSaved' => $piggybank->savedSoFar, + 'sumOfTargets' => floatval($piggybank->targetamount), 'leftToSave' => $piggybank->leftToSave]; + } else { + $accounts[$account->id]['sumOfSaved'] += $piggybank->savedSoFar; + $accounts[$account->id]['sumOfTargets'] += floatval($piggybank->targetamount); + $accounts[$account->id]['leftToSave'] += $piggybank->leftToSave; + } + } + + return View::make('piggybanks.index', compact('piggybanks', 'accounts'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc'); } /** @@ -148,17 +175,8 @@ class PiggybankController extends BaseController } else { Session::flash('error', 'Could not add ' . mf($amount, false) . ' to "' . e($piggybank->name) . '".'); } - return Redirect::route('piggybanks.index'); - } - /** - * @param Piggybank $piggybank - * - * @return \Illuminate\View\View - */ - public function remove(Piggybank $piggybank) - { - return View::make('piggybanks.remove', compact('piggybank')); + return Redirect::route('piggybanks.index'); } /** @@ -180,47 +198,20 @@ class PiggybankController extends BaseController } else { Session::flash('error', 'Could not remove ' . mf($amount, false) . ' from "' . e($piggybank->name) . '".'); } + return Redirect::route('piggybanks.index'); } - public function index() + /** + * @param Piggybank $piggybank + * + * @return \Illuminate\View\View + */ + public function remove(Piggybank $piggybank) { - /** @var \FireflyIII\Database\Piggybank $repos */ - $repos = App::make('FireflyIII\Database\Piggybank'); - - /** @var Collection $piggybanks */ - $piggybanks = $repos->get(); - - $accounts = []; - /** @var Piggybank $piggybank */ - foreach ($piggybanks as $piggybank) { - $piggybank->savedSoFar = floatval($piggybank->currentRelevantRep()->currentamount); - $piggybank->percentage = intval($piggybank->savedSoFar / $piggybank->targetamount * 100); - $piggybank->leftToSave = $piggybank->targetamount - $piggybank->savedSoFar; - - /* - * Fill account information: - */ - $account = $piggybank->account; - if (!isset($accounts[$account->id])) { - $accounts[$account->id] = [ - 'name' => $account->name, - 'balance' => $account->balance(), - 'leftForPiggybanks' => $repos->leftOnAccount($account), - 'sumOfSaved' => $piggybank->savedSoFar, - 'sumOfTargets' => floatval($piggybank->targetamount), - 'leftToSave' => $piggybank->leftToSave - ]; - } else { - $accounts[$account->id]['sumOfSaved'] += $piggybank->savedSoFar; - $accounts[$account->id]['sumOfTargets'] += floatval($piggybank->targetamount); - $accounts[$account->id]['leftToSave'] += $piggybank->leftToSave; - } - } - return View::make('piggybanks.index', compact('piggybanks', 'accounts'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc'); + return View::make('piggybanks.remove', compact('piggybank')); } - public function show(Piggybank $piggyBank) { throw new NotImplementedException; @@ -249,6 +240,7 @@ class PiggybankController extends BaseController Session::flash('warnings', $messages['warnings']); Session::flash('successes', $messages['successes']); Session::flash('error', 'Could not save piggy bank: ' . $messages['errors']->first()); + return Redirect::route('piggybanks.create')->withInput()->withErrors($messages['errors']); } // store! @@ -296,6 +288,7 @@ class PiggybankController extends BaseController Session::flash('warnings', $messages['warnings']); Session::flash('successes', $messages['successes']); Session::flash('error', 'Could not save piggy bank: ' . $messages['errors']->first()); + return Redirect::route('piggybanks.edit', $piggyBank->id)->withInput()->withErrors($messages['errors']); } // store! @@ -312,6 +305,7 @@ class PiggybankController extends BaseController Session::flash('warnings', $messageBags['warnings']); Session::flash('successes', $messageBags['successes']); Session::flash('errors', $messageBags['errors']); + return Redirect::route('piggybanks.edit', $piggyBank->id)->withInput(); break; } diff --git a/app/controllers/PreferencesController.php b/app/controllers/PreferencesController.php index e8e6b4b3e9..6e165af1c3 100644 --- a/app/controllers/PreferencesController.php +++ b/app/controllers/PreferencesController.php @@ -28,13 +28,12 @@ class PreferencesController extends BaseController /** @var \FireflyIII\Shared\Preferences\Preferences $preferences */ $preferences = App::make('FireflyIII\Shared\Preferences\Preferences'); - $accounts = $acct->getAssetAccounts(); - $viewRange = $preferences->get('viewRange', '1M'); + $accounts = $acct->getAssetAccounts(); + $viewRange = $preferences->get('viewRange', '1M'); $viewRangeValue = $viewRange->data; - $frontpage = $preferences->get('frontpageAccounts', []); + $frontpage = $preferences->get('frontpageAccounts', []); - return View::make('preferences.index')->with('accounts', $accounts)->with('frontpageAccounts', $frontpage) - ->with('viewRange', $viewRangeValue); + return View::make('preferences.index')->with('accounts', $accounts)->with('frontpageAccounts', $frontpage)->with('viewRange', $viewRangeValue); } /** diff --git a/app/controllers/ProfileController.php b/app/controllers/ProfileController.php index ebfbc437cd..938d41f28a 100644 --- a/app/controllers/ProfileController.php +++ b/app/controllers/ProfileController.php @@ -6,15 +6,6 @@ class ProfileController extends BaseController { - /** - * @return \Illuminate\View\View - * - */ - public function index() - { - return View::make('profile.index')->with('title', 'Profile')->with('subTitle', Auth::user()->email)->with('mainTitleIcon', 'fa-user'); - } - /** * @return \Illuminate\View\View */ @@ -25,6 +16,15 @@ class ProfileController extends BaseController ); } + /** + * @return \Illuminate\View\View + * + */ + public function index() + { + return View::make('profile.index')->with('title', 'Profile')->with('subTitle', Auth::user()->email)->with('mainTitleIcon', 'fa-user'); + } + /** * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View */ diff --git a/app/controllers/RecurringController.php b/app/controllers/RecurringController.php index b780a4822b..1569a7e9ec 100644 --- a/app/controllers/RecurringController.php +++ b/app/controllers/RecurringController.php @@ -1,7 +1,5 @@ with('periods', $periods) - ->with('subTitle', 'Create new'); + return View::make('recurring.create')->with('periods', $periods)->with('subTitle', 'Create new'); } /** @@ -35,9 +31,9 @@ class RecurringController extends BaseController */ public function delete(RecurringTransaction $recurringTransaction) { - return View::make('recurring.delete') - ->with('recurringTransaction', $recurringTransaction) - ->with('subTitle', 'Delete "' . $recurringTransaction->name . '"'); + return View::make('recurring.delete')->with('recurringTransaction', $recurringTransaction)->with( + 'subTitle', 'Delete "' . $recurringTransaction->name . '"' + ); } /** @@ -72,10 +68,9 @@ class RecurringController extends BaseController { $periods = \Config::get('firefly.periods_to_text'); - return View::make('recurring.edit') - ->with('periods', $periods) - ->with('recurringTransaction', $recurringTransaction) - ->with('subTitle', 'Edit "' . $recurringTransaction->name . '"'); + return View::make('recurring.edit')->with('periods', $periods)->with('recurringTransaction', $recurringTransaction)->with( + 'subTitle', 'Edit "' . $recurringTransaction->name . '"' + ); } /** @@ -86,31 +81,32 @@ class RecurringController extends BaseController return View::make('recurring.index'); } - /** - * - */ - public function show(RecurringTransaction $recurringTransaction) - { - return View::make('recurring.show') - ->with('recurring', $recurringTransaction) - ->with('subTitle', $recurringTransaction->name); - } - /** * @param RecurringTransaction $recurringTransaction + * * @return mixed */ public function rescan(RecurringTransaction $recurringTransaction) { if (intval($recurringTransaction->active) == 0) { Session::flash('warning', 'Inactive recurring transactions cannot be scanned.'); + return Redirect::back(); } throw new NotImplementedException; Session::flash('success', 'Rescanned everything.'); + return Redirect::back(); } + /** + * + */ + public function show(RecurringTransaction $recurringTransaction) + { + return View::make('recurring.show')->with('recurring', $recurringTransaction)->with('subTitle', $recurringTransaction->name); + } + public function store() { throw new NotImplementedException; diff --git a/app/controllers/ReportController.php b/app/controllers/ReportController.php index baab2c53a0..8c9f1fa021 100644 --- a/app/controllers/ReportController.php +++ b/app/controllers/ReportController.php @@ -49,11 +49,7 @@ class ReportController extends BaseController $end = clone $date; $end->endOfYear(); while ($date < $end) { - $summary[] = [ - 'month' => $date->format('F'), - 'income' => $tj->getSumOfIncomesByMonth($date), - 'expense' => $tj->getSumOfExpensesByMonth($date), - ]; + $summary[] = ['month' => $date->format('F'), 'income' => $tj->getSumOfIncomesByMonth($date), 'expense' => $tj->getSumOfExpensesByMonth($date),]; $date->addMonth(); } diff --git a/app/controllers/SearchController.php b/app/controllers/SearchController.php index 49fe5ff1af..6217bdcac2 100644 --- a/app/controllers/SearchController.php +++ b/app/controllers/SearchController.php @@ -14,7 +14,7 @@ class SearchController extends BaseController throw new NotImplementedException; $subTitle = null; $rawQuery = null; - $result = []; + $result = []; if (!is_null(Input::get('q'))) { $rawQuery = trim(Input::get('q')); $words = explode(' ', $rawQuery); @@ -25,18 +25,12 @@ class SearchController extends BaseController $categories = $this->_helper->searchCategories($words); $budgets = $this->_helper->searchBudgets($words); $tags = $this->_helper->searchTags($words); - $result = [ - 'transactions' => $transactions, - 'accounts' => $accounts, - 'categories' => $categories, - 'budgets' => $budgets, - 'tags' => $tags - ]; + $result = ['transactions' => $transactions, 'accounts' => $accounts, 'categories' => $categories, 'budgets' => $budgets, 'tags' => $tags]; } return View::make('search.index')->with('title', 'Search')->with('subTitle', $subTitle)->with( 'mainTitleIcon', 'fa-search' - )->with('query', $rawQuery)->with('result',$result); + )->with('query', $rawQuery)->with('result', $result); } } \ No newline at end of file diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 32af9b1acc..2cf16b311c 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -23,36 +23,6 @@ class TransactionController extends BaseController View::share('mainTitleIcon', 'fa-repeat'); } - /** - * @param $what - * - * @return $this - */ - public function index($what) - { - - switch ($what) { - case 'expenses': - case 'withdrawal': - $subTitleIcon = 'fa-long-arrow-left'; - $subTitle = 'Expenses'; - break; - case 'revenue': - case 'deposit': - $subTitleIcon = 'fa-long-arrow-right'; - $subTitle = 'Revenue, income and deposits'; - break; - case 'transfer': - case 'transfers': - $subTitleIcon = 'fa-arrows-h'; - $subTitle = 'Transfers'; - break; - } - - return View::make('transactions.index', compact('subTitle', 'subTitleIcon'))->with('what', $what); - - } - /** * Shows the view helping the user to create a new transaction journal. * @@ -122,7 +92,6 @@ class TransactionController extends BaseController } - /** * @param TransactionJournal $transactionJournal * @@ -201,12 +170,7 @@ class TransactionController extends BaseController /* * Data to properly display the edit form. */ - $prefilled = [ - 'date' => $journal->date->format('Y-m-d'), - 'category' => '', - 'budget_id' => 0, - 'piggybank_id' => $piggyBankId - ]; + $prefilled = ['date' => $journal->date->format('Y-m-d'), 'category' => '', 'budget_id' => 0, 'piggybank_id' => $piggyBankId]; /* * Fill in the category. @@ -245,6 +209,7 @@ class TransactionController extends BaseController /* * Show the view. */ + return View::make('transactions.edit')->with('journal', $journal)->with('accounts', $accounts)->with( 'what', $what )->with('budgets', $budgets)->with('data', $prefilled)->with('piggies', $piggies)->with( @@ -252,6 +217,36 @@ class TransactionController extends BaseController ); } + /** + * @param $what + * + * @return $this + */ + public function index($what) + { + + switch ($what) { + case 'expenses': + case 'withdrawal': + $subTitleIcon = 'fa-long-arrow-left'; + $subTitle = 'Expenses'; + break; + case 'revenue': + case 'deposit': + $subTitleIcon = 'fa-long-arrow-right'; + $subTitle = 'Revenue, income and deposits'; + break; + case 'transfer': + case 'transfers': + $subTitleIcon = 'fa-arrows-h'; + $subTitle = 'Transfers'; + break; + } + + return View::make('transactions.index', compact('subTitle', 'subTitleIcon'))->with('what', $what); + + } + /** * @param TransactionJournal $journal * @@ -273,8 +268,8 @@ class TransactionController extends BaseController */ public function store($what) { - $data = Input::except('_token'); - $data['what'] = $what; + $data = Input::except('_token'); + $data['what'] = $what; $data['currency'] = 'EUR'; /** @var \FireflyIII\Database\TransactionJournal $repository */ @@ -292,6 +287,7 @@ class TransactionController extends BaseController Session::flash('warnings', $messages['warnings']); Session::flash('successes', $messages['successes']); Session::flash('error', 'Could not save transaction: ' . $messages['errors']->first()); + return Redirect::route('transactions.create', $what)->withInput()->withErrors($messages['errors']); } // store! @@ -301,7 +297,7 @@ class TransactionController extends BaseController if ($data['post_submit_action'] == 'create_another') { return Redirect::route('transactions.create', $what); } else { - return Redirect::route('transactions.index',$what); + return Redirect::route('transactions.index', $what); } break; case 'validate_only': @@ -310,7 +306,7 @@ class TransactionController extends BaseController Session::flash('successes', $messageBags['successes']); Session::flash('errors', $messageBags['errors']); - return Redirect::route('transactions.create',$what)->withInput(); + return Redirect::route('transactions.create', $what)->withInput(); break; } @@ -335,6 +331,7 @@ class TransactionController extends BaseController */ if ($messageBag->count() > 0) { Session::flash('error', 'Could not save transaction: ' . $messageBag->first()); + return Redirect::route('transactions.create', [$what])->withInput()->withErrors($messageBag); } @@ -359,6 +356,7 @@ class TransactionController extends BaseController Session::flash('warnings', $messageBags['warnings']); Session::flash('successes', $messageBags['successes']); Session::flash('errors', $messageBags['errors']); + return Redirect::route('transactions.create', [$what])->withInput(); break; default: @@ -408,6 +406,7 @@ class TransactionController extends BaseController Session::flash('warnings', $messageBags['warnings']); Session::flash('successes', $messageBags['successes']); Session::flash('errors', $messageBags['errors']); + return Redirect::route('transactions.edit', $journal->id)->withInput(); break; default: diff --git a/app/controllers/UserController.php b/app/controllers/UserController.php index 60300f52e7..18ca03429a 100644 --- a/app/controllers/UserController.php +++ b/app/controllers/UserController.php @@ -23,6 +23,18 @@ class UserController extends BaseController return View::make('user.login'); } + /** + * Logout user. + * + * @return \Illuminate\Http\RedirectResponse + */ + public function logout() + { + Auth::logout(); + Session::flush(); + + return Redirect::route('index'); + } /** * Login. @@ -32,10 +44,7 @@ class UserController extends BaseController public function postLogin() { $rememberMe = Input::get('remember_me') == '1'; - $data = [ - 'email' => Input::get('email'), - 'password' => Input::get('password') - ]; + $data = ['email' => Input::get('email'), 'password' => Input::get('password')]; $result = Auth::attempt($data, $rememberMe); if ($result) { return Redirect::route('index'); @@ -46,20 +55,6 @@ class UserController extends BaseController return View::make('user.login'); } - /** - * If allowed, show the register form. - * - * @return $this|\Illuminate\View\View - */ - public function register() - { - if (Config::get('auth.allow_register') !== true) { - return View::make('error')->with('message', 'Not possible'); - } - - return View::make('user.register'); - } - /** * If allowed, register the user. * @@ -85,7 +80,6 @@ class UserController extends BaseController $user = $repository->register(Input::all()); - //$user = $this->user->register(Input::all()); if ($user) { if (Config::get('auth.verify_mail') === true) { @@ -101,29 +95,6 @@ class UserController extends BaseController return View::make('user.register'); } - /** - * Logout user. - * - * @return \Illuminate\Http\RedirectResponse - */ - public function logout() - { - Auth::logout(); - Session::flush(); - - return Redirect::route('index'); - } - - /** - * Show form to help user get a new password. - * - * @return \Illuminate\View\View - */ - public function remindme() - { - return View::make('user.remindme'); - } - /** * If need to verify, send new reset code. * Otherwise, send new password. @@ -157,6 +128,30 @@ class UserController extends BaseController } + /** + * If allowed, show the register form. + * + * @return $this|\Illuminate\View\View + */ + public function register() + { + if (Config::get('auth.allow_register') !== true) { + return View::make('error')->with('message', 'Not possible'); + } + + return View::make('user.register'); + } + + /** + * Show form to help user get a new password. + * + * @return \Illuminate\View\View + */ + public function remindme() + { + return View::make('user.remindme'); + } + /** * Send a user a password based on his reset code. * From 4aa9a045161923cf5fe63e744f8d268bcb3d8f6b Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 12 Nov 2014 22:37:09 +0100 Subject: [PATCH 019/193] Code clean up and reformat. --- app/lib/FireflyIII/Database/Account.php | 475 ++++++++-------- app/lib/FireflyIII/Database/AccountType.php | 157 +++--- app/lib/FireflyIII/Database/Budget.php | 245 ++++---- app/lib/FireflyIII/Database/Category.php | 168 +++--- .../Database/Ifaces/AccountInterface.php | 62 +-- .../Database/Ifaces/BudgetInterface.php | 2 +- app/lib/FireflyIII/Database/Ifaces/CUD.php | 44 +- .../Database/Ifaces/CategoryInterface.php | 3 - .../Database/Ifaces/CommonDatabaseCalls.php | 29 +- .../Database/Ifaces/RecurringInterface.php | 1 + .../Ifaces/RecurringTransactionInterface.php | 2 - .../Ifaces/TransactionJournalInterface.php | 22 +- app/lib/FireflyIII/Database/Piggybank.php | 189 +++---- app/lib/FireflyIII/Database/Recurring.php | 117 ++-- .../Database/RecurringTransaction.php | 85 ++- app/lib/FireflyIII/Database/Transaction.php | 133 +++-- .../Database/TransactionCurrency.php | 82 +-- .../Database/TransactionJournal.php | 527 +++++++++--------- .../FireflyIII/Database/TransactionType.php | 151 ++--- app/lib/FireflyIII/Database/User.php | 46 +- .../Exception/ValidationException.php | 3 +- app/lib/FireflyIII/Form/Form.php | 295 +++++----- app/lib/FireflyIII/Shared/Json/Account.php | 3 +- app/lib/FireflyIII/Shared/Json/Json.php | 39 +- .../FireflyIII/Shared/Mail/Registration.php | 48 +- .../Shared/Mail/RegistrationInterface.php | 14 +- .../Preferences/PreferencesInterface.php | 16 +- .../Shared/SingleTableInheritanceEntity.php | 68 ++- app/lib/FireflyIII/Shared/Toolkit/Date.php | 67 +-- app/lib/FireflyIII/Shared/Toolkit/Filter.php | 52 +- app/lib/FireflyIII/Shared/Toolkit/Form.php | 6 +- .../FireflyIII/Shared/Toolkit/Navigation.php | 2 + .../Validation/ValidationServiceProvider.php | 1 + 33 files changed, 1543 insertions(+), 1611 deletions(-) diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index e345a1c6d0..414f046379 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -29,64 +29,54 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } /** - * @param Ardent $model - * @param array $data + * @param array $types * - * @return bool + * @return int */ - public function update(Ardent $model, array $data) + public function countAccountsByType(array $types) { - $model->name = $data['name']; - $model->active = isset($data['active']) ? intval($data['active']) : 0; - $model->save(); + return $this->getUser()->accounts()->accountTypeIn($types)->count(); + } - if (isset($data['openingbalance']) && isset($data['openingbalancedate'])) { - $openingBalance = $this->openingBalanceTransaction($model); + /** + * @return int + */ + public function countAssetAccounts() + { + return $this->countAccountsByType(['Default account', 'Asset account']); + } - $openingBalance->date = new Carbon($data['openingbalancedate']); - $openingBalance->save(); - $amount = floatval($data['openingbalance']); - /** @var \Transaction $transaction */ - foreach ($openingBalance->transactions as $transaction) { - if ($transaction->account_id == $model->id) { - $transaction->amount = $amount; - } else { - $transaction->amount = $amount * -1; - } - $transaction->save(); - } - } - return true; + /** + * @return int + */ + public function countExpenseAccounts() + { + return $this->countAccountsByType(['Expense account', 'Beneficiary account']); + } + + /** + * Counts the number of total revenue accounts. Useful for DataTables. + * + * @return int + */ + public function countRevenueAccounts() + { + return $this->countAccountsByType(['Revenue account']); } /** * @param \Account $account * - * @return \TransactionJournal|null + * @return \Account|null */ - public function openingBalanceTransaction(\Account $account) + public function findInitialBalanceAccount(\Account $account) { - return \TransactionJournal::withRelevantData() - ->accountIs($account) - ->leftJoin( - 'transaction_types', 'transaction_types.id', '=', - 'transaction_journals.transaction_type_id' - ) - ->where('transaction_types.type', 'Opening balance') - ->first(['transaction_journals.*']); - } + /** @var \FireflyIII\Database\AccountType $acctType */ + $acctType = \App::make('FireflyIII\Database\AccountType'); - /** - * Get all asset accounts. Optional JSON based parameters. - * - * @param array $parameters - * - * @return Collection - */ - public function getAssetAccounts(array $parameters = []) - { - return $this->getAccountsByType(['Default account', 'Asset account'], $parameters); + $accountType = $acctType->findByWhat('initial'); + return $this->getUser()->accounts()->where('account_type_id', $accountType->id)->where('name', 'LIKE', $account->name . '%')->first(); } /** @@ -149,44 +139,27 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } /** - * @param \Account $account + * Get all asset accounts. Optional JSON based parameters. * - * @return \Account|null - */ - public function findInitialBalanceAccount(\Account $account) - { - /** @var \FireflyIII\Database\AccountType $acctType */ - $acctType = \App::make('FireflyIII\Database\AccountType'); - - $accountType = $acctType->findByWhat('initial'); - - return $this->getUser()->accounts()->where('account_type_id', $accountType->id)->where('name', 'LIKE', $account->name . '%')->first(); - } - - /** - * @return int - */ - public function countAssetAccounts() - { - return $this->countAccountsByType(['Default account', 'Asset account']); - } - - /** - * @param array $types + * @param array $parameters * - * @return int + * @return Collection */ - public function countAccountsByType(array $types) + public function getAssetAccounts(array $parameters = []) { - return $this->getUser()->accounts()->accountTypeIn($types)->count(); + return $this->getAccountsByType(['Default account', 'Asset account'], $parameters); + } /** - * @return int + * Get all default accounts. + * + * @return Collection */ - public function countExpenseAccounts() + public function getDefaultAccounts() { - return $this->countAccountsByType(['Expense account', 'Beneficiary account']); + // TODO: Implement getDefaultAccounts() method. + throw new NotImplementedException; } /** @@ -199,45 +172,6 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface return $this->getAccountsByType(['Expense account', 'Beneficiary account'], $parameters); } - /** - * Returns an object with id $id. - * - * @param int $id - * - * @return Ardent - */ - public function find($id) - { - return $this->getUser()->accounts()->find($id); - } - - public function firstExpenseAccountOrCreate($name) - { - /** @var \FireflyIII\Database\AccountType $accountTypeRepos */ - $accountTypeRepos = \App::make('FireflyIII\Database\AccountType'); - - $accountType = $accountTypeRepos->findByWhat('expense'); - - $data = [ - 'user_id' => $this->getUser()->id, - 'account_type_id' => $accountType->id, - 'name' => $name, - 'active' => 1 - ]; - return \Account::firstOrCreate($data); - - } - - /** - * Counts the number of total revenue accounts. Useful for DataTables. - * - * @return int - */ - public function countRevenueAccounts() - { - return $this->countAccountsByType(['Revenue account']); - } - /** * Get all revenue accounts. * @@ -250,6 +184,65 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface return $this->getAccountsByType(['Revenue account'], $parameters); } + /** + * @param \Account $account + * + * @return \TransactionJournal|null + */ + public function openingBalanceTransaction(\Account $account) + { + return \TransactionJournal::withRelevantData()->accountIs($account)->leftJoin( + 'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id' + )->where('transaction_types.type', 'Opening balance')->first(['transaction_journals.*']); + } + + /** + * @param \Account $account + * @param array $data + * + * @return bool + */ + public function storeInitialBalance(\Account $account, array $data) + { + $opposingData = ['name' => $account->name . ' Initial Balance', 'active' => 0, 'what' => 'initial']; + $opposingAccount = $this->store($opposingData); + + /* + * Create a journal from opposing to account or vice versa. + */ + $balance = floatval($data['openingbalance']); + $date = new Carbon($data['openingbalancedate']); + /** @var \FireflyIII\Database\TransactionJournal $tj */ + $tj = \App::make('FireflyIII\Database\TransactionJournal'); + if ($balance < 0) { + // first transaction draws money from the new account to the opposing + $from = $account; + $to = $opposingAccount; + } else { + // first transaction puts money into account + $from = $opposingAccount; + $to = $account; + } + + // data for transaction journal: + $balance = $balance < 0 ? $balance * -1 : $balance; + $opening = ['what' => 'opening', 'currency' => 'EUR', 'amount' => $balance, 'from' => $from, 'to' => $to, 'date' => $date, + 'description' => 'Opening balance for new account ' . $account->name,]; + + + $validation = $tj->validate($opening); + if ($validation['errors']->count() == 0) { + $tj->store($opening); + + return true; + } else { + var_dump($validation['errors']); + exit; + } + + return false; + } + /** * @param Ardent $model * @@ -258,10 +251,83 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface public function destroy(Ardent $model) { $model->delete(); + return true; } + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + + /* + * Find account type. + */ + /** @var \FireflyIII\Database\AccountType $acctType */ + $acctType = \App::make('FireflyIII\Database\AccountType'); + + $accountType = $acctType->findByWhat($data['what']); + + $data['user_id'] = $this->getUser()->id; + $data['account_type_id'] = $accountType->id; + $data['active'] = isset($data['active']) && $data['active'] === '1' ? 1 : 0; + + + $data = array_except($data, ['_token', 'what']); + $account = new \Account($data); + if (!$account->validate()) { + var_dump($account->errors()->all()); + exit; + } + $account->save(); + if (isset($data['openingbalance']) && floatval($data['openingbalance']) != 0) { + $this->storeInitialBalance($account, $data); + } + + + /* Tell transaction journal to store a new one.*/ + + + return $account; + + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + $model->name = $data['name']; + $model->active = isset($data['active']) ? intval($data['active']) : 0; + $model->save(); + + if (isset($data['openingbalance']) && isset($data['openingbalancedate'])) { + $openingBalance = $this->openingBalanceTransaction($model); + + $openingBalance->date = new Carbon($data['openingbalancedate']); + $openingBalance->save(); + $amount = floatval($data['openingbalance']); + /** @var \Transaction $transaction */ + foreach ($openingBalance->transactions as $transaction) { + if ($transaction->account_id == $model->id) { + $transaction->amount = $amount; + } else { + $transaction->amount = $amount * -1; + } + $transaction->save(); + } + } + + return true; + } + /** * Validates a model. Returns an array containing MessageBags * errors/warnings/successes. @@ -272,9 +338,9 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface */ public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; /* * Name validation: @@ -327,139 +393,34 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface if (!$errors->has('openingbalancedate')) { $successes->add('openingbalancedate', 'OK'); } - return [ - 'errors' => $errors, - 'warnings' => $warnings, - 'successes' => $successes - ]; + + return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } /** - * @param array $data + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param Ardent $model + * + * @return array + */ + public function validateObject(Ardent $model) + { + // TODO: Implement validateObject() method. + throw new NotImplementedException; + } + + /** + * Returns an object with id $id. + * + * @param int $id * * @return Ardent */ - public function store(array $data) + public function find($id) { - - /* - * Find account type. - */ - /** @var \FireflyIII\Database\AccountType $acctType */ - $acctType = \App::make('FireflyIII\Database\AccountType'); - - $accountType = $acctType->findByWhat($data['what']); - - $data['user_id'] = $this->getUser()->id; - $data['account_type_id'] = $accountType->id; - $data['active'] = isset($data['active']) && $data['active'] === '1' ? 1 : 0; - - - $data = array_except($data, array('_token', 'what')); - $account = new \Account($data); - if (!$account->validate()) { - var_dump($account->errors()->all()); - exit; - } - $account->save(); - if (isset($data['openingbalance']) && floatval($data['openingbalance']) != 0) { - $this->storeInitialBalance($account, $data); - } - - - /* Tell transaction journal to store a new one.*/ - - - return $account; - - } - - /** - * @param \Account $account - * @param array $data - * - * @return bool - */ - public function storeInitialBalance(\Account $account, array $data) - { - $opposingData = [ - 'name' => $account->name . ' Initial Balance', - 'active' => 0, - 'what' => 'initial' - ]; - $opposingAccount = $this->store($opposingData); - - /* - * Create a journal from opposing to account or vice versa. - */ - $balance = floatval($data['openingbalance']); - $date = new Carbon($data['openingbalancedate']); - /** @var \FireflyIII\Database\TransactionJournal $tj */ - $tj = \App::make('FireflyIII\Database\TransactionJournal'); - if ($balance < 0) { - // first transaction draws money from the new account to the opposing - $from = $account; - $to = $opposingAccount; - } else { - // first transaction puts money into account - $from = $opposingAccount; - $to = $account; - } - - // data for transaction journal: - $balance = $balance < 0 ? $balance * -1 : $balance; - $opening = [ - 'what' => 'opening', - 'currency' => 'EUR', - 'amount' => $balance, - 'from' => $from, - 'to' => $to, - 'date' => $date, - 'description' => 'Opening balance for new account ' . $account->name, - ]; - - - $validation = $tj->validate($opening); - if ($validation['errors']->count() == 0) { - $tj->store($opening); - return true; - } else { - var_dump($validation['errors']); - exit; - } - return false; - } - - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - return $this->getUser()->accounts()->whereIn('id', $ids)->get(); - } - - /** - * Get all default accounts. - * - * @return Collection - */ - public function getDefaultAccounts() - { - // TODO: Implement getDefaultAccounts() method. - throw new NotImplementedException; - } - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - // TODO: Implement get() method. - throw new NotImplementedException; + return $this->getUser()->accounts()->find($id); } /** @@ -476,16 +437,36 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. + * Returns all objects. * - * @param Ardent $model - * - * @return array + * @return Collection */ - public function validateObject(Ardent $model) + public function get() { - // TODO: Implement validateObject() method. + // TODO: Implement get() method. throw new NotImplementedException; } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + return $this->getUser()->accounts()->whereIn('id', $ids)->get(); + } + + public function firstExpenseAccountOrCreate($name) + { + /** @var \FireflyIII\Database\AccountType $accountTypeRepos */ + $accountTypeRepos = \App::make('FireflyIII\Database\AccountType'); + + $accountType = $accountTypeRepos->findByWhat('expense'); + + $data = ['user_id' => $this->getUser()->id, 'account_type_id' => $accountType->id, 'name' => $name, 'active' => 1]; + + return \Account::firstOrCreate($data); + + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/AccountType.php b/app/lib/FireflyIII/Database/AccountType.php index 5d101c1653..0c5341d1c5 100644 --- a/app/lib/FireflyIII/Database/AccountType.php +++ b/app/lib/FireflyIII/Database/AccountType.php @@ -3,12 +3,12 @@ namespace FireflyIII\Database; use Firefly\Exception\FireflyException; -use FireflyIII\Exception\NotImplementedException; -use Illuminate\Support\Collection; -use LaravelBook\Ardent\Ardent; use FireflyIII\Database\Ifaces\AccountTypeInterface; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; +use FireflyIII\Exception\NotImplementedException; +use Illuminate\Support\Collection; +use LaravelBook\Ardent\Ardent; /** * Class AccountType @@ -18,6 +18,81 @@ use FireflyIII\Database\Ifaces\CUD; class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls { + /** + * @param Ardent $model + * + * @return bool + */ + public function destroy(Ardent $model) + { + // TODO: Implement destroy() method. + throw new NotImplementedException; + } + + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. + throw new NotImplementedException; + } + + /** + * Validates an array. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param array $model + * + * @return array + */ + public function validate(array $model) + { + // TODO: Implement validate() method. + throw new NotImplementedException; + } + + /** + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param Ardent $model + * + * @return array + */ + public function validateObject(Ardent $model) + { + // TODO: Implement validateObject() method. + throw new NotImplementedException; + } + + /** + * Returns an object with id $id. + * + * @param int $id + * + * @return Ardent + */ + public function find($id) + { + // TODO: Implement find() method. + throw new NotImplementedException; + } + /** * Finds an account type using one of the "$what"'s: expense, asset, revenue * @@ -46,84 +121,10 @@ class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls break; } + return null; } - /** - * @param Ardent $model - * - * @return bool - */ - public function destroy(Ardent $model) - { - // TODO: Implement destroy() method. - throw new NotImplementedException; - } - - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - - /** - * Validates an array. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param array $model - * - * @return array - */ - public function validate(array $model) - { - // TODO: Implement validate() method. - throw new NotImplementedException; - } - - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - // TODO: Implement store() method. - throw new NotImplementedException; - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - // TODO: Implement update() method. - throw new NotImplementedException; - } - - /** - * Returns an object with id $id. - * - * @param int $id - * - * @return Ardent - */ - public function find($id) - { - // TODO: Implement find() method. - throw new NotImplementedException; - } - /** * Returns all objects. * diff --git a/app/lib/FireflyIII/Database/Budget.php b/app/lib/FireflyIII/Database/Budget.php index 0d0eda4be3..03aa341f7b 100644 --- a/app/lib/FireflyIII/Database/Budget.php +++ b/app/lib/FireflyIII/Database/Budget.php @@ -27,22 +27,6 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface $this->setUser(\Auth::user()); } - /** - * @param \Budget $budget - * @param Carbon $date - * - * @return \LimitRepetition|null - */ - public function repetitionOnStartingOnDate(\Budget $budget, Carbon $date) - { - return \LimitRepetition:: - leftJoin('limits', 'limit_repetitions.limit_id', '=', 'limits.id')->leftJoin( - 'components', 'limits.component_id', '=', 'components.id' - )->where('limit_repetitions.startdate', $date->format('Y-m-d'))->where( - 'components.id', $budget->id - )->first(['limit_repetitions.*']); - } - /** * @param Ardent $model * @@ -51,9 +35,50 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface public function destroy(Ardent $model) { $model->delete(); + return true; } + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + $data['user_id'] = $this->getUser()->id; + + $budget = new \Budget($data); + $budget->class = 'Budget'; + + if (!$budget->validate()) { + var_dump($budget->errors()->all()); + exit; + } + $budget->save(); + + return $budget; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + $model->name = $data['name']; + if (!$model->validate()) { + var_dump($model->errors()->all()); + exit; + } + + + $model->save(); + + return true; + } /** * Validates an array. Returns an array containing MessageBags @@ -65,9 +90,9 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface */ public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; if (isset($model['name'])) { if (strlen($model['name']) < 1) { @@ -91,103 +116,7 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface $successes->add('name', 'OK'); } - return [ - 'errors' => $errors, - 'warnings' => $warnings, - 'successes' => $successes - ]; - } - - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - $data['user_id'] = $this->getUser()->id; - - $budget = new \Budget($data); - $budget->class = 'Budget'; - - if (!$budget->validate()) { - var_dump($budget->errors()->all()); - exit; - } - $budget->save(); - return $budget; - } - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - $budgets = $this->getUser()->budgets()->get(); - - return $budgets; - } - - /** - * @param \Budget $budget - * @param Carbon $date - * - * @return float - */ - public function spentInMonth(\Budget $budget, Carbon $date) - { - $end = clone $date; - $date->startOfMonth(); - $end->endOfMonth(); - $sum = floatval($budget->transactionjournals()->before($end)->after($date)->lessThan(0)->sum('amount')) * -1; - return $sum; - } - - - /** - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - public function transactionsWithoutBudgetInDateRange(Carbon $start, Carbon $end) - { - // Add expenses that have no budget: - return \Auth::user()->transactionjournals()->whereNotIn( - 'transaction_journals.id', function ($query) use ($start, $end) { - $query->select('transaction_journals.id')->from('transaction_journals') - ->leftJoin( - 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', - 'transaction_journals.id' - ) - ->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) - ->where('components.class', 'Budget'); - } - )->before($end)->after($start)->lessThan(0)->transactionTypes(['Withdrawal'])->get(); - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - $model->name = $data['name']; - if (!$model->validate()) { - var_dump($model->errors()->all()); - exit; - } - - - $model->save(); - - return true; + return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } /** @@ -217,17 +146,6 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface throw new NotImplementedException; } - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. - throw new NotImplementedException; - } - /** * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. * @@ -240,4 +158,79 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface // TODO: Implement findByWhat() method. throw new NotImplementedException; } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + $budgets = $this->getUser()->budgets()->get(); + + return $budgets; + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } + + /** + * @param \Budget $budget + * @param Carbon $date + * + * @return \LimitRepetition|null + */ + public function repetitionOnStartingOnDate(\Budget $budget, Carbon $date) + { + return \LimitRepetition:: + leftJoin('limits', 'limit_repetitions.limit_id', '=', 'limits.id')->leftJoin( + 'components', 'limits.component_id', '=', 'components.id' + )->where('limit_repetitions.startdate', $date->format('Y-m-d'))->where( + 'components.id', $budget->id + )->first(['limit_repetitions.*']); + } + + /** + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function transactionsWithoutBudgetInDateRange(Carbon $start, Carbon $end) + { + // Add expenses that have no budget: + return \Auth::user()->transactionjournals()->whereNotIn( + 'transaction_journals.id', function ($query) use ($start, $end) { + $query->select('transaction_journals.id')->from('transaction_journals')->leftJoin( + 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' + )->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')->where( + 'transaction_journals.date', '>=', $start->format('Y-m-d') + )->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->where('components.class', 'Budget'); + } + )->before($end)->after($start)->lessThan(0)->transactionTypes(['Withdrawal'])->get(); + } + + /** + * @param \Budget $budget + * @param Carbon $date + * + * @return float + */ + public function spentInMonth(\Budget $budget, Carbon $date) + { + $end = clone $date; + $date->startOfMonth(); + $end->endOfMonth(); + $sum = floatval($budget->transactionjournals()->before($end)->after($date)->lessThan(0)->sum('amount')) * -1; + + return $sum; + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Category.php b/app/lib/FireflyIII/Database/Category.php index 5c378a2704..0e4085e439 100644 --- a/app/lib/FireflyIII/Database/Category.php +++ b/app/lib/FireflyIII/Database/Category.php @@ -35,9 +35,40 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface public function destroy(Ardent $model) { $model->delete(); + return true; } + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + $model->name = $data['name']; + if (!$model->validate()) { + var_dump($model->errors()->all()); + exit; + } + + + $model->save(); + + return true; + } /** * Validates an array. Returns an array containing MessageBags @@ -49,9 +80,9 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface */ public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; if (isset($model['name'])) { if (strlen($model['name']) < 1) { @@ -75,68 +106,7 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface $successes->add('name', 'OK'); } - return [ - 'errors' => $errors, - 'warnings' => $warnings, - 'successes' => $successes - ]; - } - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - return $this->getUser()->categories()->orderBy('name', 'ASC')->get(); - } - - - /** - * @param \Category $budget - * @param Carbon $date - * - * @return null - */ - public function repetitionOnStartingOnDate(\Category $category, Carbon $date) - { - return null; - } - - /** - * @param \Category $category - * @param Carbon $date - * - * @return float - */ - public function spentInMonth(\Category $category, Carbon $date) - { - $end = clone $date; - $date->startOfMonth(); - $end->endOfMonth(); - $sum = floatval($category->transactionjournals()->before($end)->after($date)->lessThan(0)->sum('amount')) * -1; - return $sum; - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - $model->name = $data['name']; - if (!$model->validate()) { - var_dump($model->errors()->all()); - exit; - } - - - $model->save(); - - return true; + return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } /** @@ -153,17 +123,6 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface throw new NotImplementedException; } - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - // TODO: Implement store() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * @@ -177,17 +136,6 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface throw new NotImplementedException; } - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. - throw new NotImplementedException; - } - /** * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. * @@ -200,4 +148,52 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface // TODO: Implement findByWhat() method. throw new NotImplementedException; } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + return $this->getUser()->categories()->orderBy('name', 'ASC')->get(); + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } + + /** + * @param \Category $budget + * @param Carbon $date + * + * @return null + */ + public function repetitionOnStartingOnDate(\Category $category, Carbon $date) + { + return null; + } + + /** + * @param \Category $category + * @param Carbon $date + * + * @return float + */ + public function spentInMonth(\Category $category, Carbon $date) + { + $end = clone $date; + $date->startOfMonth(); + $end->endOfMonth(); + $sum = floatval($category->transactionjournals()->before($end)->after($date)->lessThan(0)->sum('amount')) * -1; + + return $sum; + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php b/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php index a24fa07421..2871e988f7 100644 --- a/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php +++ b/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php @@ -13,13 +13,13 @@ interface AccountInterface { /** - * Get all asset accounts. The parameters are optional and are provided by the DataTables plugin. + * Counts the number of accounts found with the included types. * - * @param array $parameters + * @param array $types * - * @return Collection + * @return int */ - public function getAssetAccounts(array $parameters = []); + public function countAccountsByType(array $types); /** * Counts the number of total asset accounts. Useful for DataTables. @@ -55,6 +55,32 @@ interface AccountInterface */ public function findInitialBalanceAccount(\Account $account); + /** + * Get all accounts of the selected types. Is also capable of handling DataTables' parameters. + * + * @param array $types + * @param array $parameters + * + * @return Collection + */ + public function getAccountsByType(array $types, array $parameters = []); + + /** + * Get all asset accounts. The parameters are optional and are provided by the DataTables plugin. + * + * @param array $parameters + * + * @return Collection + */ + public function getAssetAccounts(array $parameters = []); + + /** + * Get all default accounts. + * + * @return Collection + */ + public function getDefaultAccounts(); + public function getExpenseAccounts(array $parameters = []); /** @@ -66,32 +92,6 @@ interface AccountInterface */ public function getRevenueAccounts(array $parameters = []); - /** - * Get all accounts of the selected types. Is also capable of handling DataTables' parameters. - * - * @param array $types - * @param array $parameters - * - * @return Collection - */ - public function getAccountsByType(array $types, array $parameters = []); - - /** - * Counts the number of accounts found with the included types. - * - * @param array $types - * - * @return int - */ - public function countAccountsByType(array $types); - - /** - * Get all default accounts. - * - * @return Collection - */ - public function getDefaultAccounts(); - /** * @param \Account $account * @@ -101,7 +101,7 @@ interface AccountInterface /** * @param \Account $account - * @param array $data + * @param array $data * * @return bool */ diff --git a/app/lib/FireflyIII/Database/Ifaces/BudgetInterface.php b/app/lib/FireflyIII/Database/Ifaces/BudgetInterface.php index 17fd25dbe9..149970cbc2 100644 --- a/app/lib/FireflyIII/Database/Ifaces/BudgetInterface.php +++ b/app/lib/FireflyIII/Database/Ifaces/BudgetInterface.php @@ -14,7 +14,7 @@ interface BudgetInterface { /** * @param \Budget $budget - * @param Carbon $date + * @param Carbon $date * * @return \LimitRepetition|null */ diff --git a/app/lib/FireflyIII/Database/Ifaces/CUD.php b/app/lib/FireflyIII/Database/Ifaces/CUD.php index 3c457f8629..70578007e7 100644 --- a/app/lib/FireflyIII/Database/Ifaces/CUD.php +++ b/app/lib/FireflyIII/Database/Ifaces/CUD.php @@ -1,11 +1,12 @@ setUser(\Auth::user()); } - /** - * @param \Account $account - * - * @return float - */ - public function leftOnAccount(\Account $account) - { - $balance = $account->balance(); - /** @var \Piggybank $p */ - foreach ($account->piggybanks()->get() as $p) { - $balance -= $p->currentRelevantRep()->currentamount; - } - - return $balance; - - } - /** * @param Ardent $model * @@ -54,6 +37,56 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface $model->delete(); } + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + $data['rep_every'] = isset($data['rep_every']) ? $data['rep_every'] : 0; + $data['reminder_skip'] = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0; + $data['order'] = isset($data['order']) ? $data['order'] : 0; + $data['remind_me'] = isset($data['remind_me']) ? intval($data['remind_me']) : 0; + $data['startdate'] = isset($data['startdate']) ? $data['startdate'] : Carbon::now()->format('Y-m-d'); + $data['targetdate'] = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null; + + + $piggybank = new \Piggybank($data); + if (!$piggybank->validate()) { + var_dump($piggybank->errors()->all()); + exit; + } + $piggybank->save(); + \Event::fire('piggybanks.store', [$piggybank]); + $piggybank->save(); + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + /** @var \Piggybank $model */ + $model->name = $data['name']; + $model->account_id = intval($data['account_id']); + $model->targetamount = floatval($data['targetamount']); + $model->targetdate = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null; + $model->rep_every = isset($data['rep_every']) ? $data['rep_every'] : 0; + $model->reminder_skip = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0; + $model->order = isset($data['order']) ? $data['order'] : 0; + $model->remind_me = isset($data['remind_me']) ? intval($data['remind_me']) : 0; + if (!$model->validate()) { + var_dump($model->errors()); + exit(); + } + $model->save(); + + return true; + } /** * Validates an array. Returns an array containing MessageBags @@ -65,9 +98,9 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface */ public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; /* * Name validation: @@ -104,7 +137,7 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface } // check period. if (!$errors->has('reminder') && !$errors->has('targetdate') && isset($model['remind_me']) && intval($model['remind_me']) == 1) { - $today = new Carbon; + $today = new Carbon; $target = new Carbon($model['targetdate']); switch ($model['reminder']) { case 'week': @@ -135,72 +168,7 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface } } - return [ - 'errors' => $errors, - 'warnings' => $warnings, - 'successes' => $successes - ]; - } - - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - $data['rep_every'] = isset($data['rep_every']) ? $data['rep_every'] : 0; - $data['reminder_skip'] = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0; - $data['order'] = isset($data['order']) ? $data['order'] : 0; - $data['remind_me'] = isset($data['remind_me']) ? intval($data['remind_me']) : 0; - $data['startdate'] = isset($data['startdate']) ? $data['startdate'] : Carbon::now()->format('Y-m-d'); - $data['targetdate'] = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null; - - - $piggybank = new \Piggybank($data); - if (!$piggybank->validate()) { - var_dump($piggybank->errors()->all()); - exit; - } - $piggybank->save(); - \Event::fire('piggybanks.store', [$piggybank]); - $piggybank->save(); - } - - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - return $this->getUser()->piggybanks()->where('repeats', 0)->get(); - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - /** @var \Piggybank $model */ - $model->name = $data['name']; - $model->account_id = intval($data['account_id']); - $model->targetamount = floatval($data['targetamount']); - $model->targetdate = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null; - $model->rep_every = isset($data['rep_every']) ? $data['rep_every'] : 0; - $model->reminder_skip = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0; - $model->order = isset($data['order']) ? $data['order'] : 0; - $model->remind_me = isset($data['remind_me']) ? intval($data['remind_me']) : 0; - if (!$model->validate()) { - var_dump($model->errors()); - exit(); - } - $model->save(); - return true; + return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } /** @@ -230,17 +198,6 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface throw new NotImplementedException; } - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. - throw new NotImplementedException; - } - /** * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. * @@ -253,4 +210,42 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface // TODO: Implement findByWhat() method. throw new NotImplementedException; } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + return $this->getUser()->piggybanks()->where('repeats', 0)->get(); + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } + + /** + * @param \Account $account + * + * @return float + */ + public function leftOnAccount(\Account $account) + { + $balance = $account->balance(); + /** @var \Piggybank $p */ + foreach ($account->piggybanks()->get() as $p) { + $balance -= $p->currentRelevantRep()->currentamount; + } + + return $balance; + + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Recurring.php b/app/lib/FireflyIII/Database/Recurring.php index 410de6a3a6..d7d4bd4de3 100644 --- a/app/lib/FireflyIII/Database/Recurring.php +++ b/app/lib/FireflyIII/Database/Recurring.php @@ -4,12 +4,12 @@ namespace FireflyIII\Database; use Carbon\Carbon; -use FireflyIII\Exception\NotImplementedException; -use Illuminate\Support\Collection; -use LaravelBook\Ardent\Ardent; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\RecurringInterface; +use FireflyIII\Exception\NotImplementedException; +use Illuminate\Support\Collection; +use LaravelBook\Ardent\Ardent; /** * Class Recurring @@ -28,30 +28,6 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface $this->setUser(\Auth::user()); } - /** - * @param \RecurringTransaction $recurring - * @param Carbon $start - * @param Carbon $end - * - * @return \TransactionJournal|null - */ - public function getJournalForRecurringInRange(\RecurringTransaction $recurring, Carbon $start, Carbon $end) - { - return $this->getUser()->transactionjournals()->where('recurring_transaction_id', $recurring->id)->after($start)->before($end)->first(); - - } - - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - return $this->getUser()->recurringtransactions()->get(); - } - /** * @param Ardent $model * @@ -64,16 +40,25 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface } /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. + * @param array $data * - * @param Ardent $model - * - * @return array + * @return Ardent */ - public function validateObject(Ardent $model) + public function store(array $data) { - // TODO: Implement validateObject() method. + // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. throw new NotImplementedException; } @@ -92,25 +77,16 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface } /** - * @param array $data + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. * - * @return Ardent - */ - public function store(array $data) - { - // TODO: Implement store() method. - throw new NotImplementedException; - } - - /** * @param Ardent $model - * @param array $data * - * @return bool + * @return array */ - public function update(Ardent $model, array $data) + public function validateObject(Ardent $model) { - // TODO: Implement update() method. + // TODO: Implement validateObject() method. throw new NotImplementedException; } @@ -127,17 +103,6 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface throw new NotImplementedException; } - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. - throw new NotImplementedException; - } - /** * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. * @@ -150,4 +115,38 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface // TODO: Implement findByWhat() method. throw new NotImplementedException; } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + return $this->getUser()->recurringtransactions()->get(); + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } + + /** + * @param \RecurringTransaction $recurring + * @param Carbon $start + * @param Carbon $end + * + * @return \TransactionJournal|null + */ + public function getJournalForRecurringInRange(\RecurringTransaction $recurring, Carbon $start, Carbon $end) + { + return $this->getUser()->transactionjournals()->where('recurring_transaction_id', $recurring->id)->after($start)->before($end)->first(); + + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/RecurringTransaction.php b/app/lib/FireflyIII/Database/RecurringTransaction.php index 6eb8cac8f1..b4e80c489d 100644 --- a/app/lib/FireflyIII/Database/RecurringTransaction.php +++ b/app/lib/FireflyIII/Database/RecurringTransaction.php @@ -26,17 +26,6 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac $this->setUser(\Auth::user()); } - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - return $this->getUser()->recurringtransactions()->get(); - } - /** * @param Ardent $model * @@ -49,16 +38,25 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac } /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. + * @param array $data * - * @param Ardent $model - * - * @return array + * @return Ardent */ - public function validateObject(Ardent $model) + public function store(array $data) { - // TODO: Implement validateObject() method. + // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. throw new NotImplementedException; } @@ -77,25 +75,16 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac } /** - * @param array $data + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. * - * @return Ardent - */ - public function store(array $data) - { - // TODO: Implement store() method. - throw new NotImplementedException; - } - - /** * @param Ardent $model - * @param array $data * - * @return bool + * @return array */ - public function update(Ardent $model, array $data) + public function validateObject(Ardent $model) { - // TODO: Implement update() method. + // TODO: Implement validateObject() method. throw new NotImplementedException; } @@ -112,17 +101,6 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac throw new NotImplementedException; } - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. - throw new NotImplementedException; - } - /** * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. * @@ -135,4 +113,25 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac // TODO: Implement findByWhat() method. throw new NotImplementedException; } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + return $this->getUser()->recurringtransactions()->get(); + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Transaction.php b/app/lib/FireflyIII/Database/Transaction.php index 09d88c00c5..26a3d252d5 100644 --- a/app/lib/FireflyIII/Database/Transaction.php +++ b/app/lib/FireflyIII/Database/Transaction.php @@ -20,6 +20,55 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls { use SwitchUser; + /** + * @param Ardent $model + * + * @return bool + */ + public function destroy(Ardent $model) + { + // TODO: Implement destroy() method. + throw new NotImplementedException; + } + + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + $transaction = new \Transaction; + $transaction->account()->associate($data['account']); + $transaction->transactionJournal()->associate($data['transaction_journal']); + $transaction->amount = floatval($data['amount']); + if (isset($data['piggybank'])) { + $transaction->piggybank()->associate($data['piggybank']); + } + if (isset($data['description'])) { + $transaction->description = $data['description']; + } + if ($transaction->validate()) { + $transaction->save(); + } else { + throw new FireflyException($transaction->errors()->first()); + } + + return $transaction; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. + throw new NotImplementedException; + } + /** * Validates an array. Returns an array containing MessageBags * errors/warnings/successes. @@ -30,9 +79,9 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls */ public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; if (!isset($model['account_id']) && !isset($model['account'])) { @@ -83,47 +132,7 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls $successes->add('amount', 'OK'); } - return [ - 'errors' => $errors, - 'warnings' => $warnings, - 'successes' => $successes - ]; - } - - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - $transaction = new \Transaction; - $transaction->account()->associate($data['account']); - $transaction->transactionJournal()->associate($data['transaction_journal']); - $transaction->amount = floatval($data['amount']); - if (isset($data['piggybank'])) { - $transaction->piggybank()->associate($data['piggybank']); - } - if (isset($data['description'])) { - $transaction->description = $data['description']; - } - if ($transaction->validate()) { - $transaction->save(); - } else { - throw new FireflyException($transaction->errors()->first()); - } - return $transaction; - } - - /** - * @param Ardent $model - * - * @return bool - */ - public function destroy(Ardent $model) - { - // TODO: Implement destroy() method. - throw new NotImplementedException; + return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } /** @@ -140,18 +149,6 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls throw new NotImplementedException; } - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - // TODO: Implement update() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * @@ -165,6 +162,19 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls throw new NotImplementedException; } + /** + * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. + * + * @param $what + * + * @return \AccountType|null + */ + public function findByWhat($what) + { + // TODO: Implement findByWhat() method. + throw new NotImplementedException; + } + /** * Returns all objects. * @@ -186,17 +196,4 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls // TODO: Implement getByIds() method. throw new NotImplementedException; } - - /** - * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. - * - * @param $what - * - * @return \AccountType|null - */ - public function findByWhat($what) - { - // TODO: Implement findByWhat() method. - throw new NotImplementedException; - } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/TransactionCurrency.php b/app/lib/FireflyIII/Database/TransactionCurrency.php index 91cb15a869..82a4639345 100644 --- a/app/lib/FireflyIII/Database/TransactionCurrency.php +++ b/app/lib/FireflyIII/Database/TransactionCurrency.php @@ -3,12 +3,12 @@ namespace FireflyIII\Database; -use FireflyIII\Exception\NotImplementedException; -use Illuminate\Support\Collection; -use LaravelBook\Ardent\Ardent; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\TransactionCurrencyInterface; +use FireflyIII\Exception\NotImplementedException; +use Illuminate\Support\Collection; +use LaravelBook\Ardent\Ardent; /** * Class TransactionType @@ -19,16 +19,6 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa { - /** - * @param string $code - * - * @return \TransactionCurrency|null - */ - public function findByCode($code) - { - return \TransactionCurrency::whereCode($code)->first(); - } - /** * @param Ardent $model * @@ -41,16 +31,25 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa } /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. + * @param array $data * - * @param Ardent $model - * - * @return array + * @return Ardent */ - public function validateObject(Ardent $model) + public function store(array $data) { - // TODO: Implement validateObject() method. + // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. throw new NotImplementedException; } @@ -69,25 +68,16 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa } /** - * @param array $data + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. * - * @return Ardent - */ - public function store(array $data) - { - // TODO: Implement store() method. - throw new NotImplementedException; - } - - /** * @param Ardent $model - * @param array $data * - * @return bool + * @return array */ - public function update(Ardent $model, array $data) + public function validateObject(Ardent $model) { - // TODO: Implement update() method. + // TODO: Implement validateObject() method. throw new NotImplementedException; } @@ -104,6 +94,19 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa throw new NotImplementedException; } + /** + * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. + * + * @param $what + * + * @return \AccountType|null + */ + public function findByWhat($what) + { + // TODO: Implement findByWhat() method. + throw new NotImplementedException; + } + /** * Returns all objects. * @@ -127,15 +130,12 @@ class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDa } /** - * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. + * @param string $code * - * @param $what - * - * @return \AccountType|null + * @return \TransactionCurrency|null */ - public function findByWhat($what) + public function findByCode($code) { - // TODO: Implement findByWhat() method. - throw new NotImplementedException; + return \TransactionCurrency::whereCode($code)->first(); } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index c9291faf98..0c2430ae62 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -31,97 +31,111 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData } /** - * @param Carbon $date + * @param Ardent $model * - * @return float + * @return bool */ - public function getSumOfIncomesByMonth(Carbon $date) + public function destroy(Ardent $model) { - $end = clone $date; - $date->startOfMonth(); - $end->endOfMonth(); - - $sum = \DB::table('transactions') - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') - ->where('amount', '>', 0) - ->where('transaction_types.type', '=', 'Deposit') - ->where('transaction_journals.date', '>=', $date->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount'); - $sum = floatval($sum); - return $sum; + // TODO: Implement destroy() method. + throw new NotImplementedException; } /** - * @param Carbon $date + * @param array $data * - * @return float + * @return Ardent */ - public function getSumOfExpensesByMonth(Carbon $date) + public function store(array $data) { - $end = clone $date; - $date->startOfMonth(); - $end->endOfMonth(); - $sum = \DB::table('transactions') - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') - ->where('amount', '>', 0) - ->where('transaction_types.type', '=', 'Withdrawal') - ->where('transaction_journals.date', '>=', $date->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount'); - $sum = floatval($sum); - return $sum; + /** @var \FireflyIII\Database\TransactionType $typeRepository */ + $typeRepository = \App::make('FireflyIII\Database\TransactionType'); + + /** @var \FireflyIII\Database\Account $accountRepository */ + $accountRepository = \App::make('FireflyIII\Database\Account'); + + /** @var \FireflyIII\Database\TransactionCurrency $currencyRepository */ + $currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency'); + + /** @var \FireflyIII\Database\Transaction $transactionRepository */ + $transactionRepository = \App::make('FireflyIII\Database\Transaction'); + + $journalType = $typeRepository->findByWhat($data['what']); + $currency = $currencyRepository->findByCode($data['currency']); + + $journal = new \TransactionJournal; + $journal->transactionType()->associate($journalType); + $journal->transactionCurrency()->associate($currency); + $journal->user()->associate($this->getUser()); + $journal->description = $data['description']; + $journal->date = $data['date']; + $journal->completed = 0; + + /* + * This must be enough to store the journal: + */ + if (!$journal->validate()) { + \Log::error($journal->errors()->all()); + throw new FireflyException('store() transaction journal failed, but it should not!'); + } + $journal->save(); + + /* + * Still need to find the accounts related to the transactions. + * This depends on the type of transaction. + */ + switch ($data['what']) { + case 'withdrawal': + $data['from'] = $accountRepository->find($data['account_id']); + $data['to'] = $accountRepository->firstExpenseAccountOrCreate($data['expense_account']); + break; + case 'opening': + break; + + default: + throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".'); + break; + } + + /* + * Then store both transactions. + */ + $first = ['account' => $data['from'], 'transaction_journal' => $journal, 'amount' => ($data['amount'] * -1),]; + $validate = $transactionRepository->validate($first); + if ($validate['errors']->count() == 0) { + $transactionRepository->store($first); + } else { + throw new FireflyException($validate['errors']->first()); + } + + $second = ['account' => $data['to'], 'transaction_journal' => $journal, 'amount' => floatval($data['amount']),]; + + $validate = $transactionRepository->validate($second); + if ($validate['errors']->count() == 0) { + $transactionRepository->store($second); + } else { + throw new FireflyException($validate['errors']->first()); + } + + $journal->completed = 1; + $journal->save(); + + return $journal; } /** - * @param Carbon $start - * @param Carbon $end + * @param Ardent $model + * @param array $data * - * @return Collection + * @return bool */ - public function getInDateRange(Carbon $start, Carbon $end) + public function update(Ardent $model, array $data) { - return $this->getuser()->transactionjournals()->withRelevantData()->before($end)->after($start)->get(); + // TODO: Implement update() method. + throw new NotImplementedException; } - /** - * @param \Account $account - * @param int $count - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - public function getInDateRangeAccount(\Account $account, $count = 20, Carbon $start, Carbon $end) - { - - $accountID = $account->id; - $query = $this->_user - ->transactionjournals() - ->with(['transactions', 'transactioncurrency', 'transactiontype']) - ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') - ->where('accounts.id', $accountID) - ->where('date', '>=', $start->format('Y-m-d')) - ->where('date', '<=', $end->format('Y-m-d')) - ->orderBy('transaction_journals.date', 'DESC') - ->orderBy('transaction_journals.id', 'DESC') - ->take($count) - ->get(['transaction_journals.*']); - - return $query; - } - - /** - * @return TransactionJournal - */ - public function first() - { - return $this->getUser()->transactionjournals()->orderBy('date', 'ASC')->first(); - } - - /** * Validates an array. Returns an array containing MessageBags * errors/warnings/successes. @@ -133,9 +147,9 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData public function validate(array $model) { - $warnings = new MessageBag; + $warnings = new MessageBag; $successes = new MessageBag; - $errors = new MessageBag; + $errors = new MessageBag; if (!isset($model['what'])) { @@ -173,10 +187,12 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData */ if (isset($model['amount']) && floatval($model['amount']) < 0.01) { $errors->add('amount', 'Amount must be > 0.01'); - } else if (!isset($model['amount'])) { - $errors->add('amount', 'Amount must be set!'); } else { - $successes->add('amount', 'OK'); + if (!isset($model['amount'])) { + $errors->add('amount', 'Amount must be set!'); + } else { + $successes->add('amount', 'OK'); + } } /* @@ -240,26 +256,26 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData break; } -// if (isset($model['to_id']) && intval($model['to_id']) < 1) { -// $errors->add('account_to', 'Invalid to-account'); -// } -// -// if (isset($model['from_id']) && intval($model['from_id']) < 1) { -// $errors->add('account_from', 'Invalid from-account'); -// -// } -// if (isset($model['account_id']) && intval($model['account_id']) < 1) { -// $errors->add('account_id', 'Invalid account!'); -// } -// if (isset($model['to']) && !($model['to'] instanceof \Account)) { -// $errors->add('account_to', 'Invalid to-account'); -// } -// if (isset($model['from']) && !($model['from'] instanceof \Account)) { -// $errors->add('account_from', 'Invalid from-account'); -// } -// if (!isset($model['amount']) || (isset($model['amount']) && floatval($model['amount']) < 0)) { -// $errors->add('amount', 'Invalid amount'); -// } + // if (isset($model['to_id']) && intval($model['to_id']) < 1) { + // $errors->add('account_to', 'Invalid to-account'); + // } + // + // if (isset($model['from_id']) && intval($model['from_id']) < 1) { + // $errors->add('account_from', 'Invalid from-account'); + // + // } + // if (isset($model['account_id']) && intval($model['account_id']) < 1) { + // $errors->add('account_id', 'Invalid account!'); + // } + // if (isset($model['to']) && !($model['to'] instanceof \Account)) { + // $errors->add('account_to', 'Invalid to-account'); + // } + // if (isset($model['from']) && !($model['from'] instanceof \Account)) { + // $errors->add('account_from', 'Invalid from-account'); + // } + // if (!isset($model['amount']) || (isset($model['amount']) && floatval($model['amount']) < 0)) { + // $errors->add('amount', 'Invalid amount'); + // } $validator = \Validator::make([$model], \Transaction::$rules); @@ -277,169 +293,12 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData if (!$errors->has('date')) { $successes->add('date', 'OK'); } - return [ - 'errors' => $errors, - 'warnings' => $warnings, - 'successes' => $successes - ]; + + return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - - /** @var \FireflyIII\Database\TransactionType $typeRepository */ - $typeRepository = \App::make('FireflyIII\Database\TransactionType'); - - /** @var \FireflyIII\Database\Account $accountRepository */ - $accountRepository = \App::make('FireflyIII\Database\Account'); - - /** @var \FireflyIII\Database\TransactionCurrency $currencyRepository */ - $currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency'); - - /** @var \FireflyIII\Database\Transaction $transactionRepository */ - $transactionRepository = \App::make('FireflyIII\Database\Transaction'); - - $journalType = $typeRepository->findByWhat($data['what']); - $currency = $currencyRepository->findByCode($data['currency']); - - $journal = new \TransactionJournal; - $journal->transactionType()->associate($journalType); - $journal->transactionCurrency()->associate($currency); - $journal->user()->associate($this->getUser()); - $journal->description = $data['description']; - $journal->date = $data['date']; - $journal->completed = 0; - - /* - * This must be enough to store the journal: - */ - if (!$journal->validate()) { - \Log::error($journal->errors()->all()); - throw new FireflyException('store() transaction journal failed, but it should not!'); - } - $journal->save(); - - /* - * Still need to find the accounts related to the transactions. - * This depends on the type of transaction. - */ - switch ($data['what']) { - case 'withdrawal': - $data['from'] = $accountRepository->find($data['account_id']); - $data['to'] = $accountRepository->firstExpenseAccountOrCreate($data['expense_account']); - break; - case 'opening': - break; - - default: - throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".'); - break; - } - - /* - * Then store both transactions. - */ - $first = [ - 'account' => $data['from'], - 'transaction_journal' => $journal, - 'amount' => ($data['amount'] * -1), - ]; - $validate = $transactionRepository->validate($first); - if ($validate['errors']->count() == 0) { - $transactionRepository->store($first); - } else { - throw new FireflyException($validate['errors']->first()); - } - - $second = [ - 'account' => $data['to'], - 'transaction_journal' => $journal, - 'amount' => floatval($data['amount']), - ]; - - $validate = $transactionRepository->validate($second); - if ($validate['errors']->count() == 0) { - $transactionRepository->store($second); - } else { - throw new FireflyException($validate['errors']->first()); - } - - $journal->completed = 1; - $journal->save(); - return $journal; - } - - /** - * Returns an object with id $id. - * - * @param int $id - * - * @return Ardent - */ - public function find($id) - { - return $this->getUser()->transactionjournals()->find($id); - } - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - return $this->getUser()->transactionjournals()->get(); - } - - /** - * Some objects. - * - * @return Collection - */ - public function getTransfers() - { - return $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Transfer'])->get(['transaction_journals.*']); - } - - /** - * Some objects. - * - * @return Collection - */ - public function getDeposits() - { - return $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Deposit'])->get(['transaction_journals.*']); - } - - /** - * Some objects. - * - * @return Collection - */ - public function getWithdrawals() - { - return $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Withdrawal'])->get(['transaction_journals.*']); - } - - - /** - * @param Ardent $model - * - * @return bool - */ - public function destroy(Ardent $model) - { - // TODO: Implement destroy() method. - throw new NotImplementedException; - } - /** * Validates a model. Returns an array containing MessageBags * errors/warnings/successes. @@ -455,26 +314,15 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData } /** - * @param Ardent $model - * @param array $data + * Returns an object with id $id. * - * @return bool - */ - public function update(Ardent $model, array $data) - { - // TODO: Implement update() method. - throw new NotImplementedException; - } - - /** - * @param array $ids + * @param int $id * - * @return Collection + * @return Ardent */ - public function getByIds(array $ids) + public function find($id) { - // TODO: Implement getByIds() method. - throw new NotImplementedException; + return $this->getUser()->transactionjournals()->find($id); } /** @@ -489,4 +337,137 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData // TODO: Implement findByWhat() method. throw new NotImplementedException; } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + return $this->getUser()->transactionjournals()->get(); + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } + + /** + * @return TransactionJournal + */ + public function first() + { + return $this->getUser()->transactionjournals()->orderBy('date', 'ASC')->first(); + } + + /** + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function getInDateRange(Carbon $start, Carbon $end) + { + return $this->getuser()->transactionjournals()->withRelevantData()->before($end)->after($start)->get(); + } + + /** + * @param Carbon $date + * + * @return float + */ + public function getSumOfExpensesByMonth(Carbon $date) + { + $end = clone $date; + $date->startOfMonth(); + $end->endOfMonth(); + + $sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin( + 'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id' + )->where('amount', '>', 0)->where('transaction_types.type', '=', 'Withdrawal')->where('transaction_journals.date', '>=', $date->format('Y-m-d')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount'); + $sum = floatval($sum); + + return $sum; + } + + /** + * @param Carbon $date + * + * @return float + */ + public function getSumOfIncomesByMonth(Carbon $date) + { + $end = clone $date; + $date->startOfMonth(); + $end->endOfMonth(); + + $sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin( + 'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id' + )->where('amount', '>', 0)->where('transaction_types.type', '=', 'Deposit')->where('transaction_journals.date', '>=', $date->format('Y-m-d')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount'); + $sum = floatval($sum); + + return $sum; + } + + /** + * Some objects. + * + * @return Collection + */ + public function getDeposits() + { + return $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Deposit'])->get(['transaction_journals.*']); + } + + /** + * @param \Account $account + * @param int $count + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function getInDateRangeAccount(\Account $account, $count = 20, Carbon $start, Carbon $end) + { + + $accountID = $account->id; + $query = $this->_user->transactionjournals()->with(['transactions', 'transactioncurrency', 'transactiontype'])->leftJoin( + 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' + )->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')->where('accounts.id', $accountID)->where( + 'date', '>=', $start->format('Y-m-d') + )->where('date', '<=', $end->format('Y-m-d'))->orderBy('transaction_journals.date', 'DESC')->orderBy('transaction_journals.id', 'DESC')->take( + $count + )->get(['transaction_journals.*']); + + return $query; + } + + /** + * Some objects. + * + * @return Collection + */ + public function getTransfers() + { + return $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Transfer'])->get(['transaction_journals.*']); + } + + /** + * Some objects. + * + * @return Collection + */ + public function getWithdrawals() + { + return $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Withdrawal'])->get(['transaction_journals.*']); + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/TransactionType.php b/app/lib/FireflyIII/Database/TransactionType.php index c6cc1c59dd..fea091ae62 100644 --- a/app/lib/FireflyIII/Database/TransactionType.php +++ b/app/lib/FireflyIII/Database/TransactionType.php @@ -19,6 +19,81 @@ use LaravelBook\Ardent\Ardent; class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCalls { + /** + * @param Ardent $model + * + * @return bool + */ + public function destroy(Ardent $model) + { + // TODO: Implement destroy() method. + throw new NotImplementedException; + } + + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + // TODO: Implement store() method. + throw new NotImplementedException; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. + throw new NotImplementedException; + } + + /** + * Validates an array. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param array $model + * + * @return array + */ + public function validate(array $model) + { + // TODO: Implement validate() method. + throw new NotImplementedException; + } + + /** + * Validates a model. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param Ardent $model + * + * @return array + */ + public function validateObject(Ardent $model) + { + // TODO: Implement validateObject() method. + throw new NotImplementedException; + } + + /** + * Returns an object with id $id. + * + * @param int $id + * + * @return Ardent + */ + public function find($id) + { + // TODO: Implement find() method. + throw new NotImplementedException; + } + /** * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. * @@ -44,84 +119,10 @@ class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCa } + return null; } - /** - * @param Ardent $model - * - * @return bool - */ - public function destroy(Ardent $model) - { - // TODO: Implement destroy() method. - throw new NotImplementedException; - } - - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - - /** - * Validates an array. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param array $model - * - * @return array - */ - public function validate(array $model) - { - // TODO: Implement validate() method. - throw new NotImplementedException; - } - - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - // TODO: Implement store() method. - throw new NotImplementedException; - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - // TODO: Implement update() method. - throw new NotImplementedException; - } - - /** - * Returns an object with id $id. - * - * @param int $id - * - * @return Ardent - */ - public function find($id) - { - // TODO: Implement find() method. - throw new NotImplementedException; - } - /** * Returns all objects. * diff --git a/app/lib/FireflyIII/Database/User.php b/app/lib/FireflyIII/Database/User.php index 1796ab8468..4cb416e42a 100644 --- a/app/lib/FireflyIII/Database/User.php +++ b/app/lib/FireflyIII/Database/User.php @@ -11,6 +11,26 @@ namespace FireflyIII\Database; class User { + /** + * @param $mail + * + * @return null|User + */ + public function findByEmail($mail) + { + return \User::where('email', $mail)->first(); + } + + /** + * @param $reset + * + * @return null|User + */ + public function findByReset($reset) + { + return \User::where('reset', $reset)->first(); + } + /** * @param array $data * @@ -18,10 +38,10 @@ class User */ public function register(array $data) { - $user = new \User; - $user->email = isset($data['email']) ? $data['email'] : null; + $user = new \User; + $user->email = isset($data['email']) ? $data['email'] : null; $user->migrated = 0; - $user->reset = \Str::random(32); + $user->reset = \Str::random(32); $user->password = \Hash::make(\Str::random(12)); if (!$user->save()) { @@ -50,24 +70,4 @@ class User return true; } - /** - * @param $mail - * - * @return null|User - */ - public function findByEmail($mail) - { - return \User::where('email', $mail)->first(); - } - - /** - * @param $reset - * - * @return null|User - */ - public function findByReset($reset) - { - return \User::where('reset', $reset)->first(); - } - } \ No newline at end of file diff --git a/app/lib/FireflyIII/Exception/ValidationException.php b/app/lib/FireflyIII/Exception/ValidationException.php index 4cb09c9f5d..56116a870d 100644 --- a/app/lib/FireflyIII/Exception/ValidationException.php +++ b/app/lib/FireflyIII/Exception/ValidationException.php @@ -6,6 +6,7 @@ namespace FireflyIII\Exception; * * @package Firefly\Exception */ -class ValidationException extends \Exception { +class ValidationException extends \Exception +{ } \ No newline at end of file diff --git a/app/lib/FireflyIII/Form/Form.php b/app/lib/FireflyIII/Form/Form.php index ad7483cc07..171c0a7d96 100644 --- a/app/lib/FireflyIII/Form/Form.php +++ b/app/lib/FireflyIII/Form/Form.php @@ -14,36 +14,6 @@ use Illuminate\Support\MessageBag; class Form { - /** - * @param $name - * @param null $value - * @param array $options - * - * @return string - * @throws FireflyException - */ - public static function ffInteger($name, $value = null, array $options = []) - { - $options['step'] = '1'; - return self::ffInput('number', $name, $value, $options); - - } - - /** - * @param $name - * @param int $value - * @param null $checked - * @param array $options - * - * @return string - * @throws FireflyException - */ - public static function ffCheckbox($name, $value = 1, $checked = null, $options = []) - { - $options['checked'] = $checked ? true : null; - return self::ffInput('checkbox', $name, $value, $options); - } - /** * @param $name * @param null $value @@ -56,6 +26,7 @@ class Form { $options['step'] = 'any'; $options['min'] = '0.01'; + return self::ffInput('amount', $name, $value, $options); } @@ -71,10 +42,27 @@ class Form public static function ffBalance($name, $value = null, array $options = []) { $options['step'] = 'any'; + return self::ffInput('amount', $name, $value, $options); } + /** + * @param $name + * @param int $value + * @param null $checked + * @param array $options + * + * @return string + * @throws FireflyException + */ + public static function ffCheckbox($name, $value = 1, $checked = null, $options = []) + { + $options['checked'] = $checked ? true : null; + + return self::ffInput('checkbox', $name, $value, $options); + } + /** * @param $name * @param null $value @@ -96,126 +84,12 @@ class Form * @return string * @throws FireflyException */ - public static function ffTags($name, $value = null, array $options = []) + public static function ffInteger($name, $value = null, array $options = []) { - $options['data-role'] = 'tagsinput'; - return self::ffInput('text', $name, $value, $options); - } + $options['step'] = '1'; - /** - * @param $name - * @param array $list - * @param null $selected - * @param array $options - * - * @return string - * @throws FireflyException - */ - public static function ffSelect($name, array $list = [], $selected = null, array $options = []) - { - return self::ffInput('select', $name, $selected, $options, $list); - } + return self::ffInput('number', $name, $value, $options); - /** - * @param $name - * @param null $value - * @param array $options - * - * @return string - * @throws FireflyException - */ - public static function ffText($name, $value = null, array $options = array()) - { - return self::ffInput('text', $name, $value, $options); - - } - - /** - * @param $name - * @param $options - * - * @return string - */ - public static function label($name, $options) - { - if (isset($options['label'])) { - return $options['label']; - } - $labels = [ - 'amount_min' => 'Amount (min)', - 'amount_max' => 'Amount (max)', - 'match' => 'Matches on', - 'repeat_freq' => 'Repetition', - 'account_from_id' => 'Account from', - 'account_to_id' => 'Account to', - 'account_id' => 'Asset account' - ]; - - return isset($labels[$name]) ? $labels[$name] : str_replace('_', ' ', ucfirst($name)); - - } - - /** - * Return buttons for update/validate/return. - * - * @param $type - * @param $name - */ - public static function ffOptionsList($type, $name) - { - $previousValue = \Input::old('post_submit_action'); - $previousValue = is_null($previousValue) ? 'store' : $previousValue; - /* - * Store. - */ - $store = ''; - switch ($type) { - case 'create': - $store = '
'; - $store .= '
'; - break; - case 'update': - $store = '
'; - $store .= '
'; - break; - default: - throw new FireflyException('Cannot create ffOptionsList for option (store) ' . $type); - break; - } - - /* - * validate is always the same: - */ - $validate = '
'; - - /* - * Store & return: - */ - switch ($type) { - case 'create': - $return = '
'; - break; - case 'update': - $return = '
'; - break; - default: - throw new FireflyException('Cannot create ffOptionsList for option (store+return) ' . $type); - break; - } - return $store . $validate . $return; } /** @@ -228,7 +102,7 @@ class Form * @return string * @throws FireflyException */ - public static function ffInput($type, $name, $value = null, array $options = array(), $list = []) + public static function ffInput($type, $name, $value = null, array $options = [], $list = []) { /* * add some defaults to this method: @@ -376,4 +250,129 @@ class Form return $html; } + + /** + * @param $name + * @param $options + * + * @return string + */ + public static function label($name, $options) + { + if (isset($options['label'])) { + return $options['label']; + } + $labels = ['amount_min' => 'Amount (min)', 'amount_max' => 'Amount (max)', 'match' => 'Matches on', 'repeat_freq' => 'Repetition', + 'account_from_id' => 'Account from', 'account_to_id' => 'Account to', 'account_id' => 'Asset account']; + + return isset($labels[$name]) ? $labels[$name] : str_replace('_', ' ', ucfirst($name)); + + } + + /** + * Return buttons for update/validate/return. + * + * @param $type + * @param $name + */ + public static function ffOptionsList($type, $name) + { + $previousValue = \Input::old('post_submit_action'); + $previousValue = is_null($previousValue) ? 'store' : $previousValue; + /* + * Store. + */ + $store = ''; + switch ($type) { + case 'create': + $store = '
'; + $store .= '
'; + break; + case 'update': + $store = '
'; + $store .= '
'; + break; + default: + throw new FireflyException('Cannot create ffOptionsList for option (store) ' . $type); + break; + } + + /* + * validate is always the same: + */ + $validate = '
'; + + /* + * Store & return: + */ + switch ($type) { + case 'create': + $return = '
'; + break; + case 'update': + $return = '
'; + break; + default: + throw new FireflyException('Cannot create ffOptionsList for option (store+return) ' . $type); + break; + } + + return $store . $validate . $return; + } + + /** + * @param $name + * @param array $list + * @param null $selected + * @param array $options + * + * @return string + * @throws FireflyException + */ + public static function ffSelect($name, array $list = [], $selected = null, array $options = []) + { + return self::ffInput('select', $name, $selected, $options, $list); + } + + /** + * @param $name + * @param null $value + * @param array $options + * + * @return string + * @throws FireflyException + */ + public static function ffTags($name, $value = null, array $options = []) + { + $options['data-role'] = 'tagsinput'; + + return self::ffInput('text', $name, $value, $options); + } + + /** + * @param $name + * @param null $value + * @param array $options + * + * @return string + * @throws FireflyException + */ + public static function ffText($name, $value = null, array $options = []) + { + return self::ffInput('text', $name, $value, $options); + + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Json/Account.php b/app/lib/FireflyIII/Shared/Json/Account.php index 120ed6fad8..28724e732f 100644 --- a/app/lib/FireflyIII/Shared/Json/Account.php +++ b/app/lib/FireflyIII/Shared/Json/Account.php @@ -7,6 +7,7 @@ namespace FireflyIII\Shared\Json; * * @package FireflyIII\Shared\Json */ -class Account { +class Account +{ } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Json/Json.php b/app/lib/FireflyIII/Shared/Json/Json.php index 0a0cbc7730..2b0956de80 100644 --- a/app/lib/FireflyIII/Shared/Json/Json.php +++ b/app/lib/FireflyIII/Shared/Json/Json.php @@ -4,6 +4,7 @@ namespace FireflyIII\Shared\Json; /** * Class Json + * * @package FireflyIII\Shared\Json */ class Json @@ -24,11 +25,7 @@ class Json } else { $length = intval(\Input::get('length')); } - $parameters = [ - 'start' => intval(\Input::get('start')), - 'length' => $length, - 'draw' => intval(\Input::get('draw')), - ]; + $parameters = ['start' => intval(\Input::get('start')), 'length' => $length, 'draw' => intval(\Input::get('draw')),]; /* @@ -36,16 +33,12 @@ class Json */ if (!is_null(\Input::get('columns')) && is_array(\Input::get('columns'))) { foreach (\Input::get('columns') as $column) { - $parameters['columns'][] = [ - 'data' => $column['data'], - 'name' => $column['name'], - 'searchable' => $column['searchable'] == 'true' ? true : false, - 'orderable' => $column['orderable'] == 'true' ? true : false, - 'search' => [ - 'value' => $column['search']['value'], - 'regex' => $column['search']['regex'] == 'true' ? true : false, - ] - ]; + $parameters['columns'][] = ['data' => $column['data'], 'name' => $column['name'], + 'searchable' => $column['searchable'] == 'true' ? true : false, + 'orderable' => $column['orderable'] == 'true' ? true : false, 'search' => ['value' => $column['search']['value'], + 'regex' => + $column['search']['regex'] == 'true' + ? true : false,]]; } } @@ -58,10 +51,7 @@ class Json foreach (\Input::get('order') as $order) { $columnIndex = intval($order['column']); $columnName = $parameters['columns'][$columnIndex]['name']; - $parameters['order'][] = [ - 'name' => $columnName, - 'dir' => strtoupper($order['dir']) - ]; + $parameters['order'][] = ['name' => $columnName, 'dir' => strtoupper($order['dir'])]; if ($columnName == 'to' || $columnName == 'from') { $parameters['orderOnAccount'] = true; } @@ -70,17 +60,12 @@ class Json /* * Search parameters: */ - $parameters['search'] = [ - 'value' => '', - 'regex' => false - ]; + $parameters['search'] = ['value' => '', 'regex' => false]; if (!is_null(\Input::get('search')) && is_array(\Input::get('search'))) { $search = \Input::get('search'); - $parameters['search'] = [ - 'value' => $search['value'], - 'regex' => $search['regex'] == 'true' ? true : false - ]; + $parameters['search'] = ['value' => $search['value'], 'regex' => $search['regex'] == 'true' ? true : false]; } + return $parameters; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Mail/Registration.php b/app/lib/FireflyIII/Shared/Mail/Registration.php index 922c67141e..3fafddbff7 100644 --- a/app/lib/FireflyIII/Shared/Mail/Registration.php +++ b/app/lib/FireflyIII/Shared/Mail/Registration.php @@ -8,27 +8,6 @@ namespace FireflyIII\Shared\Mail; */ class Registration implements RegistrationInterface { - /** - * @param \User $user - * - * @return mixed|void - */ - public function sendVerificationMail(\User $user) - { - - $reset = \Str::random(32); - $user->reset = $reset; - $user->forceSave(); - $email = $user->email; - $data = ['reset' => $reset]; - - \Mail::send( - ['emails.user.verify-html', 'emails.user.verify-text'], $data, function ($message) use ($email) { - $message->to($email, $email)->subject('Verify your e-mail address.'); - } - ); - } - /** * @param \User $user * @@ -37,9 +16,9 @@ class Registration implements RegistrationInterface public function sendPasswordMail(\User $user) { - $password = \Str::random(12); + $password = \Str::random(12); $user->password = $password; - $user->reset = \Str::random(32); // new one. + $user->reset = \Str::random(32); // new one. $user->forceSave(); $email = $user->email; @@ -59,7 +38,7 @@ class Registration implements RegistrationInterface */ public function sendResetVerification(\User $user) { - $reset = \Str::random(32); + $reset = \Str::random(32); $user->reset = $reset; $user->forceSave(); $email = $user->email; @@ -74,4 +53,25 @@ class Registration implements RegistrationInterface } + /** + * @param \User $user + * + * @return mixed|void + */ + public function sendVerificationMail(\User $user) + { + + $reset = \Str::random(32); + $user->reset = $reset; + $user->forceSave(); + $email = $user->email; + $data = ['reset' => $reset]; + + \Mail::send( + ['emails.user.verify-html', 'emails.user.verify-text'], $data, function ($message) use ($email) { + $message->to($email, $email)->subject('Verify your e-mail address.'); + } + ); + } + } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Mail/RegistrationInterface.php b/app/lib/FireflyIII/Shared/Mail/RegistrationInterface.php index 0606956120..0741757b4e 100644 --- a/app/lib/FireflyIII/Shared/Mail/RegistrationInterface.php +++ b/app/lib/FireflyIII/Shared/Mail/RegistrationInterface.php @@ -10,13 +10,6 @@ namespace FireflyIII\Shared\Mail; interface RegistrationInterface { - /** - * @param \User $user - * - * @return mixed - */ - public function sendVerificationMail(\User $user); - /** * @param \User $user * @@ -31,4 +24,11 @@ interface RegistrationInterface */ public function sendResetVerification(\User $user); + /** + * @param \User $user + * + * @return mixed + */ + public function sendVerificationMail(\User $user); + } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Preferences/PreferencesInterface.php b/app/lib/FireflyIII/Shared/Preferences/PreferencesInterface.php index 4e7389695f..27f18a7ac5 100644 --- a/app/lib/FireflyIII/Shared/Preferences/PreferencesInterface.php +++ b/app/lib/FireflyIII/Shared/Preferences/PreferencesInterface.php @@ -10,14 +10,6 @@ interface PreferencesInterface { - /** - * @param $name - * @param $value - * - * @return null|\Preference - */ - public function set($name, $value); - /** * @param $name * @param null $default @@ -26,4 +18,12 @@ interface PreferencesInterface */ public function get($name, $default = null); + /** + * @param $name + * @param $value + * + * @return null|\Preference + */ + public function set($name, $value); + } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/SingleTableInheritanceEntity.php b/app/lib/FireflyIII/Shared/SingleTableInheritanceEntity.php index 9787e02e40..664813d406 100644 --- a/app/lib/FireflyIII/Shared/SingleTableInheritanceEntity.php +++ b/app/lib/FireflyIII/Shared/SingleTableInheritanceEntity.php @@ -10,18 +10,18 @@ use LaravelBook\Ardent\Ardent; */ abstract class SingleTableInheritanceEntity extends Ardent { - /** - * The field that stores the subclass - * - * @var string - */ - protected $subclassField = null; /** * must be overridden and set to true in subclasses * * @var bool */ protected $isSubclass = false; + /** + * The field that stores the subclass + * + * @var string + */ + protected $subclassField = null; /** * @param array $attributes @@ -36,24 +36,6 @@ abstract class SingleTableInheritanceEntity extends Ardent return $instance; } - - /** - * if no subclass is defined, function as normal - * - * @param array $attributes - * - * @return \Illuminate\Database\Eloquent\Model|static - */ - public function mapData(array $attributes) - { - if (!$this->subclassField) { - return $this->newInstance(); - } - - return new $attributes[$this->subclassField]; - } - - /** * * instead of using $this->newInstance(), call @@ -86,14 +68,6 @@ abstract class SingleTableInheritanceEntity extends Ardent return $builder; } - /** - * @return bool - */ - public function isSubclass() - { - return $this->isSubclass; - } - /** * ensure that the subclass field is assigned on save * @@ -106,11 +80,7 @@ abstract class SingleTableInheritanceEntity extends Ardent * @return bool */ public function save( - array $rules = [], - array $customMessages = [], - array $options = [], - \Closure $beforeSave = null, - \Closure $afterSave = null + array $rules = [], array $customMessages = [], array $options = [], \Closure $beforeSave = null, \Closure $afterSave = null ) { if ($this->subclassField) { $this->attributes[$this->subclassField] = get_class($this); @@ -118,4 +88,28 @@ abstract class SingleTableInheritanceEntity extends Ardent return parent::save($rules, $customMessages, $options, $beforeSave, $afterSave); } + + /** + * if no subclass is defined, function as normal + * + * @param array $attributes + * + * @return \Illuminate\Database\Eloquent\Model|static + */ + public function mapData(array $attributes) + { + if (!$this->subclassField) { + return $this->newInstance(); + } + + return new $attributes[$this->subclassField]; + } + + /** + * @return bool + */ + public function isSubclass() + { + return $this->isSubclass; + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index 1abf90e321..845381346e 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -12,39 +12,6 @@ use Firefly\Exception\FireflyException; */ class Date { - /** - * @param Carbon $currentEnd - * @param $repeatFreq - * - * @throws FireflyException - */ - public function endOfPeriod(Carbon $currentEnd, $repeatFreq) - { - switch ($repeatFreq) { - default: - throw new FireflyException('Cannot do endOfPeriod for $repeat_freq ' . $repeatFreq); - break; - case 'daily': - $currentEnd->addDay(); - break; - case 'weekly': - $currentEnd->addWeek()->subDay(); - break; - case 'monthly': - $currentEnd->addMonth()->subDay(); - break; - case 'quarterly': - $currentEnd->addMonths(3)->subDay(); - break; - case 'half-year': - $currentEnd->addMonths(6)->subDay(); - break; - case 'yearly': - $currentEnd->addYear()->subDay(); - break; - } - } - /** * @param Carbon $date * @param $repeatFreq @@ -81,6 +48,40 @@ class Date $date->addYears($add); break; } + return $date; } + + /** + * @param Carbon $currentEnd + * @param $repeatFreq + * + * @throws FireflyException + */ + public function endOfPeriod(Carbon $currentEnd, $repeatFreq) + { + switch ($repeatFreq) { + default: + throw new FireflyException('Cannot do endOfPeriod for $repeat_freq ' . $repeatFreq); + break; + case 'daily': + $currentEnd->addDay(); + break; + case 'weekly': + $currentEnd->addWeek()->subDay(); + break; + case 'monthly': + $currentEnd->addMonth()->subDay(); + break; + case 'quarterly': + $currentEnd->addMonths(3)->subDay(); + break; + case 'half-year': + $currentEnd->addMonths(6)->subDay(); + break; + case 'yearly': + $currentEnd->addYear()->subDay(); + break; + } + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Toolkit/Filter.php b/app/lib/FireflyIII/Shared/Toolkit/Filter.php index b3cb70686c..f6c923f15a 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Filter.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Filter.php @@ -18,29 +18,6 @@ use Firefly\Exception\FireflyException; */ class Filter { - /** - * Checks and sets the currently set 'range' or defaults to a session - * and if that fails, defaults to 1M. Always returns the final value. - * - * @return string - */ - public function setSessionRangeValue() - { - if (!is_null(\Session::get('range'))) { - $range = \Session::get('range'); - } else { - /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ - $preferences = \App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); - $viewRange = $preferences->get('viewRange', '1M'); - - // default range: - $range = $viewRange->data; - \Session::put('range', $range); - } - return $range; - - } - /** * Save Session::get('start') and Session::get('end') for other methods to use. */ @@ -87,10 +64,35 @@ class Filter \Session::put('period', $period); \Session::put('prev', $this->periodName($range, $prev)); \Session::put('next', $this->periodName($range, $next)); + return null; } + /** + * Checks and sets the currently set 'range' or defaults to a session + * and if that fails, defaults to 1M. Always returns the final value. + * + * @return string + */ + public function setSessionRangeValue() + { + if (!is_null(\Session::get('range'))) { + $range = \Session::get('range'); + } else { + /** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */ + $preferences = \App::make('FireflyIII\Shared\Preferences\PreferencesInterface'); + $viewRange = $preferences->get('viewRange', '1M'); + + // default range: + $range = $viewRange->data; + \Session::put('range', $range); + } + + return $range; + + } + /** * @param $range * @param Carbon $start @@ -198,12 +200,14 @@ class Filter break; case '3M': $month = intval($date->format('m')); + return 'Q' . ceil(($month / 12) * 4) . ' ' . $date->format('Y'); break; case '6M': $month = intval($date->format('m')); $half = ceil(($month / 12) * 2); $halfName = $half == 1 ? 'first' : 'second'; + return $halfName . ' half of ' . $date->format('d-m-Y'); break; case '1Y': @@ -252,6 +256,7 @@ class Filter break; } + return $date; } @@ -291,6 +296,7 @@ class Filter throw new FireflyException('Cannot do _next() on ' . $range); break; } + return $date; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Toolkit/Form.php b/app/lib/FireflyIII/Shared/Toolkit/Form.php index 7383a0e7a2..2fa690a427 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Form.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Form.php @@ -9,12 +9,13 @@ use Illuminate\Support\Collection; * * @package FireflyIII\Shared\Toolkit */ -class Form { +class Form +{ /** * Takes any collection and tries to make a sensible select list compatible array of it. * * @param Collection $set - * @param null $titleField + * @param null $titleField * * @return mixed */ @@ -44,6 +45,7 @@ class Form { } $selectList[$id] = $title; } + return $selectList; } diff --git a/app/lib/FireflyIII/Shared/Toolkit/Navigation.php b/app/lib/FireflyIII/Shared/Toolkit/Navigation.php index f4f40e9117..1b26fc8b51 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Navigation.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Navigation.php @@ -33,6 +33,7 @@ class Navigation * Save in session: */ \Session::put('start', $next); + return true; } @@ -59,6 +60,7 @@ class Navigation * Save in session: */ \Session::put('start', $prev); + return true; } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Validation/ValidationServiceProvider.php b/app/lib/FireflyIII/Shared/Validation/ValidationServiceProvider.php index 5ba7a32446..96a421aeca 100644 --- a/app/lib/FireflyIII/Shared/Validation/ValidationServiceProvider.php +++ b/app/lib/FireflyIII/Shared/Validation/ValidationServiceProvider.php @@ -7,6 +7,7 @@ use Illuminate\Support\ServiceProvider; /** * Class ValidationServiceProvider + * * @package FireflyIII\Shared\Validation */ class ValidationServiceProvider extends ServiceProvider From 71d174d765893f012d5ceb1b34a3f59a31efa47b Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 12 Nov 2014 22:37:44 +0100 Subject: [PATCH 020/193] Code clean up and reformat. --- app/models/Account.php | 126 +++++++++++------------- app/models/AccountMeta.php | 6 +- app/models/AccountType.php | 24 +++-- app/models/Budget.php | 30 +++--- app/models/Category.php | 30 +++--- app/models/Component.php | 44 ++++----- app/models/Importentry.php | 28 +++--- app/models/Importmap.php | 50 +++++----- app/models/Limit.php | 66 ++++++------- app/models/LimitRepetition.php | 58 +++++------ app/models/Piggybank.php | 147 ++++++++++++---------------- app/models/PiggybankEvent.php | 30 +++--- app/models/PiggybankRepetition.php | 35 +++---- app/models/Preference.php | 60 ++++++------ app/models/RecurringTransaction.php | 67 ++++++------- app/models/Reminder.php | 23 +++-- app/models/Transaction.php | 136 ++++++++++++------------- app/models/TransactionCurrency.php | 16 +-- app/models/TransactionJournal.php | 125 +++++++++++------------ app/models/TransactionType.php | 16 +-- app/models/User.php | 74 +++++++------- 21 files changed, 551 insertions(+), 640 deletions(-) diff --git a/app/models/Account.php b/app/models/Account.php index 2346f5501d..ce207b98d9 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -5,25 +5,25 @@ use LaravelBook\Ardent\Builder; /** * Account * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property integer $user_id - * @property integer $account_type_id - * @property string $name - * @property boolean $active - * @property-read \AccountType $accountType + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property integer $user_id + * @property integer $account_type_id + * @property string $name + * @property boolean $active + * @property-read \AccountType $accountType * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions - * @property-read \Illuminate\Database\Eloquent\Collection|\Piggybank[] $piggybanks - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\Account whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereAccountTypeId($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereName($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereActive($value) - * @method static \Account accountTypeIn($types) + * @property-read \Illuminate\Database\Eloquent\Collection|\Piggybank[] $piggybanks + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\Account whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereAccountTypeId($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereName($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereActive($value) + * @method static \Account accountTypeIn($types) */ class Account extends Ardent { @@ -34,16 +34,23 @@ class Account extends Ardent * @var array */ public static $rules - = [ - 'name' => ['required', 'between:1,100', 'alphabasic'], - 'user_id' => 'required|exists:users,id', - 'account_type_id' => 'required|exists:account_types,id', - 'active' => 'required|boolean' + = ['name' => ['required', 'between:1,100', 'alphabasic'], 'user_id' => 'required|exists:users,id', + 'account_type_id' => 'required|exists:account_types,id', 'active' => 'required|boolean' ]; protected $fillable = ['name', 'user_id', 'account_type_id', 'active']; + /** + * Account type. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function accountType() + { + return $this->belongsTo('AccountType'); + } + /** * Get an accounts current balance. * @@ -56,43 +63,12 @@ class Account extends Ardent $date = is_null($date) ? new \Carbon\Carbon : $date; return floatval( - $this->transactions() - ->leftJoin( - 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' - ) - ->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount') + $this->transactions()->leftJoin( + 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' + )->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount') ); } - /** - * @param TransactionJournal $journal - * - * @return float - */ - public function balanceBeforeJournal(TransactionJournal $journal) - { - return floatval( - $this->transactions() - ->leftJoin( - 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' - ) - ->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d')) - ->where('transaction_journals.created_at', '<=', $journal->created_at->format('Y-m-d H:i:s')) - ->where('transaction_journals.id', '!=', $journal->id) - ->sum('transactions.amount') - ); - } - - /** - * Account type. - * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - */ - public function accountType() - { - return $this->belongsTo('AccountType'); - } - /** * Transactions. * @@ -103,6 +79,22 @@ class Account extends Ardent return $this->hasMany('Transaction'); } + /** + * @param TransactionJournal $journal + * + * @return float + */ + public function balanceBeforeJournal(TransactionJournal $journal) + { + return floatval( + $this->transactions()->leftJoin( + 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' + )->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d'))->where( + 'transaction_journals.created_at', '<=', $journal->created_at->format('Y-m-d H:i:s') + )->where('transaction_journals.id', '!=', $journal->id)->sum('transactions.amount') + ); + } + /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ @@ -123,16 +115,6 @@ class Account extends Ardent return null; } - /** - * User - * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - */ - public function user() - { - return $this->belongsTo('User'); - } - /** * @param Builder $query * @param array $types @@ -146,5 +128,15 @@ class Account extends Ardent $query->whereIn('account_types.type', $types); } + /** + * User + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function user() + { + return $this->belongsTo('User'); + } + } \ No newline at end of file diff --git a/app/models/AccountMeta.php b/app/models/AccountMeta.php index 12b09102b9..dc8a8452b9 100644 --- a/app/models/AccountMeta.php +++ b/app/models/AccountMeta.php @@ -12,11 +12,7 @@ class AccountMeta extends Ardent * @var array */ public static $rules - = [ - 'account_id' => 'numeric|required|exists:accounts,id', - 'name' => 'required|between:1,250', - 'data' => 'required' - ]; + = ['account_id' => 'numeric|required|exists:accounts,id', 'name' => 'required|between:1,250', 'data' => 'required']; /** * @var array diff --git a/app/models/AccountType.php b/app/models/AccountType.php index 77a4ec8585..63deaee28a 100644 --- a/app/models/AccountType.php +++ b/app/models/AccountType.php @@ -5,24 +5,22 @@ use Illuminate\Database\Eloquent\Model as Eloquent; /** * AccountType * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $type - * @property boolean $editable + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $type + * @property boolean $editable * @property-read \Illuminate\Database\Eloquent\Collection|\Account[] $accounts - * @method static \Illuminate\Database\Query\Builder|\AccountType whereId($value) - * @method static \Illuminate\Database\Query\Builder|\AccountType whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\AccountType whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\AccountType whereType($value) - * @method static \Illuminate\Database\Query\Builder|\AccountType whereEditable($value) + * @method static \Illuminate\Database\Query\Builder|\AccountType whereId($value) + * @method static \Illuminate\Database\Query\Builder|\AccountType whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\AccountType whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\AccountType whereType($value) + * @method static \Illuminate\Database\Query\Builder|\AccountType whereEditable($value) */ class AccountType extends Eloquent { public static $rules - = [ - 'type' => ['required', 'between:1,50', 'alphabasic'], - 'editable' => 'required|boolean', + = ['type' => ['required', 'between:1,50', 'alphabasic'], 'editable' => 'required|boolean', ]; diff --git a/app/models/Budget.php b/app/models/Budget.php index 18bf3d069c..e00793396a 100644 --- a/app/models/Budget.php +++ b/app/models/Budget.php @@ -3,22 +3,22 @@ /** * Budget * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $name - * @property integer $user_id - * @property string $class - * @property-read \Illuminate\Database\Eloquent\Collection|\Limit[] $limits + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $name + * @property integer $user_id + * @property string $class + * @property-read \Illuminate\Database\Eloquent\Collection|\Limit[] $limits * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals - * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\Budget whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Budget whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Budget whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Budget whereName($value) - * @method static \Illuminate\Database\Query\Builder|\Budget whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\Budget whereClass($value) + * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\Budget whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Budget whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Budget whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Budget whereName($value) + * @method static \Illuminate\Database\Query\Builder|\Budget whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\Budget whereClass($value) */ class Budget extends Component { diff --git a/app/models/Category.php b/app/models/Category.php index 2469907cdc..c39e0642f6 100644 --- a/app/models/Category.php +++ b/app/models/Category.php @@ -3,22 +3,22 @@ /** * Category * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $name - * @property integer $user_id - * @property string $class + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $name + * @property integer $user_id + * @property string $class * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals - * @property-read \Illuminate\Database\Eloquent\Collection|\Limit[] $limits - * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\Category whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Category whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Category whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Category whereName($value) - * @method static \Illuminate\Database\Query\Builder|\Category whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\Category whereClass($value) + * @property-read \Illuminate\Database\Eloquent\Collection|\Limit[] $limits + * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\Category whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Category whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Category whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Category whereName($value) + * @method static \Illuminate\Database\Query\Builder|\Category whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\Category whereClass($value) */ class Category extends Component { diff --git a/app/models/Component.php b/app/models/Component.php index f0905fcb84..b70d981ccf 100644 --- a/app/models/Component.php +++ b/app/models/Component.php @@ -4,36 +4,32 @@ use FireflyIII\Shared\SingleTableInheritanceEntity; /** * Component * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $name - * @property integer $user_id - * @property string $class - * @property-read \Illuminate\Database\Eloquent\Collection|\Limit[] $limits + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $name + * @property integer $user_id + * @property string $class + * @property-read \Illuminate\Database\Eloquent\Collection|\Limit[] $limits * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals - * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\Component whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Component whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Component whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Component whereName($value) - * @method static \Illuminate\Database\Query\Builder|\Component whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\Component whereClass($value) + * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\Component whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Component whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Component whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Component whereName($value) + * @method static \Illuminate\Database\Query\Builder|\Component whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\Component whereClass($value) */ class Component extends SingleTableInheritanceEntity { public static $rules - = [ - 'user_id' => 'exists:users,id|required', - 'name' => ['required', 'between:1,100','min:1', 'alphabasic'], - 'class' => 'required', - ]; - protected $table = 'components'; - protected $subclassField = 'class'; - protected $fillable = ['name','user_id']; - + = ['user_id' => 'exists:users,id|required', 'name' => ['required', 'between:1,100', 'min:1', 'alphabasic'], + 'class' => 'required',]; + protected $fillable = ['name', 'user_id']; + protected $subclassField = 'class'; + protected $table = 'components'; /** * @return \Illuminate\Database\Eloquent\Relations\HasMany diff --git a/app/models/Importentry.php b/app/models/Importentry.php index 9bf832b31a..790f64ff6a 100644 --- a/app/models/Importentry.php +++ b/app/models/Importentry.php @@ -4,21 +4,21 @@ use Illuminate\Database\Eloquent\Model as Eloquent; /** * Importentry * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $class - * @property integer $importmap_id - * @property integer $old - * @property integer $new + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $class + * @property integer $importmap_id + * @property integer $old + * @property integer $new * @property-read \Importmap $importmap - * @method static \Illuminate\Database\Query\Builder|\Importentry whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Importentry whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Importentry whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Importentry whereClass($value) - * @method static \Illuminate\Database\Query\Builder|\Importentry whereImportmapId($value) - * @method static \Illuminate\Database\Query\Builder|\Importentry whereOld($value) - * @method static \Illuminate\Database\Query\Builder|\Importentry whereNew($value) + * @method static \Illuminate\Database\Query\Builder|\Importentry whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Importentry whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Importentry whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Importentry whereClass($value) + * @method static \Illuminate\Database\Query\Builder|\Importentry whereImportmapId($value) + * @method static \Illuminate\Database\Query\Builder|\Importentry whereOld($value) + * @method static \Illuminate\Database\Query\Builder|\Importentry whereNew($value) */ class Importentry extends Eloquent { diff --git a/app/models/Importmap.php b/app/models/Importmap.php index ab81ed683a..7dc54ca6ea 100644 --- a/app/models/Importmap.php +++ b/app/models/Importmap.php @@ -4,33 +4,38 @@ use LaravelBook\Ardent\Ardent as Ardent; /** * Importmap * - * @property integer $id + * @property integer $id * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at - * @property integer $user_id - * @property string $file - * @property integer $totaljobs - * @property integer $jobsdone - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\Importmap whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Importmap whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Importmap whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Importmap whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\Importmap whereFile($value) - * @method static \Illuminate\Database\Query\Builder|\Importmap whereTotaljobs($value) - * @method static \Illuminate\Database\Query\Builder|\Importmap whereJobsdone($value) + * @property integer $user_id + * @property string $file + * @property integer $totaljobs + * @property integer $jobsdone + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\Importmap whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Importmap whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Importmap whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Importmap whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\Importmap whereFile($value) + * @method static \Illuminate\Database\Query\Builder|\Importmap whereTotaljobs($value) + * @method static \Illuminate\Database\Query\Builder|\Importmap whereJobsdone($value) */ class Importmap extends Ardent { public static $rules - = [ - 'user_id' => 'required|exists:users,id', - 'file' => 'required', - 'totaljobs' => 'numeric|required|min:0', - 'jobsdone' => 'numeric|required|min:0', + = ['user_id' => 'required|exists:users,id', 'file' => 'required', 'totaljobs' => 'numeric|required|min:0', 'jobsdone' => 'numeric|required|min:0', ]; + public function pct() + { + if ($this->jobsdone == 0 || $this->totaljobs == 0) { + return 0; + } else { + return round((($this->jobsdone / $this->totaljobs) * 100), 1); + } + } + /** * User * @@ -40,13 +45,4 @@ class Importmap extends Ardent { return $this->belongsTo('User'); } - - public function pct() - { - if ($this->jobsdone == 0 || $this->totaljobs == 0) { - return 0; - } else { - return round((($this->jobsdone / $this->totaljobs) * 100), 1); - } - } } \ No newline at end of file diff --git a/app/models/Limit.php b/app/models/Limit.php index 23f893ed1e..d53d1c04f1 100644 --- a/app/models/Limit.php +++ b/app/models/Limit.php @@ -7,36 +7,32 @@ use LaravelBook\Ardent\Ardent as Ardent; /** * Limit * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property integer $component_id - * @property \Carbon\Carbon $startdate - * @property float $amount - * @property boolean $repeats - * @property string $repeat_freq - * @property-read \Budget $budget - * @property-read \Component $component + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property integer $component_id + * @property \Carbon\Carbon $startdate + * @property float $amount + * @property boolean $repeats + * @property string $repeat_freq + * @property-read \Budget $budget + * @property-read \Component $component * @property-read \Illuminate\Database\Eloquent\Collection|\LimitRepetition[] $limitrepetitions - * @method static \Illuminate\Database\Query\Builder|\Limit whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Limit whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Limit whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Limit whereComponentId($value) - * @method static \Illuminate\Database\Query\Builder|\Limit whereStartdate($value) - * @method static \Illuminate\Database\Query\Builder|\Limit whereAmount($value) - * @method static \Illuminate\Database\Query\Builder|\Limit whereRepeats($value) - * @method static \Illuminate\Database\Query\Builder|\Limit whereRepeatFreq($value) + * @method static \Illuminate\Database\Query\Builder|\Limit whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Limit whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Limit whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Limit whereComponentId($value) + * @method static \Illuminate\Database\Query\Builder|\Limit whereStartdate($value) + * @method static \Illuminate\Database\Query\Builder|\Limit whereAmount($value) + * @method static \Illuminate\Database\Query\Builder|\Limit whereRepeats($value) + * @method static \Illuminate\Database\Query\Builder|\Limit whereRepeatFreq($value) */ class Limit extends Ardent { public static $rules - = [ - 'component_id' => 'required|exists:components,id', - 'startdate' => 'required|date', - 'amount' => 'numeric|required|min:0.01', - 'repeats' => 'required|boolean', - 'repeat_freq' => 'required|in:daily,weekly,monthly,quarterly,half-year,yearly' + = ['component_id' => 'required|exists:components,id', 'startdate' => 'required|date', 'amount' => 'numeric|required|min:0.01', + 'repeats' => 'required|boolean', 'repeat_freq' => 'required|in:daily,weekly,monthly,quarterly,half-year,yearly' ]; @@ -90,15 +86,15 @@ class Limit extends Ardent } $end->subDay(); $count = $this->limitrepetitions()->where('startdate', $start->format('Y-m-d'))->where('enddate', $end->format('Y-m-d'))->count(); - \Log::debug('All: '.$this->limitrepetitions()->count().' (#'.$this->id.')'); - \Log::debug('Found ' . $count.' limit-reps for limit #' . $this->id.' with start '.$start->format('Y-m-d') .' and end ' . $end->format('Y-m-d')); + \Log::debug('All: ' . $this->limitrepetitions()->count() . ' (#' . $this->id . ')'); + \Log::debug('Found ' . $count . ' limit-reps for limit #' . $this->id . ' with start ' . $start->format('Y-m-d') . ' and end ' . $end->format('Y-m-d')); if ($count == 0) { - $repetition = new \LimitRepetition(); + $repetition = new \LimitRepetition(); $repetition->startdate = $start; - $repetition->enddate = $end; - $repetition->amount = $this->amount; + $repetition->enddate = $end; + $repetition->amount = $this->amount; $repetition->limit()->associate($this); try { @@ -113,12 +109,14 @@ class Limit extends Ardent if (isset($repetition->id)) { \Event::fire('limits.repetition', [$repetition]); } - } else if($count == 1) { - // update this one: - $repetition = $this->limitrepetitions()->where('startdate', $start->format('Y-m-d'))->where('enddate', $end->format('Y-m-d'))->first(); - $repetition->amount = $this->amount; - $repetition->save(); + } else { + if ($count == 1) { + // update this one: + $repetition = $this->limitrepetitions()->where('startdate', $start->format('Y-m-d'))->where('enddate', $end->format('Y-m-d'))->first(); + $repetition->amount = $this->amount; + $repetition->save(); + } } } diff --git a/app/models/LimitRepetition.php b/app/models/LimitRepetition.php index 06613afb59..ec7fefbe53 100644 --- a/app/models/LimitRepetition.php +++ b/app/models/LimitRepetition.php @@ -6,31 +6,26 @@ use LaravelBook\Ardent\Ardent as Ardent; /** * LimitRepetition * - * @property integer $id + * @property integer $id * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at - * @property integer $limit_id + * @property integer $limit_id * @property \Carbon\Carbon $startdate * @property \Carbon\Carbon $enddate - * @property float $amount - * @property-read \Limit $limit - * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereId($value) - * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereLimitId($value) - * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereStartdate($value) - * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereEnddate($value) - * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereAmount($value) + * @property float $amount + * @property-read \Limit $limit + * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereId($value) + * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereLimitId($value) + * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereStartdate($value) + * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereEnddate($value) + * @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereAmount($value) */ class LimitRepetition extends Ardent { public static $rules - = [ - 'limit_id' => 'required|exists:limits,id', - 'startdate' => 'required|date', - 'enddate' => 'required|date', - 'amount' => 'numeric|required|min:0.01', - ]; + = ['limit_id' => 'required|exists:limits,id', 'startdate' => 'required|date', 'enddate' => 'required|date', 'amount' => 'numeric|required|min:0.01',]; /** * @return array @@ -40,20 +35,6 @@ class LimitRepetition extends Ardent return ['created_at', 'updated_at', 'startdate', 'enddate']; } - public function spentInRepetition() { - $sum = \DB::table('transactions') - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') - ->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id') - ->leftJoin('limits', 'limits.component_id', '=', 'components.id') - ->leftJoin('limit_repetitions', 'limit_repetitions.limit_id', '=', 'limits.id') - ->where('transaction_journals.date', '>=', $this->startdate->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $this->enddate->format('Y-m-d')) - ->where('transactions.amount', '>', 0) - ->where('limit_repetitions.id', '=', $this->id)->sum('transactions.amount'); - return floatval($sum); - } - /** * How much money is left in this? */ @@ -63,6 +44,21 @@ class LimitRepetition extends Ardent } + public function spentInRepetition() + { + $sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin( + 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' + )->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')->leftJoin( + 'limits', 'limits.component_id', '=', 'components.id' + )->leftJoin('limit_repetitions', 'limit_repetitions.limit_id', '=', 'limits.id')->where( + 'transaction_journals.date', '>=', $this->startdate->format('Y-m-d') + )->where('transaction_journals.date', '<=', $this->enddate->format('Y-m-d'))->where('transactions.amount', '>', 0)->where( + 'limit_repetitions.id', '=', $this->id + )->sum('transactions.amount'); + + return floatval($sum); + } + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php index c364bcf0d2..03ec278c47 100644 --- a/app/models/Piggybank.php +++ b/app/models/Piggybank.php @@ -5,77 +5,62 @@ use LaravelBook\Ardent\Ardent as Ardent; /** * Piggybank * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property integer $account_id - * @property string $name - * @property float $targetamount - * @property \Carbon\Carbon $startdate - * @property \Carbon\Carbon $targetdate - * @property boolean $repeats - * @property string $rep_length - * @property integer $rep_every - * @property integer $rep_times - * @property string $reminder - * @property integer $reminder_skip - * @property boolean $remind_me - * @property integer $order - * @property-read \Account $account + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property integer $account_id + * @property string $name + * @property float $targetamount + * @property \Carbon\Carbon $startdate + * @property \Carbon\Carbon $targetdate + * @property boolean $repeats + * @property string $rep_length + * @property integer $rep_every + * @property integer $rep_times + * @property string $reminder + * @property integer $reminder_skip + * @property boolean $remind_me + * @property integer $order + * @property-read \Account $account * @property-read \Illuminate\Database\Eloquent\Collection|\PiggybankRepetition[] $piggybankrepetitions - * @property-read \Illuminate\Database\Eloquent\Collection|\PiggybankEvent[] $piggybankevents - * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereAccountId($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereName($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereTargetamount($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereStartdate($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereTargetdate($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepeats($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepLength($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepEvery($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepTimes($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminder($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminderSkip($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRemindMe($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereOrder($value) + * @property-read \Illuminate\Database\Eloquent\Collection|\PiggybankEvent[] $piggybankevents + * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereAccountId($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereName($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereTargetamount($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereStartdate($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereTargetdate($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepeats($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepLength($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepEvery($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepTimes($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminder($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminderSkip($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRemindMe($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereOrder($value) */ class Piggybank extends Ardent { public static $rules - = [ - 'account_id' => 'required|exists:accounts,id', // link to Account - 'name' => 'required|between:1,255', // name - 'targetamount' => 'required|min:0', // amount you want to save - 'startdate' => 'date', // when you started - 'targetdate' => 'date', // when its due - 'repeats' => 'required|boolean', // does it repeat? - 'rep_length' => 'in:day,week,month,year', // how long is the period? - 'rep_every' => 'required|min:1|max:100', // how often does it repeat? every 3 years. - 'rep_times' => 'min:1|max:100', // how many times do you want to save this amount? eg. 3 times - 'reminder' => 'in:day,week,month,year', // want a reminder to put money in this? - 'reminder_skip' => 'required|min:0|max:100', // every week? every 2 months? - 'remind_me' => 'required|boolean', - 'order' => 'required:min:1', // not yet used. - ]; - public $fillable - = [ - 'account_id', - 'name', - 'targetamount', - 'startdate', - 'targetdate', - 'repeats', - 'rep_length', - 'rep_every', - 'rep_times', - 'reminder', - 'reminder_skip', - 'remind_me', - 'order' + = ['account_id' => 'required|exists:accounts,id', // link to Account + 'name' => 'required|between:1,255', // name + 'targetamount' => 'required|min:0', // amount you want to save + 'startdate' => 'date', // when you started + 'targetdate' => 'date', // when its due + 'repeats' => 'required|boolean', // does it repeat? + 'rep_length' => 'in:day,week,month,year', // how long is the period? + 'rep_every' => 'required|min:1|max:100', // how often does it repeat? every 3 years. + 'rep_times' => 'min:1|max:100', // how many times do you want to save this amount? eg. 3 times + 'reminder' => 'in:day,week,month,year', // want a reminder to put money in this? + 'reminder_skip' => 'required|min:0|max:100', // every week? every 2 months? + 'remind_me' => 'required|boolean', 'order' => 'required:min:1', // not yet used. ]; + public $fillable + = ['account_id', 'name', 'targetamount', 'startdate', 'targetdate', 'repeats', 'rep_length', 'rep_every', 'rep_times', 'reminder', 'reminder_skip', + 'remind_me', 'order']; /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo @@ -89,8 +74,8 @@ class Piggybank extends Ardent { $rep = new \PiggybankRepetition; $rep->piggybank()->associate($this); - $rep->startdate = $start; - $rep->targetdate = $target; + $rep->startdate = $start; + $rep->targetdate = $target; $rep->currentamount = 0; $rep->save(); \Event::fire('piggybanks.repetition', [$rep]); @@ -98,14 +83,6 @@ class Piggybank extends Ardent return $rep; } - /** - * @return array - */ - public function getDates() - { - return ['created_at', 'updated_at', 'targetdate', 'startdate']; - } - /** * Grabs the PiggyBankRepetition that's currently relevant / active * @@ -113,8 +90,7 @@ class Piggybank extends Ardent */ public function currentRelevantRep() { - $query = $this->piggybankrepetitions() - ->where( + $query = $this->piggybankrepetitions()->where( function ($q) { $q->where( @@ -123,8 +99,7 @@ class Piggybank extends Ardent $q->whereNull('startdate'); $q->orWhere('startdate', '<=', $today->format('Y-m-d')); } - ) - ->where( + )->where( function ($q) { $today = new Carbon; $q->whereNull('targetdate'); @@ -154,6 +129,14 @@ class Piggybank extends Ardent return $this->hasMany('PiggybankRepetition'); } + /** + * @return array + */ + public function getDates() + { + return ['created_at', 'updated_at', 'targetdate', 'startdate']; + } + /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ @@ -171,8 +154,7 @@ class Piggybank extends Ardent */ public function repetitionForDate(Carbon $date) { - $query = $this->piggybankrepetitions() - ->where( + $query = $this->piggybankrepetitions()->where( function ($q) use ($date) { $q->where( @@ -180,8 +162,7 @@ class Piggybank extends Ardent $q->whereNull('startdate'); $q->orWhere('startdate', '<=', $date->format('Y-m-d')); } - ) - ->where( + )->where( function ($q) use ($date) { $q->whereNull('targetdate'); $q->orWhere('targetdate', '>=', $date->format('Y-m-d')); diff --git a/app/models/PiggybankEvent.php b/app/models/PiggybankEvent.php index 5c6cc88fb7..ceb3c1bf91 100644 --- a/app/models/PiggybankEvent.php +++ b/app/models/PiggybankEvent.php @@ -5,29 +5,25 @@ use LaravelBook\Ardent\Ardent as Ardent; /** * PiggybankEvent * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property integer $piggybank_id - * @property \Carbon\Carbon $date - * @property float $amount + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property integer $piggybank_id + * @property \Carbon\Carbon $date + * @property float $amount * @property-read \Piggybank $piggybank - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereId($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent wherePiggybankId($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereDate($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereAmount($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereId($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent wherePiggybankId($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereDate($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereAmount($value) */ class PiggybankEvent extends Ardent { public static $rules - = [ - 'piggybank_id' => 'required|exists:piggybanks,id', - 'date' => 'required|date', - 'amount' => 'required|numeric' - ]; + = ['piggybank_id' => 'required|exists:piggybanks,id', 'date' => 'required|date', 'amount' => 'required|numeric']; /** * @return array diff --git a/app/models/PiggybankRepetition.php b/app/models/PiggybankRepetition.php index 9f66ef2820..99e0ee85a6 100644 --- a/app/models/PiggybankRepetition.php +++ b/app/models/PiggybankRepetition.php @@ -4,31 +4,26 @@ use LaravelBook\Ardent\Ardent as Ardent; /** * PiggybankRepetition * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property integer $piggybank_id - * @property \Carbon\Carbon $startdate - * @property \Carbon\Carbon $targetdate - * @property float $currentamount + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property integer $piggybank_id + * @property \Carbon\Carbon $startdate + * @property \Carbon\Carbon $targetdate + * @property float $currentamount * @property-read \Piggybank $piggybank - * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereId($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition wherePiggybankId($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereStartdate($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereTargetdate($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereCurrentamount($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereId($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition wherePiggybankId($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereStartdate($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereTargetdate($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankRepetition whereCurrentamount($value) */ class PiggybankRepetition extends Ardent { public static $rules - = [ - 'piggybank_id' => 'required|exists:piggybanks,id', - 'targetdate' => 'date', - 'startdate' => 'date', - 'currentamount' => 'required|numeric' - ]; + = ['piggybank_id' => 'required|exists:piggybanks,id', 'targetdate' => 'date', 'startdate' => 'date', 'currentamount' => 'required|numeric']; /** * @return array diff --git a/app/models/Preference.php b/app/models/Preference.php index ba8ac43bf9..5f28bd6a17 100644 --- a/app/models/Preference.php +++ b/app/models/Preference.php @@ -5,44 +5,24 @@ use LaravelBook\Ardent\Ardent; /** * Preference * - * @property integer $id + * @property integer $id * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at - * @property integer $user_id - * @property string $name - * @property string $data - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\Preference whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Preference whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Preference whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Preference whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\Preference whereName($value) - * @method static \Illuminate\Database\Query\Builder|\Preference whereData($value) + * @property integer $user_id + * @property string $name + * @property string $data + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\Preference whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Preference whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Preference whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Preference whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\Preference whereName($value) + * @method static \Illuminate\Database\Query\Builder|\Preference whereData($value) */ class Preference extends Ardent { public static $rules - = [ - 'user_id' => 'required|exists:users,id', - 'name' => 'required|between:1,255', - 'data' => 'required' - ]; - - /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - */ - public function user() - { - return $this->belongsTo('User'); - } - - /** - * @param $value - */ - public function setDataAttribute($value) - { - $this->attributes['data'] = json_encode($value); - } + = ['user_id' => 'required|exists:users,id', 'name' => 'required|between:1,255', 'data' => 'required']; /** * @param $value @@ -54,4 +34,20 @@ class Preference extends Ardent return json_decode($value); } + /** + * @param $value + */ + public function setDataAttribute($value) + { + $this->attributes['data'] = json_encode($value); + } + + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function user() + { + return $this->belongsTo('User'); + } + } \ No newline at end of file diff --git a/app/models/RecurringTransaction.php b/app/models/RecurringTransaction.php index c2781e1252..c2c45a8ac2 100644 --- a/app/models/RecurringTransaction.php +++ b/app/models/RecurringTransaction.php @@ -5,52 +5,43 @@ use LaravelBook\Ardent\Ardent; /** * RecurringTransaction * - * @property integer $id + * @property integer $id * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at - * @property integer $user_id - * @property string $name - * @property string $match - * @property float $amount_max - * @property float $amount_min + * @property integer $user_id + * @property string $name + * @property string $match + * @property float $amount_max + * @property float $amount_min * @property \Carbon\Carbon $date - * @property boolean $active - * @property boolean $automatch - * @property string $repeat_freq - * @property integer $skip - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereId($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereName($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereMatch($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereAmountMax($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereAmountMin($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereDate($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereActive($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereAutomatch($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereRepeatFreq($value) - * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereSkip($value) + * @property boolean $active + * @property boolean $automatch + * @property string $repeat_freq + * @property integer $skip + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereId($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereName($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereMatch($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereAmountMax($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereAmountMin($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereDate($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereActive($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereAutomatch($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereRepeatFreq($value) + * @method static \Illuminate\Database\Query\Builder|\RecurringTransaction whereSkip($value) */ class RecurringTransaction extends Ardent { public static $rules - = [ - 'user_id' => 'required|exists:users,id', - 'name' => 'required|between:1,255', - 'match' => 'required', - 'amount_max' => 'required|between:0,65536', - 'amount_min' => 'required|between:0,65536', - 'date' => 'required|date', - 'active' => 'required|between:0,1', - 'automatch' => 'required|between:0,1', - 'repeat_freq' => 'required|in:daily,weekly,monthly,quarterly,half-year,yearly', - 'skip' => 'required|between:0,31', - ]; + = ['user_id' => 'required|exists:users,id', 'name' => 'required|between:1,255', 'match' => 'required', 'amount_max' => 'required|between:0,65536', + 'amount_min' => 'required|between:0,65536', 'date' => 'required|date', 'active' => 'required|between:0,1', 'automatch' => 'required|between:0,1', + 'repeat_freq' => 'required|in:daily,weekly,monthly,quarterly,half-year,yearly', 'skip' => 'required|between:0,31',]; - protected $fillable = ['user_id','name','match','amount_min','amount_max','date','repeat_freq','skip','active','automatch']; + protected $fillable = ['user_id', 'name', 'match', 'amount_min', 'amount_max', 'date', 'repeat_freq', 'skip', 'active', 'automatch']; /** * @return array @@ -68,7 +59,7 @@ class RecurringTransaction extends Ardent { $today = new Carbon; $start = clone $this->date; - $skip = $this->skip == 0 ? 1 : $this->skip; + $skip = $this->skip == 0 ? 1 : $this->skip; if ($today < $start) { return $start; } diff --git a/app/models/Reminder.php b/app/models/Reminder.php index 0d11a174f5..e8fb4154cd 100644 --- a/app/models/Reminder.php +++ b/app/models/Reminder.php @@ -1,27 +1,26 @@ 'numeric|required|exists:accounts,id', - 'piggybank_id' => 'numeric|exists:piggybanks,id', - 'transaction_journal_id' => 'numeric|required|exists:transaction_journals,id', - 'description' => 'between:1,255', - 'amount' => 'required|between:-65536,65536|not_in:0,0.00', - ]; + = ['account_id' => 'numeric|required|exists:accounts,id', 'piggybank_id' => 'numeric|exists:piggybanks,id', + 'transaction_journal_id' => 'numeric|required|exists:transaction_journals,id', 'description' => 'between:1,255', + 'amount' => 'required|between:-65536,65536|not_in:0,0.00',]; /** @@ -58,36 +54,6 @@ class Transaction extends Ardent return $this->belongsTo('Account'); } - /** - * @param Piggybank $piggybank - * - * @return bool - */ - public function connectPiggybank(\Piggybank $piggybank = null) - { - throw new NotImplementedException; -// if (is_null($piggybank)) { -// return true; -// } -// /** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggyRepository */ -// $piggyRepository = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface'); -// if ($this->account_id == $piggybank->account_id) { -// $this->piggybank()->associate($piggybank); -// $this->save(); -// \Event::fire('piggybanks.createRelatedTransfer', [$piggybank, $this->transactionJournal, $this]); -// return true; -// } -// return false; - } - - /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - */ - public function piggybank() - { - return $this->belongsTo('Piggybank'); - } - /** * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ @@ -112,6 +78,36 @@ class Transaction extends Ardent return $this->belongsToMany('Component'); } + /** + * @param Piggybank $piggybank + * + * @return bool + */ + public function connectPiggybank(\Piggybank $piggybank = null) + { + throw new NotImplementedException; + // if (is_null($piggybank)) { + // return true; + // } + // /** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggyRepository */ + // $piggyRepository = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface'); + // if ($this->account_id == $piggybank->account_id) { + // $this->piggybank()->associate($piggybank); + // $this->save(); + // \Event::fire('piggybanks.createRelatedTransfer', [$piggybank, $this->transactionJournal, $this]); + // return true; + // } + // return false; + } + + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function piggybank() + { + return $this->belongsTo('Piggybank'); + } + public function scopeAccountIs(Builder $query, Account $account) { $query->where('transactions.account_id', $account->id); @@ -121,8 +117,7 @@ class Transaction extends Ardent { if (is_null($this->joinedJournals)) { $query->leftJoin( - 'transaction_journals', 'transaction_journals.id', '=', - 'transactions.transaction_journal_id' + 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' ); $this->joinedJournals = true; } @@ -133,8 +128,7 @@ class Transaction extends Ardent { if (is_null($this->joinedJournals)) { $query->leftJoin( - 'transaction_journals', 'transaction_journals.id', '=', - 'transactions.transaction_journal_id' + 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' ); $this->joinedJournals = true; } @@ -155,15 +149,13 @@ class Transaction extends Ardent { if (is_null($this->joinedJournals)) { $query->leftJoin( - 'transaction_journals', 'transaction_journals.id', '=', - 'transactions.transaction_journal_id' + 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' ); $this->joinedJournals = true; } if (is_null($this->joinedTransactionTypes)) { $query->leftJoin( - 'transaction_types', 'transaction_types.id', '=', - 'transaction_journals.transaction_type_id' + 'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id' ); $this->joinedTransactionTypes = true; } diff --git a/app/models/TransactionCurrency.php b/app/models/TransactionCurrency.php index 23ee95ad1f..bac3143feb 100644 --- a/app/models/TransactionCurrency.php +++ b/app/models/TransactionCurrency.php @@ -4,15 +4,15 @@ use Illuminate\Database\Eloquent\Model as Eloquent; /** * TransactionCurrency * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $code + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $code * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals - * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereId($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereCode($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereId($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereCode($value) */ class TransactionCurrency extends Eloquent { diff --git a/app/models/TransactionJournal.php b/app/models/TransactionJournal.php index 89513a0d46..fdc0ae6dab 100644 --- a/app/models/TransactionJournal.php +++ b/app/models/TransactionJournal.php @@ -7,57 +7,52 @@ use LaravelBook\Ardent\Builder; /** * TransactionJournal * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property integer $user_id - * @property integer $transaction_type_id - * @property integer $recurring_transaction_id - * @property integer $transaction_currency_id - * @property string $description - * @property boolean $completed - * @property \Carbon\Carbon $date + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property integer $user_id + * @property integer $transaction_type_id + * @property integer $recurring_transaction_id + * @property integer $transaction_currency_id + * @property string $description + * @property boolean $completed + * @property \Carbon\Carbon $date * @property-read \Illuminate\Database\Eloquent\Collection|\ * 'Budget[] $budgets * @property-read \Illuminate\Database\Eloquent\Collection|\ * 'Category[] $categories - * @property-read \Illuminate\Database\Eloquent\Collection|\Component[] $components - * @property-read \RecurringTransaction $recurringTransaction - * @property-read \TransactionCurrency $transactionCurrency - * @property-read \TransactionType $transactionType + * @property-read \Illuminate\Database\Eloquent\Collection|\Component[] $components + * @property-read \RecurringTransaction $recurringTransaction + * @property-read \TransactionCurrency $transactionCurrency + * @property-read \TransactionType $transactionType * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereId($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionTypeId($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereRecurringTransactionId($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionCurrencyId($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDescription($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCompleted($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDate($value) - * @method static \TransactionJournal accountIs($account) - * @method static \TransactionJournal after($date) - * @method static \TransactionJournal before($date) - * @method static \TransactionJournal defaultSorting() - * @method static \TransactionJournal moreThan($amount) - * @method static \TransactionJournal lessThan($amount) - * @method static \TransactionJournal onDate($date) - * @method static \TransactionJournal transactionTypes($types) - * @method static \TransactionJournal withRelevantData() + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereId($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionTypeId($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereRecurringTransactionId($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionCurrencyId($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDescription($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCompleted($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDate($value) + * @method static \TransactionJournal accountIs($account) + * @method static \TransactionJournal after($date) + * @method static \TransactionJournal before($date) + * @method static \TransactionJournal defaultSorting() + * @method static \TransactionJournal moreThan($amount) + * @method static \TransactionJournal lessThan($amount) + * @method static \TransactionJournal onDate($date) + * @method static \TransactionJournal transactionTypes($types) + * @method static \TransactionJournal withRelevantData() */ class TransactionJournal extends Ardent { public static $rules - = [ - 'transaction_type_id' => 'required|exists:transaction_types,id', - 'transaction_currency_id' => 'required|exists:transaction_currencies,id', - 'description' => 'required|between:1,255', - 'date' => 'required|date', - 'completed' => 'required|between:0,1' - ]; + = ['transaction_type_id' => 'required|exists:transaction_types,id', 'transaction_currency_id' => 'required|exists:transaction_currencies,id', + 'description' => 'required|between:1,255', 'date' => 'required|date', 'completed' => 'required|between:0,1']; /** @@ -99,15 +94,8 @@ class TransactionJournal extends Ardent return floatval($t->amount); } } - return -0.01; - } - /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - */ - public function recurringTransaction() - { - return $this->belongsTo('RecurringTransaction'); + return -0.01; } /** @@ -118,6 +106,14 @@ class TransactionJournal extends Ardent return ['created_at', 'updated_at', 'date']; } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function recurringTransaction() + { + return $this->belongsTo('RecurringTransaction'); + } + /** * @param Builder $query * @param Account $account @@ -158,25 +154,11 @@ class TransactionJournal extends Ardent $query->orderBy('date', 'DESC')->orderBy('transaction_journals.id', 'DESC'); } - public function scopeMoreThan(Builder $query, $amount) - { - if (is_null($this->joinedTransactions)) { - $query->leftJoin( - 'transactions', 'transactions.transaction_journal_id', '=', - 'transaction_journals.id' - ); - $this->joinedTransactions = true; - } - - $query->where('transactions.amount', '>=', $amount); - } - public function scopeLessThan(Builder $query, $amount) { if (is_null($this->joinedTransactions)) { $query->leftJoin( - 'transactions', 'transactions.transaction_journal_id', '=', - 'transaction_journals.id' + 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' ); $this->joinedTransactions = true; } @@ -184,6 +166,18 @@ class TransactionJournal extends Ardent $query->where('transactions.amount', '<=', $amount); } + public function scopeMoreThan(Builder $query, $amount) + { + if (is_null($this->joinedTransactions)) { + $query->leftJoin( + 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' + ); + $this->joinedTransactions = true; + } + + $query->where('transactions.amount', '>=', $amount); + } + /** * @param $query * @param Carbon $date @@ -199,8 +193,7 @@ class TransactionJournal extends Ardent { if (is_null($this->joinedTransactionTypes)) { $query->leftJoin( - 'transaction_types', 'transaction_types.id', '=', - 'transaction_journals.transaction_type_id' + 'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id' ); $this->joinedTransactionTypes = true; } diff --git a/app/models/TransactionType.php b/app/models/TransactionType.php index 9633bc07e1..0fea66cadd 100644 --- a/app/models/TransactionType.php +++ b/app/models/TransactionType.php @@ -5,15 +5,15 @@ use LaravelBook\Ardent\Ardent; /** * TransactionType * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $type + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $type * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionJournals - * @method static \Illuminate\Database\Query\Builder|\TransactionType whereId($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionType whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionType whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionType whereType($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionType whereId($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionType whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionType whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionType whereType($value) */ class TransactionType extends Ardent { diff --git a/app/models/User.php b/app/models/User.php index 6f665beaf7..15de4c9168 100644 --- a/app/models/User.php +++ b/app/models/User.php @@ -9,29 +9,29 @@ use LaravelBook\Ardent\Ardent; /** * User * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $email - * @property string $password - * @property string $reset - * @property string $remember_token - * @property boolean $migrated - * @property-read \Illuminate\Database\Eloquent\Collection|\Account[] $accounts - * @property-read \Illuminate\Database\Eloquent\Collection|\Budget[] $budgets - * @property-read \Illuminate\Database\Eloquent\Collection|\Category[] $categories - * @property-read \Illuminate\Database\Eloquent\Collection|\Component[] $components - * @property-read \Illuminate\Database\Eloquent\Collection|\Preference[] $preferences + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $email + * @property string $password + * @property string $reset + * @property string $remember_token + * @property boolean $migrated + * @property-read \Illuminate\Database\Eloquent\Collection|\Account[] $accounts + * @property-read \Illuminate\Database\Eloquent\Collection|\Budget[] $budgets + * @property-read \Illuminate\Database\Eloquent\Collection|\Category[] $categories + * @property-read \Illuminate\Database\Eloquent\Collection|\Component[] $components + * @property-read \Illuminate\Database\Eloquent\Collection|\Preference[] $preferences * @property-read \Illuminate\Database\Eloquent\Collection|\RecurringTransaction[] $recurringtransactions - * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals - * @method static \Illuminate\Database\Query\Builder|\User whereId($value) - * @method static \Illuminate\Database\Query\Builder|\User whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\User whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\User whereEmail($value) - * @method static \Illuminate\Database\Query\Builder|\User wherePassword($value) - * @method static \Illuminate\Database\Query\Builder|\User whereReset($value) - * @method static \Illuminate\Database\Query\Builder|\User whereRememberToken($value) - * @method static \Illuminate\Database\Query\Builder|\User whereMigrated($value) + * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals + * @method static \Illuminate\Database\Query\Builder|\User whereId($value) + * @method static \Illuminate\Database\Query\Builder|\User whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\User whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\User whereEmail($value) + * @method static \Illuminate\Database\Query\Builder|\User wherePassword($value) + * @method static \Illuminate\Database\Query\Builder|\User whereReset($value) + * @method static \Illuminate\Database\Query\Builder|\User whereRememberToken($value) + * @method static \Illuminate\Database\Query\Builder|\User whereMigrated($value) */ class User extends Ardent implements UserInterface, RemindableInterface { @@ -40,24 +40,20 @@ class User extends Ardent implements UserInterface, RemindableInterface public static $rules - = [ - 'email' => 'required|email|unique:users,email', - 'migrated' => 'required|boolean', - 'password' => 'required|between:60,60', - 'reset' => 'between:32,32', - ]; - /** - * The database table used by the model. - * - * @var string - */ - protected $table = 'users'; + = ['email' => 'required|email|unique:users,email', 'migrated' => 'required|boolean', 'password' => 'required|between:60,60', + 'reset' => 'between:32,32',]; /** * The attributes excluded from the model's JSON form. * * @var array */ protected $hidden = ['remember_token']; + /** + * The database table used by the model. + * + * @var string + */ + protected $table = 'users'; /** * @return \Illuminate\Database\Eloquent\Relations\HasMany @@ -91,6 +87,11 @@ class User extends Ardent implements UserInterface, RemindableInterface return $this->hasMany('Component'); } + public function piggybanks() + { + return $this->hasManyThrough('Piggybank', 'Account'); + } + /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ @@ -115,11 +116,6 @@ class User extends Ardent implements UserInterface, RemindableInterface $this->attributes['password'] = Hash::make($value); } - public function piggybanks() - { - return $this->hasManyThrough('Piggybank', 'Account'); - } - /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ From 2597633b0e727146b7fa221c7f000293998d47a6 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 13 Nov 2014 07:25:47 +0100 Subject: [PATCH 021/193] New migration and code cleanup. --- .../2014_06_27_163032_create_users_table.php | 20 +++--- ...6_27_163145_create_account_types_table.php | 14 ++-- ...014_06_27_163259_create_accounts_table.php | 28 ++++---- ...4_06_27_163817_create_components_table.php | 24 ++++--- ...4_06_27_163818_create_piggybanks_table.php | 24 ++++--- ...42_create_transaction_currencies_table.php | 20 +++--- ..._164512_create_transaction_types_table.php | 20 +++--- ...19_create_recurring_transactions_table.php | 20 +++--- ...4620_create_transaction_journals_table.php | 36 ++++------- ...06_27_164836_create_transactions_table.php | 12 +--- ...344_create_component_transaction_table.php | 28 ++++---- ...te_component_transaction_journal_table.php | 28 ++++---- ..._07_06_123842_create_preferences_table.php | 24 ++++--- ...2014_07_09_204843_create_session_table.php | 20 +++--- .../2014_07_17_183717_create_limits_table.php | 24 ++++--- ...07_19_055011_create_limit_repeat_table.php | 24 ++++--- ...6_recurring_transactions_to_components.php | 28 ++++---- ...014_08_12_173919_create_piggy_instance.php | 24 ++++--- .../2014_08_18_100330_create_piggy_events.php | 24 ++++--- ...14_08_23_113221_create_reminders_table.php | 4 +- ...4_08_31_153322_create_importmaps_table.php | 64 +++++++++---------- ...9_01_052816_create_importentries_table.php | 26 ++++---- ..._09_02_103101_create_failed_jobs_table.php | 16 +++-- .../2014_11_10_172053_create_account_meta.php | 24 +++---- ...14_11_13_062347_expand_reminders_table.php | 33 ++++++++++ app/database/seeds/DefaultUserSeeder.php | 8 +-- 26 files changed, 299 insertions(+), 318 deletions(-) create mode 100644 app/database/migrations/2014_11_13_062347_expand_reminders_table.php diff --git a/app/database/migrations/2014_06_27_163032_create_users_table.php b/app/database/migrations/2014_06_27_163032_create_users_table.php index 25cc4349a3..7dce4f47b8 100644 --- a/app/database/migrations/2014_06_27_163032_create_users_table.php +++ b/app/database/migrations/2014_06_27_163032_create_users_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateUsersTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('users'); + } + /** * Run the migrations. * @@ -33,14 +43,4 @@ class CreateUsersTable extends Migration ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('users'); - } - } diff --git a/app/database/migrations/2014_06_27_163145_create_account_types_table.php b/app/database/migrations/2014_06_27_163145_create_account_types_table.php index b900c47bed..8a05459eaf 100644 --- a/app/database/migrations/2014_06_27_163145_create_account_types_table.php +++ b/app/database/migrations/2014_06_27_163145_create_account_types_table.php @@ -29,14 +29,14 @@ class CreateAccountTypesTable extends Migration public function up() { Schema::create( - 'account_types', function (Blueprint $table) { - $table->increments('id'); - $table->timestamps(); - $table->string('type', 50); - $table->boolean('editable'); + 'account_types', function (Blueprint $table) { + $table->increments('id'); + $table->timestamps(); + $table->string('type', 50); + $table->boolean('editable'); - $table->unique('type'); - } + $table->unique('type'); + } ); } diff --git a/app/database/migrations/2014_06_27_163259_create_accounts_table.php b/app/database/migrations/2014_06_27_163259_create_accounts_table.php index e98a4d4581..fb90d43c63 100644 --- a/app/database/migrations/2014_06_27_163259_create_accounts_table.php +++ b/app/database/migrations/2014_06_27_163259_create_accounts_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateAccountsTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('accounts'); + } + /** * Run the migrations. * @@ -28,28 +38,14 @@ class CreateAccountsTable extends Migration $table->boolean('active'); // connect accounts to users - $table->foreign('user_id') - ->references('id')->on('users') - ->onDelete('cascade'); + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); // connect accounts to account_types - $table->foreign('account_type_id') - ->references('id')->on('account_types') - ->onDelete('cascade'); + $table->foreign('account_type_id')->references('id')->on('account_types')->onDelete('cascade'); $table->unique(['user_id', 'account_type_id', 'name']); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('accounts'); - } - } diff --git a/app/database/migrations/2014_06_27_163817_create_components_table.php b/app/database/migrations/2014_06_27_163817_create_components_table.php index 998bef4ddf..3c213f7d91 100644 --- a/app/database/migrations/2014_06_27_163817_create_components_table.php +++ b/app/database/migrations/2014_06_27_163817_create_components_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateComponentsTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('components'); + } + /** * Run the migrations. * @@ -27,9 +37,7 @@ class CreateComponentsTable extends Migration $table->string('class', 20); // connect components to users - $table->foreign('user_id') - ->references('id')->on('users') - ->onDelete('cascade'); + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $table->unique(['user_id', 'class', 'name']); } @@ -37,14 +45,4 @@ class CreateComponentsTable extends Migration } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('components'); - } - } diff --git a/app/database/migrations/2014_06_27_163818_create_piggybanks_table.php b/app/database/migrations/2014_06_27_163818_create_piggybanks_table.php index 74ff3e20c8..e4f2be8348 100644 --- a/app/database/migrations/2014_06_27_163818_create_piggybanks_table.php +++ b/app/database/migrations/2014_06_27_163818_create_piggybanks_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreatePiggybanksTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('piggybanks'); + } + /** * Run the migrations. * @@ -37,23 +47,11 @@ class CreatePiggybanksTable extends Migration $table->integer('order')->unsigned(); // connect account to piggybank. - $table->foreign('account_id') - ->references('id')->on('accounts') - ->onDelete('cascade'); + $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); $table->unique(['account_id', 'name']); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('piggybanks'); - } - } diff --git a/app/database/migrations/2014_06_27_164042_create_transaction_currencies_table.php b/app/database/migrations/2014_06_27_164042_create_transaction_currencies_table.php index 64c82f8491..04e34c4863 100644 --- a/app/database/migrations/2014_06_27_164042_create_transaction_currencies_table.php +++ b/app/database/migrations/2014_06_27_164042_create_transaction_currencies_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateTransactionCurrenciesTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('transaction_currencies'); + } + /** * Run the migrations. * @@ -27,14 +37,4 @@ class CreateTransactionCurrenciesTable extends Migration ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('transaction_currencies'); - } - } diff --git a/app/database/migrations/2014_06_27_164512_create_transaction_types_table.php b/app/database/migrations/2014_06_27_164512_create_transaction_types_table.php index 6cd34a74c5..b50a7e4d08 100644 --- a/app/database/migrations/2014_06_27_164512_create_transaction_types_table.php +++ b/app/database/migrations/2014_06_27_164512_create_transaction_types_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateTransactionTypesTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('transaction_types'); + } + /** * Run the migrations. * @@ -27,14 +37,4 @@ class CreateTransactionTypesTable extends Migration ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('transaction_types'); - } - } diff --git a/app/database/migrations/2014_06_27_164619_create_recurring_transactions_table.php b/app/database/migrations/2014_06_27_164619_create_recurring_transactions_table.php index 46b48bc255..af41979983 100644 --- a/app/database/migrations/2014_06_27_164619_create_recurring_transactions_table.php +++ b/app/database/migrations/2014_06_27_164619_create_recurring_transactions_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateRecurringTransactionsTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('recurring_transactions'); + } + /** * Run the migrations. * @@ -41,14 +51,4 @@ class CreateRecurringTransactionsTable extends Migration ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('recurring_transactions'); - } - } diff --git a/app/database/migrations/2014_06_27_164620_create_transaction_journals_table.php b/app/database/migrations/2014_06_27_164620_create_transaction_journals_table.php index 75886fa254..5988ea2ab3 100644 --- a/app/database/migrations/2014_06_27_164620_create_transaction_journals_table.php +++ b/app/database/migrations/2014_06_27_164620_create_transaction_journals_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateTransactionJournalsTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('transaction_journals'); + } + /** * Run the migrations. * @@ -31,36 +41,18 @@ class CreateTransactionJournalsTable extends Migration $table->date('date'); // connect transaction journals to transaction types - $table->foreign('transaction_type_id') - ->references('id')->on('transaction_types') - ->onDelete('cascade'); + $table->foreign('transaction_type_id')->references('id')->on('transaction_types')->onDelete('cascade'); // connect transaction journals to recurring transactions - $table->foreign('recurring_transaction_id') - ->references('id')->on('recurring_transactions') - ->onDelete('set null'); + $table->foreign('recurring_transaction_id')->references('id')->on('recurring_transactions')->onDelete('set null'); // connect transaction journals to transaction currencies - $table->foreign('transaction_currency_id') - ->references('id')->on('transaction_currencies') - ->onDelete('cascade'); + $table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade'); // connect users - $table->foreign('user_id') - ->references('id')->on('users') - ->onDelete('cascade'); + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('transaction_journals'); - } - } diff --git a/app/database/migrations/2014_06_27_164836_create_transactions_table.php b/app/database/migrations/2014_06_27_164836_create_transactions_table.php index 9bd7c6177d..4875a57c83 100644 --- a/app/database/migrations/2014_06_27_164836_create_transactions_table.php +++ b/app/database/migrations/2014_06_27_164836_create_transactions_table.php @@ -39,19 +39,13 @@ class CreateTransactionsTable extends Migration $table->decimal('amount', 10, 2); // connect transactions to transaction journals - $table->foreign('transaction_journal_id') - ->references('id')->on('transaction_journals') - ->onDelete('cascade'); + $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade'); // connect piggy banks - $table->foreign('piggybank_id') - ->references('id')->on('piggybanks') - ->onDelete('set null'); + $table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('set null'); // connect account id: - $table->foreign('account_id') - ->references('id')->on('accounts') - ->onDelete('cascade'); + $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); } ); diff --git a/app/database/migrations/2014_06_27_165344_create_component_transaction_table.php b/app/database/migrations/2014_06_27_165344_create_component_transaction_table.php index 4c3a2c825a..7cbef507ee 100644 --- a/app/database/migrations/2014_06_27_165344_create_component_transaction_table.php +++ b/app/database/migrations/2014_06_27_165344_create_component_transaction_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateComponentTransactionTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('component_transaction'); + } + /** * Run the migrations. * @@ -25,26 +35,12 @@ class CreateComponentTransactionTable extends Migration $table->integer('transaction_id')->unsigned(); // connect to components - $table->foreign('component_id') - ->references('id')->on('components') - ->onDelete('cascade'); + $table->foreign('component_id')->references('id')->on('components')->onDelete('cascade'); // connect to transactions - $table->foreign('transaction_id') - ->references('id')->on('transactions') - ->onDelete('cascade'); + $table->foreign('transaction_id')->references('id')->on('transactions')->onDelete('cascade'); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('component_transaction'); - } - } diff --git a/app/database/migrations/2014_07_05_171326_create_component_transaction_journal_table.php b/app/database/migrations/2014_07_05_171326_create_component_transaction_journal_table.php index 1d4b9c5f51..b34fbc1aa2 100644 --- a/app/database/migrations/2014_07_05_171326_create_component_transaction_journal_table.php +++ b/app/database/migrations/2014_07_05_171326_create_component_transaction_journal_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateComponentTransactionJournalTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('component_transaction_journal'); + } + /** * Run the migrations. * @@ -25,26 +35,12 @@ class CreateComponentTransactionJournalTable extends Migration $table->integer('transaction_journal_id')->unsigned(); // link components with component_id - $table->foreign('component_id') - ->references('id')->on('components') - ->onDelete('cascade'); + $table->foreign('component_id')->references('id')->on('components')->onDelete('cascade'); // link transaction journals with transaction_journal_id - $table->foreign('transaction_journal_id') - ->references('id')->on('transaction_journals') - ->onDelete('cascade'); + $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade'); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('component_transaction_journal'); - } - } diff --git a/app/database/migrations/2014_07_06_123842_create_preferences_table.php b/app/database/migrations/2014_07_06_123842_create_preferences_table.php index 9aabb3bbcd..fb74ddd1bc 100644 --- a/app/database/migrations/2014_07_06_123842_create_preferences_table.php +++ b/app/database/migrations/2014_07_06_123842_create_preferences_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreatePreferencesTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('preferences'); + } + /** * Run the migrations. * @@ -27,21 +37,9 @@ class CreatePreferencesTable extends Migration $table->text('data'); // connect preferences to users - $table->foreign('user_id') - ->references('id')->on('users') - ->onDelete('cascade'); + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('preferences'); - } - } diff --git a/app/database/migrations/2014_07_09_204843_create_session_table.php b/app/database/migrations/2014_07_09_204843_create_session_table.php index 7e29be1cce..c4423f33cf 100644 --- a/app/database/migrations/2014_07_09_204843_create_session_table.php +++ b/app/database/migrations/2014_07_09_204843_create_session_table.php @@ -10,6 +10,16 @@ use Illuminate\Database\Migrations\Migration; class CreateSessionTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('sessions'); + } + /** * Run the migrations. * @@ -26,14 +36,4 @@ class CreateSessionTable extends Migration ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('sessions'); - } - } diff --git a/app/database/migrations/2014_07_17_183717_create_limits_table.php b/app/database/migrations/2014_07_17_183717_create_limits_table.php index 0edb4a17c8..fb3dbe3660 100644 --- a/app/database/migrations/2014_07_17_183717_create_limits_table.php +++ b/app/database/migrations/2014_07_17_183717_create_limits_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateLimitsTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('limits'); + } + /** * Run the migrations. * @@ -31,21 +41,9 @@ class CreateLimitsTable extends Migration $table->unique(['component_id', 'startdate', 'repeat_freq']); // connect component - $table->foreign('component_id') - ->references('id')->on('components') - ->onDelete('cascade'); + $table->foreign('component_id')->references('id')->on('components')->onDelete('cascade'); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('limits'); - } - } diff --git a/app/database/migrations/2014_07_19_055011_create_limit_repeat_table.php b/app/database/migrations/2014_07_19_055011_create_limit_repeat_table.php index f0578b463a..e69902a3eb 100644 --- a/app/database/migrations/2014_07_19_055011_create_limit_repeat_table.php +++ b/app/database/migrations/2014_07_19_055011_create_limit_repeat_table.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class CreateLimitRepeatTable extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('limit_repetitions'); + } + /** * Run the migrations. * @@ -30,21 +40,9 @@ class CreateLimitRepeatTable extends Migration $table->unique(['limit_id', 'startdate', 'enddate']); // connect limit - $table->foreign('limit_id') - ->references('id')->on('limits') - ->onDelete('cascade'); + $table->foreign('limit_id')->references('id')->on('limits')->onDelete('cascade'); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('limit_repetitions'); - } - } diff --git a/app/database/migrations/2014_08_06_044416_recurring_transactions_to_components.php b/app/database/migrations/2014_08_06_044416_recurring_transactions_to_components.php index 18a789b4bd..326228af51 100644 --- a/app/database/migrations/2014_08_06_044416_recurring_transactions_to_components.php +++ b/app/database/migrations/2014_08_06_044416_recurring_transactions_to_components.php @@ -11,6 +11,16 @@ use Illuminate\Database\Schema\Blueprint; class RecurringTransactionsToComponents extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('component_recurring_transaction'); + } + /** * Run the migrations. * @@ -26,26 +36,12 @@ class RecurringTransactionsToComponents extends Migration $table->boolean('optional'); // link components with component_id - $table->foreign('component_id') - ->references('id')->on('components') - ->onDelete('cascade'); + $table->foreign('component_id')->references('id')->on('components')->onDelete('cascade'); // link transaction journals with transaction_journal_id - $table->foreign('recurring_transaction_id') - ->references('id')->on('recurring_transactions') - ->onDelete('cascade'); + $table->foreign('recurring_transaction_id')->references('id')->on('recurring_transactions')->onDelete('cascade'); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('component_recurring_transaction'); - } - } diff --git a/app/database/migrations/2014_08_12_173919_create_piggy_instance.php b/app/database/migrations/2014_08_12_173919_create_piggy_instance.php index c4a0c0ceeb..96dbb1ec06 100644 --- a/app/database/migrations/2014_08_12_173919_create_piggy_instance.php +++ b/app/database/migrations/2014_08_12_173919_create_piggy_instance.php @@ -6,6 +6,16 @@ use Illuminate\Database\Schema\Blueprint; class CreatePiggyInstance extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('piggybank_repetitions'); + } + /** * Run the migrations. * @@ -25,21 +35,9 @@ class CreatePiggyInstance extends Migration $table->unique(['piggybank_id', 'startdate', 'targetdate']); // connect instance to piggybank. - $table->foreign('piggybank_id') - ->references('id')->on('piggybanks') - ->onDelete('cascade'); + $table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('cascade'); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('piggybank_repetitions'); - } - } diff --git a/app/database/migrations/2014_08_18_100330_create_piggy_events.php b/app/database/migrations/2014_08_18_100330_create_piggy_events.php index 3551a6b0d9..6abd680a19 100644 --- a/app/database/migrations/2014_08_18_100330_create_piggy_events.php +++ b/app/database/migrations/2014_08_18_100330_create_piggy_events.php @@ -6,6 +6,16 @@ use Illuminate\Database\Schema\Blueprint; class CreatePiggyEvents extends Migration { + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('piggybank_events'); + } + /** * Run the migrations. * @@ -22,21 +32,9 @@ class CreatePiggyEvents extends Migration $table->decimal('amount', 10, 2); // connect instance to piggybank. - $table->foreign('piggybank_id') - ->references('id')->on('piggybanks') - ->onDelete('cascade'); + $table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('cascade'); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('piggybank_events'); - } - } diff --git a/app/database/migrations/2014_08_23_113221_create_reminders_table.php b/app/database/migrations/2014_08_23_113221_create_reminders_table.php index 12a04c3b00..bf7ac668b4 100644 --- a/app/database/migrations/2014_08_23_113221_create_reminders_table.php +++ b/app/database/migrations/2014_08_23_113221_create_reminders_table.php @@ -33,9 +33,7 @@ class CreateRemindersTable extends Migration $table->boolean('active'); // connect reminders to users - $table->foreign('user_id') - ->references('id')->on('users') - ->onDelete('cascade'); + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); } ); } diff --git a/app/database/migrations/2014_08_31_153322_create_importmaps_table.php b/app/database/migrations/2014_08_31_153322_create_importmaps_table.php index c4b68c7b68..5d7eeefcf9 100644 --- a/app/database/migrations/2014_08_31_153322_create_importmaps_table.php +++ b/app/database/migrations/2014_08_31_153322_create_importmaps_table.php @@ -1,41 +1,41 @@ increments('id'); - $table->timestamps(); - $table->integer('user_id')->unsigned(); - $table->string('file',500); - $table->integer('totaljobs')->unsigned(); - $table->integer('jobsdone')->unsigned(); + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('importmaps'); + } - // connect maps to users - $table->foreign('user_id') - ->references('id')->on('users') - ->onDelete('cascade'); - }); - } + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::create( + 'importmaps', function (Blueprint $table) { + $table->increments('id'); + $table->timestamps(); + $table->integer('user_id')->unsigned(); + $table->string('file', 500); + $table->integer('totaljobs')->unsigned(); + $table->integer('jobsdone')->unsigned(); - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('importmaps'); - } + // connect maps to users + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); + } + ); + } } diff --git a/app/database/migrations/2014_09_01_052816_create_importentries_table.php b/app/database/migrations/2014_09_01_052816_create_importentries_table.php index 70cd8e862c..5003dfc9d5 100644 --- a/app/database/migrations/2014_09_01_052816_create_importentries_table.php +++ b/app/database/migrations/2014_09_01_052816_create_importentries_table.php @@ -1,11 +1,21 @@ integer('new')->unsigned(); // connect import map. - $table->foreign('importmap_id') - ->references('id')->on('importmaps') - ->onDelete('cascade'); + $table->foreign('importmap_id')->references('id')->on('importmaps')->onDelete('cascade'); } ); } - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::drop('importentries'); - } - } diff --git a/app/database/migrations/2014_09_02_103101_create_failed_jobs_table.php b/app/database/migrations/2014_09_02_103101_create_failed_jobs_table.php index eb0e8e6c12..89cb377e9d 100644 --- a/app/database/migrations/2014_09_02_103101_create_failed_jobs_table.php +++ b/app/database/migrations/2014_09_02_103101_create_failed_jobs_table.php @@ -23,13 +23,15 @@ class CreateFailedJobsTable extends Migration */ public function up() { - Schema::create('failed_jobs', function (Blueprint $table) { - $table->increments('id'); - $table->text('connection'); - $table->text('queue'); - $table->text('payload'); - $table->timestamp('failed_at'); - }); + Schema::create( + 'failed_jobs', function (Blueprint $table) { + $table->increments('id'); + $table->text('connection'); + $table->text('queue'); + $table->text('payload'); + $table->timestamp('failed_at'); + } + ); } } diff --git a/app/database/migrations/2014_11_10_172053_create_account_meta.php b/app/database/migrations/2014_11_10_172053_create_account_meta.php index 8038f3726f..55281d7748 100644 --- a/app/database/migrations/2014_11_10_172053_create_account_meta.php +++ b/app/database/migrations/2014_11_10_172053_create_account_meta.php @@ -1,11 +1,22 @@ string('title'); + $table->text('data'); + } + ); + } + +} diff --git a/app/database/seeds/DefaultUserSeeder.php b/app/database/seeds/DefaultUserSeeder.php index 935d507811..88f6759490 100644 --- a/app/database/seeds/DefaultUserSeeder.php +++ b/app/database/seeds/DefaultUserSeeder.php @@ -10,13 +10,7 @@ class DefaultUserSeeder extends Seeder DB::table('users')->delete(); User::create( - [ - 'email' => 'thegrumpydictator@gmail.com', - 'password' => 'sander', - 'reset' => null, - 'remember_token' => null, - 'migrated' => 0 - ] + ['email' => 'thegrumpydictator@gmail.com', 'password' => 'sander', 'reset' => null, 'remember_token' => null, 'migrated' => 0] ); } From 981ffe419470dbbcf8ffb90baed532d3a8b5e3a7 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 13 Nov 2014 07:50:55 +0100 Subject: [PATCH 022/193] Added a show piggybank view, removed some others. --- app/controllers/PiggybankController.php | 15 +- .../piggybanks/create-piggybank.blade.old.php | 123 ---------- .../piggybanks/create-repeated.blade.old.php | 166 ------------- app/views/piggybanks/delete.blade.old.php | 42 ---- .../piggybanks/edit-piggybank.blade.old.php | 137 ----------- .../piggybanks/edit-repeated.blade.old.php | 160 ------------- app/views/piggybanks/index.blade.old.php | 223 ------------------ app/views/piggybanks/index.blade.php | 2 +- .../piggybanks/modifyAmount.blade.old.php | 61 ----- app/views/piggybanks/show.blade.old.php | 127 ---------- app/views/piggybanks/show.blade.php | 213 +++++++++++++++++ 11 files changed, 223 insertions(+), 1046 deletions(-) delete mode 100644 app/views/piggybanks/create-piggybank.blade.old.php delete mode 100644 app/views/piggybanks/create-repeated.blade.old.php delete mode 100644 app/views/piggybanks/delete.blade.old.php delete mode 100644 app/views/piggybanks/edit-piggybank.blade.old.php delete mode 100644 app/views/piggybanks/edit-repeated.blade.old.php delete mode 100644 app/views/piggybanks/index.blade.old.php delete mode 100644 app/views/piggybanks/modifyAmount.blade.old.php delete mode 100644 app/views/piggybanks/show.blade.old.php create mode 100644 app/views/piggybanks/show.blade.php diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index 8b94de89a7..ce8ba6b2d5 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -56,8 +56,8 @@ class PiggybankController extends BaseController $accounts = $toolkit->makeSelectList($acct->getAssetAccounts()); return View::make('piggybanks.create', compact('accounts', 'periods'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc')->with( - 'subTitle', 'Create new piggy bank' - )->with('subTitleIcon', 'fa-plus'); + 'subTitle', 'Create new piggy bank' + )->with('subTitleIcon', 'fa-plus'); } /** @@ -68,8 +68,8 @@ class PiggybankController extends BaseController public function delete(Piggybank $piggybank) { return View::make('piggybanks.delete')->with('piggybank', $piggybank)->with('subTitle', 'Delete "' . $piggybank->name . '"')->with( - 'title', 'Piggy banks' - )->with('mainTitleIcon', 'fa-sort-amount-asc'); + 'title', 'Piggy banks' + )->with('mainTitleIcon', 'fa-sort-amount-asc'); } /** @@ -212,9 +212,12 @@ class PiggybankController extends BaseController return View::make('piggybanks.remove', compact('piggybank')); } - public function show(Piggybank $piggyBank) + public function show(Piggybank $piggybank) { - throw new NotImplementedException; + + return View::make('piggybanks.show', compact('piggybank'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc')->with( + 'subTitle', $piggybank->name + ); } diff --git a/app/views/piggybanks/create-piggybank.blade.old.php b/app/views/piggybanks/create-piggybank.blade.old.php deleted file mode 100644 index 5fb1eb65d4..0000000000 --- a/app/views/piggybanks/create-piggybank.blade.old.php +++ /dev/null @@ -1,123 +0,0 @@ -@extends('layouts.default') -@section('content') -
-
-

Use piggy banks to save for a one-time goal.

-
- - -{{Form::open(['class' => 'form-horizontal','url' => route('piggybanks.store.piggybank')])}} - -
-
-

Mandatory fields

- -
- -
- - @if($errors->has('name')) -

{{$errors->first('name')}}

- @else - For example: new bike, new camera - @endif -
-
- -
- -
- {{Form::select('account_id',$accounts,Input::old('account_id') ?: Input::get('account_id'),['class' => 'form-control'])}} - @if($errors->has('account_id')) -

{{$errors->first('account_id')}}

- @else - Indicate on which account you've got your savings. - @endif -
-
- -
- {{ Form::label('targetamount', 'Target amount', ['class' => 'col-sm-4 control-label'])}} -
-
- - {{Form::input('number','targetamount', Input::old('targetamount'), ['step' => 'any', 'min' => '1', 'class' => 'form-control'])}} -
- - @if($errors->has('targetamount')) -

{{$errors->first('targetamount')}}

- @else - How much money do you need to save? - @endif -
-
-
-
-

Optional fields

- - -
- {{ Form::label('startdate', 'Start date', ['class' => 'col-sm-4 control-label'])}} -
- - @if($errors->has('startdate')) -

{{$errors->first('startdate')}}

- @else - This date indicates when you start(ed) saving money for this piggy bank. This field defaults to today and you should keep it on today. - @endif -
-
- -
- {{ Form::label('targetdate', 'Target date', ['class' => 'col-sm-4 control-label'])}} -
- - @if($errors->has('targetdate')) -

{{$errors->first('targetdate')}}

- @else - If this piggy bank has a dead line, enter it here. - @endif -
-
- -
- {{ Form::label('reminder', 'Remind you every', ['class' => 'col-sm-4 control-label'])}} -
- - - - @if($errors->has('reminder')) -

{{$errors->first('reminder')}}

- @else - Enter a number and a period and Firefly will remind you to add money - to this piggy bank every now and then. - @endif -
-
- - -
-
- -
-
- -
-
- -
-
-
-
- -{{Form::close()}} -@stop diff --git a/app/views/piggybanks/create-repeated.blade.old.php b/app/views/piggybanks/create-repeated.blade.old.php deleted file mode 100644 index cd55d693a0..0000000000 --- a/app/views/piggybanks/create-repeated.blade.old.php +++ /dev/null @@ -1,166 +0,0 @@ -@extends('layouts.default') -@section('content') -
-
-

Create repeated expenses to keep track of long-term planned expenses

-
-
- -{{Form::open(['class' => 'form-horizontal','url' => route('piggybanks.store.repeated')])}} - -
-
-

Mandatory fields

- - -
- -
- - @if($errors->has('name')) -

{{$errors->first('name')}}

- @else - For example: new bike, new camera - @endif -
-
- -
- -
- {{Form::select('account_id',$accounts,Input::old('account_id') ?: Input::get('account_id'),['class' => 'form-control'])}} - @if($errors->has('account_id')) -

{{$errors->first('account_id')}}

- @else - Indicate on which account you've got your savings. - @endif -
-
- -
- {{ Form::label('targetamount', 'Target amount', ['class' => 'col-sm-4 control-label'])}} -
-
- - {{Form::input('number','targetamount', Input::old('targetamount'), ['step' => 'any', 'min' => '1', 'class' => 'form-control'])}} -
- - @if($errors->has('targetamount')) -

{{$errors->first('targetamount')}}

- @else - How much money do you need to save? - @endif -
-
- -
- {{ Form::label('targetdate', 'Target date', ['class' => 'col-sm-4 control-label'])}} -
- - @if($errors->has('targetdate')) -

{{$errors->first('targetdate')}}

- @else - A deadline is needed to properly repeat this repeated expesnse. - @endif -
-
- -
- {{ Form::label('rep_every', 'Repeat every', ['class' => 'col-sm-4 control-label'])}} -
- - - - @if($errors->has('rep_length')) -

{{$errors->first('rep_length')}}

- @else - Something about every X years bla bla bla. - @endif -
-
-
-
- -

Optional fields

- -
- {{ Form::label('startdate', 'Start date', ['class' => 'col-sm-4 control-label'])}} -
- - @if($errors->has('startdate')) -

{{$errors->first('startdate')}}

- @else - This date indicates when you start(ed) saving money for this piggy bank. This field defaults to today and you should keep it on today. - @endif -
-
- -
- {{ Form::label('reminder', 'Remind you every', ['class' => 'col-sm-4 control-label'])}} -
- - - - @if($errors->has('reminder')) -

{{$errors->first('reminder')}}

- @else - Enter a number and a period and Firefly will remind you to save money - for this repeated expense every now and then. - @endif -
-
- - - - - - -
-
- -
-
- -
-
- -
-
-
-
- -{{Form::close()}} -@stop diff --git a/app/views/piggybanks/delete.blade.old.php b/app/views/piggybanks/delete.blade.old.php deleted file mode 100644 index 4541ea09d7..0000000000 --- a/app/views/piggybanks/delete.blade.old.php +++ /dev/null @@ -1,42 +0,0 @@ -@extends('layouts.default') -@section('content') -
-
-

Remember that deleting something is permanent.

- -
- -
- -{{Form::open(['class' => 'form-horizontal','url' => route('piggybanks.destroy',$piggybank->id)])}} - -
-
-

 

-

- This form allows you to delete the piggy bank "{{{$piggybank->name}}}". -

-

- Destroying an envelope does not remove any transactions or accounts. -

-

- Are you sure? -

- -
-
- - @if($piggybank->repeats == 1) - Cancel - @else - Cancel - @endif -
-
-
-
- - -{{Form::close()}} - -@stop diff --git a/app/views/piggybanks/edit-piggybank.blade.old.php b/app/views/piggybanks/edit-piggybank.blade.old.php deleted file mode 100644 index ec572047a3..0000000000 --- a/app/views/piggybanks/edit-piggybank.blade.old.php +++ /dev/null @@ -1,137 +0,0 @@ -@extends('layouts.default') -@section('content') -
-
-

Use piggy banks to save for a one-time goal.

-
-
- -{{Form::open(['class' => 'form-horizontal','url' => route('piggybanks.update',$piggybank->id)])}} - -
-
-

Mandatory fields

- -
- -
- - @if($errors->has('name')) -

{{$errors->first('name')}}

- @else - For example: new bike, new camera - @endif -
-
- -
- -
- {{Form::select('account_id',$accounts,Input::old('account_id') ?: $piggybank->account_id,['class' => 'form-control'])}} - @if($errors->has('account_id')) -

{{$errors->first('account_id')}}

- @else - Indicate on which account you've got your savings. - @endif -
-
- -
- {{ Form::label('targetamount', 'Target amount', ['class' => 'col-sm-4 control-label'])}} -
-
- - {{Form::input('number','targetamount', Input::old('targetamount') ?: $piggybank->targetamount, ['step' => 'any', 'min' => '1', 'class' => 'form-control'])}} -
- - @if($errors->has('targetamount')) -

{{$errors->first('targetamount')}}

- @else - How much money do you need to save? - @endif -
-
-
-
-

Optional fields

- - -
- {{ Form::label('startdate', 'Start date', ['class' => 'col-sm-4 control-label'])}} -
- @if(is_null($piggybank->startdate)) - - @else - - @endif - @if($errors->has('startdate')) -

{{$errors->first('startdate')}}

- @else - This date indicates when you start(ed) saving money for this piggy bank. This field defaults to today and you should keep it on today. - @endif -
-
- -
- {{ Form::label('targetdate', 'Target date', ['class' => 'col-sm-4 control-label'])}} -
- @if(is_null($piggybank->targetdate)) - - @else - - @endif - @if($errors->has('targetdate')) -

{{$errors->first('targetdate')}}

- @else - If this piggy bank has a dead line, enter it here. - @endif -
-
- -
- {{ Form::label('reminder', 'Remind you every', ['class' => 'col-sm-4 control-label'])}} -
- - - - @if($errors->has('reminder')) -

{{$errors->first('reminder')}}

- @else - Enter a number and a period and Firefly will remind you to add money - to this piggy bank every now and then. - @endif -
-
- - -
-
- -
-
- -
-
- -
-
-
-
- -{{Form::close()}} -@stop diff --git a/app/views/piggybanks/edit-repeated.blade.old.php b/app/views/piggybanks/edit-repeated.blade.old.php deleted file mode 100644 index a16fe00add..0000000000 --- a/app/views/piggybanks/edit-repeated.blade.old.php +++ /dev/null @@ -1,160 +0,0 @@ -@extends('layouts.default') -@section('content') -
-
-

Create repeated expenses to keep track of long-term planned expenses

-
-
- -{{Form::open(['class' => 'form-horizontal','url' => route('piggybanks.update',$piggybank->id)])}} - -
-
-

Mandatory fields

- - -
- -
- - @if($errors->has('name')) -

{{$errors->first('name')}}

- @else - For example: new bike, new camera - @endif -
-
- -
- -
- {{Form::select('account_id',$accounts,Input::old('account_id') ?: $piggybank->account_id,['class' => 'form-control'])}} - @if($errors->has('account_id')) -

{{$errors->first('account_id')}}

- @else - Indicate on which account you've got your savings. - @endif -
-
- -
- {{ Form::label('targetamount', 'Target amount', ['class' => 'col-sm-4 control-label'])}} -
-
- - {{Form::input('number','targetamount', Input::old('targetamount') ?: $piggybank->targetamount, ['step' => 'any', 'min' => '1', 'class' => 'form-control'])}} -
- - @if($errors->has('targetamount')) -

{{$errors->first('targetamount')}}

- @else - How much money do you need to save? - @endif -
-
- -
- {{ Form::label('targetdate', 'Target date', ['class' => 'col-sm-4 control-label'])}} -
- @if(is_null($piggybank->targetdate)) - - @else - - @endif - @if($errors->has('targetdate')) -

{{$errors->first('targetdate')}}

- @else - A deadline is needed to properly repeat this repeated expesnse. - @endif -
-
- -
- {{ Form::label('rep_every', 'Repeat every', ['class' => 'col-sm-4 control-label'])}} -
- - - - @if($errors->has('rep_length')) -

{{$errors->first('rep_length')}}

- @else - Something about every X years bla bla bla. - @endif -
-
-
-
- -

Optional fields

-
- {{ Form::label('startdate', 'Start date', ['class' => 'col-sm-4 control-label'])}} -
- @if(is_null($piggybank->startdate)) - - @else - - @endif - @if($errors->has('startdate')) -

{{$errors->first('startdate')}}

- @else - This date indicates when you start(ed) saving money for this piggy bank. This field defaults to today and you should keep it on today. - @endif -
-
-
- {{ Form::label('reminder', 'Remind you every', ['class' => 'col-sm-4 control-label'])}} -
- - - - @if($errors->has('reminder')) -

{{$errors->first('reminder')}}

- @else - Enter a number and a period and Firefly will remind you to save money - for this repeated expense every now and then. - @endif -
-
- - - - -
-
- -
-
- -
-
- -
-
-
-
- -{{Form::close()}} -@stop diff --git a/app/views/piggybanks/index.blade.old.php b/app/views/piggybanks/index.blade.old.php deleted file mode 100644 index 981d7bc1a2..0000000000 --- a/app/views/piggybanks/index.blade.old.php +++ /dev/null @@ -1,223 +0,0 @@ -@extends('layouts.default') -@section('content') - -@if($countNonRepeating > 0) -
-@foreach($piggybanks as $piggyBank) - @if($piggyBank->repeats == 0) -
-
- -
-
-
-
-
-

- {{mf($piggyBank->currentRelevantRep()->currentamount)}} of {{mf($piggyBank->targetamount)}}
- @if($piggyBank->targetamount-$piggyBank->currentRelevantRep()->currentamount > 0) - {{mf($piggyBank->targetamount-$piggyBank->currentRelevantRep()->currentamount)}} to go. - @endif -

- -
- - - @if($accounts[$piggyBank->account_id]['account']->leftOnAccount > 0) - - @endif - @if($piggyBank->currentRelevantRep()->currentamount > 0) - - @endif -
- - -
-
-
- @endif -@endforeach -
-
-
-   -
- -
-
-
-@endif -{{-- - - -

Current piggy banks

- @if($countNonRepeating == 0) -

No piggy banks found.

- @else - @foreach($piggybanks as $piggyBank) - @if($piggyBank->repeats == 0) -

-
namematchamount_minamount_maxdateactiveautomatchrepeat_freqidDateDescriptionAmount (€)FromToBudget / categoryIDnamematchamount_minamount_maxdateactiveautomatchrepeat_freqidDateDescriptionAmount (€)FromToBudget / categoryID
- - - - - - - - - - - -
{{mf($piggyBank->currentRelevantRep()->currentamount)}} -
-
- {{$piggyBank->currentRelevantRep()->pct()}}% -
-
-
{{mf($piggyBank->targetamount)}}
- -
- @if($accounts[$piggyBank->account_id]['account']->leftOnAccount > 0) - Add money - @endif - @if($piggyBank->currentRelevantRep()->currentamount > 0) - Remove money - @endif -
-
-

- @if(!is_null($piggyBank->targetdate)) - Target date: {{$piggyBank->targetdate->format('M jS, Y')}}
- @endif - @if(!is_null($piggyBank->reminder)) - Next reminder: TODO - @endif -

- -
-
- - -
-
- @endif - @endforeach - @endif -
-
-
-
-

Current repeated expenses

- @if($countRepeating == 0) -

No repeated expenses found.

- @else - @foreach($piggybanks as $repeated) - @if($repeated->repeats == 1) -

{{{$repeated->name}}}

- - - - - - - - - - - - - -
{{mf($repeated->currentRelevantRep()->currentamount)}} -
-
- {{$repeated->currentRelevantRep()->pct()}}% -
-
-
{{mf($repeated->targetamount)}}
- -
- @if($accounts[$repeated->account_id]['account']->leftOnAccount > 0) - Add money - @endif - @if($repeated->currentRelevantRep()->currentamount > 0) - Remove money - @endif - -
-
- - @if(!is_null($repeated->reminder)) - - Next reminder: TODO - - @endif - - -
- - -
-
- @endif - @endforeach -@endif - -
-
- - - - - - - ---}} -
-
-

Account information

- - - - - - - - - @foreach($accounts as $account) - - - - - - - - @endforeach -
AccountLeft for piggy banksTotal planned savingsSaved so farLeft to save
{{{$account['account']->name}}}{{mf($account['left'])}}{{mf($account['tosave'])}}{{mf($account['saved'])}}{{mf($account['tosave']-$account['saved'])}}
-
-
- - - - - - -@stop diff --git a/app/views/piggybanks/index.blade.php b/app/views/piggybanks/index.blade.php index 4adaf1f253..9249569b32 100644 --- a/app/views/piggybanks/index.blade.php +++ b/app/views/piggybanks/index.blade.php @@ -5,7 +5,7 @@
diff --git a/app/views/piggybanks/modifyAmount.blade.old.php b/app/views/piggybanks/modifyAmount.blade.old.php deleted file mode 100644 index 6a4b5e4ca9..0000000000 --- a/app/views/piggybanks/modifyAmount.blade.old.php +++ /dev/null @@ -1,61 +0,0 @@ - - - - {{Form::token()}} - - - - diff --git a/app/views/piggybanks/show.blade.old.php b/app/views/piggybanks/show.blade.old.php deleted file mode 100644 index 1f5faf4aa9..0000000000 --- a/app/views/piggybanks/show.blade.old.php +++ /dev/null @@ -1,127 +0,0 @@ -@extends('layouts.default') -@section('content') -
-
-
- Edit - Delete - - @if(min(max($balance,$leftOnAccount),$piggyBank->targetamount) > 0) - Add money - @endif - - @if($piggyBank->currentRelevantRep()->currentamount > 0) - Remove money - @endif -
-
-
-
-
-

General information

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldValue
Account{{{$piggyBank->account->name}}}
Target amount{{mf($piggyBank->targetamount)}}
Start date - @if(is_null($piggyBank->startdate)) - No start date - @else - {{$piggyBank->startdate->format('jS F Y')}} - @endif -
Target date - @if(is_null($piggyBank->targetdate)) - No target date - @else - {{$piggyBank->targetdate->format('jS F Y')}} - @endif -
Repeats every - @if(!is_null($piggyBank->rep_length)) - Every {{$piggyBank->rep_every}} {{$piggyBank->rep_length}}(s) - @if(!is_null($piggyBank->rep_times)) - ({{$piggyBank->rep_times}} times) - @else - (indefinitely) - @endif - @else - Does not repeat - @endif -
Reminder - @if(is_null($piggyBank->reminder)) - (no reminder) - @else - Every {{$piggyBank->reminder_skip}} {{$piggyBank->reminder}}(s) - @endif -
-
-
-

Piggy bank instances info

- @foreach($piggyBank->piggybankrepetitions()->orderBy('startdate')->get() as $rep) - - - - - - - - - - - - - - - - - - - - - -
FieldValue
ID#{{$rep->id}}
Current amount{{mf($rep->currentamount)}} of {{mf($piggyBank->targetamount)}}
Start date - @if(is_null($rep->startdate)) - No start date - @else - {{$rep->startdate->format('jS F Y')}} - @endif -
Target date - @if(is_null($rep->targetdate)) - No target date - @else - {{$rep->targetdate->format('jS F Y')}} - @endif -
- @endforeach -
-
- -@stop - -@section('scripts') -@stop \ No newline at end of file diff --git a/app/views/piggybanks/show.blade.php b/app/views/piggybanks/show.blade.php new file mode 100644 index 0000000000..4a6df0a352 --- /dev/null +++ b/app/views/piggybanks/show.blade.php @@ -0,0 +1,213 @@ +@extends('layouts.default') +@section('content') + +
+
+
+
+ Events +
+
+
+
+
+ +
+
+
+
+ Details +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Account{{{$piggybank->account->name}}}
Target amount{{mf($piggybank->targetamount)}}
Saved so far{{mf(0)}}
Left to save{{mf(0)}}
Start date + @if(is_null($piggybank->startdate)) + No start date + @else + {{$piggybank->startdate->format('jS F Y')}} + @endif +
Target date + @if(is_null($piggybank->targetdate)) + No target date + @else + {{$piggybank->targetdate->format('jS F Y')}} + @endif +
Reminder + @if(intval($piggybank->remind_me) == 0) + (no reminder) + @else + Every + @if($piggybank->reminder_skip != 0) + {{$piggybank->reminder_skip}} + @endif + {{$piggybank->reminder}}(s) + @endif +
Reminders left12
Expected amount per reminder{{mf(0)}}
+
+
+
+ +
+ +{{-- +
+
+
+ Edit + Delete + + @if(min(max($balance,$leftOnAccount),$piggybank->targetamount) > 0) + Add money + @endif + + @if($piggybank->currentRelevantRep()->currentamount > 0) + Remove money + @endif +
+
+
+
+
+

General information

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldValue
Account{{{$piggybank->account->name}}}
Target amount{{mf($piggybank->targetamount)}}
Start date + @if(is_null($piggybank->startdate)) + No start date + @else + {{$piggybank->startdate->format('jS F Y')}} + @endif +
Target date + @if(is_null($piggybank->targetdate)) + No target date + @else + {{$piggybank->targetdate->format('jS F Y')}} + @endif +
Repeats every + @if(!is_null($piggybank->rep_length)) + Every {{$piggybank->rep_every}} {{$piggybank->rep_length}}(s) + @if(!is_null($piggybank->rep_times)) + ({{$piggybank->rep_times}} times) + @else + (indefinitely) + @endif + @else + Does not repeat + @endif +
Reminder + @if(is_null($piggybank->reminder)) + (no reminder) + @else + Every {{$piggybank->reminder_skip}} {{$piggybank->reminder}}(s) + @endif +
+
+
+

Piggy bank instances info

+ @foreach($piggybank->piggybankrepetitions()->orderBy('startdate')->get() as $rep) + + + + + + + + + + + + + + + + + + + + + +
FieldValue
ID#{{$rep->id}}
Current amount{{mf($rep->currentamount)}} of {{mf($piggybank->targetamount)}}
Start date + @if(is_null($rep->startdate)) + No start date + @else + {{$rep->startdate->format('jS F Y')}} + @endif +
Target date + @if(is_null($rep->targetdate)) + No target date + @else + {{$rep->targetdate->format('jS F Y')}} + @endif +
+ @endforeach +
+
+--}} +@stop + +@section('scripts') +@stop From 4a20c008ffc73687bd86e8af040ddb4c6520d223 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 13 Nov 2014 11:17:39 +0100 Subject: [PATCH 023/193] Implementing recurring transactions. --- app/controllers/GoogleChartController.php | 4 +- app/controllers/GoogleTableController.php | 11 +- app/controllers/PiggybankController.php | 2 +- app/controllers/RecurringController.php | 42 +++++- app/lib/FireflyIII/Database/Recurring.php | 54 ++++++- .../Database/RecurringTransaction.php | 137 ------------------ public/assets/stylesheets/sbadmin/sb.css | 2 + 7 files changed, 108 insertions(+), 144 deletions(-) delete mode 100644 app/lib/FireflyIII/Database/RecurringTransaction.php diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index 61c520089b..ad7d48710b 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -464,8 +464,8 @@ class GoogleChartController extends BaseController $chart->addColumn('Name', 'string'); $chart->addColumn('Amount', 'number'); - /** @var \FireflyIII\Database\Recurring $rcr */ - $rcr = App::make('FireflyIII\Database\Recurring'); + /** @var \FireflyIII\Database\RecurringTransaction $rcr */ + $rcr = App::make('FireflyIII\Database\RecurringTransaction'); /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ $dateKit = App::make('FireflyIII\Shared\Toolkit\Date'); diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php index 9b5cfeccba..52af4237e3 100644 --- a/app/controllers/GoogleTableController.php +++ b/app/controllers/GoogleTableController.php @@ -99,6 +99,9 @@ class GoogleTableController extends BaseController $chart->addColumn('ID_Delete', 'string'); $chart->addColumn('Name_URL', 'string'); $chart->addColumn('Name', 'string'); + $chart->addColumn('Matches','string'); + $chart->addColumn('Min amount','number'); + $chart->addColumn('Max amount','number'); /** @var \FireflyIII\Database\RecurringTransaction $repository */ $repository = App::make('FireflyIII\Database\RecurringTransaction'); @@ -107,7 +110,10 @@ class GoogleTableController extends BaseController /** @var \RecurringTransaction $entry */ foreach ($set as $entry) { - $row = [$entry->id, route('recurring.edit', $entry->id), route('recurring.delete', $entry->id), route('recurring.show', $entry->id), $entry->name]; + $row = [$entry->id, route('recurring.edit', $entry->id), route('recurring.delete', $entry->id), route('recurring.show', $entry->id), $entry->name + , $entry->match,$entry->amount_min,$entry->amount_max + + ]; $chart->addRowArray($row); } @@ -365,6 +371,9 @@ class GoogleTableController extends BaseController $descriptionURL = route('transactions.show', $journal->id); $description = $journal->description; $id = $journal->id; + if(!isset($journal->transactions[0]) || !isset($journal->transactions[1])) { + continue; + } if ($journal->transactions[0]->amount < 0) { diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index ce8ba6b2d5..c3e84a1f06 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -251,7 +251,7 @@ class PiggybankController extends BaseController Session::flash('success', 'New piggy bank stored!'); if ($data['post_submit_action'] == 'create_another') { - return Redirect::route('piggybanks.create'); + return Redirect::route('piggybanks.create')->withInput(); } else { return Redirect::route('piggybanks.index'); } diff --git a/app/controllers/RecurringController.php b/app/controllers/RecurringController.php index 1569a7e9ec..3843503086 100644 --- a/app/controllers/RecurringController.php +++ b/app/controllers/RecurringController.php @@ -1,4 +1,7 @@ validate($data); + /** @var MessageBag $messages ['errors'] */ + if ($messages['errors']->count() > 0) { + Session::flash('warnings', $messages['warnings']); + Session::flash('successes', $messages['successes']); + Session::flash('error', 'Could not save recurring transaction: ' . $messages['errors']->first()); + + return Redirect::route('recurring.create')->withInput()->withErrors($messages['errors']); + } + // store! + $repos->store($data); + Session::flash('success', 'New recurring transaction stored!'); + + if ($data['post_submit_action'] == 'create_another') { + return Redirect::route('recurring.create')->withInput(); + } else { + return Redirect::route('recurring.index'); + } + break; + case 'validate_only': + $messageBags = $repos->validate($data); + Session::flash('warnings', $messageBags['warnings']); + Session::flash('successes', $messageBags['successes']); + Session::flash('errors', $messageBags['errors']); + + return Redirect::route('recurring.create')->withInput(); + break; + } } diff --git a/app/lib/FireflyIII/Database/Recurring.php b/app/lib/FireflyIII/Database/Recurring.php index d7d4bd4de3..704a13dd1e 100644 --- a/app/lib/FireflyIII/Database/Recurring.php +++ b/app/lib/FireflyIII/Database/Recurring.php @@ -9,6 +9,7 @@ use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\RecurringInterface; use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; +use Illuminate\Support\MessageBag; use LaravelBook\Ardent\Ardent; /** @@ -72,8 +73,57 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface */ public function validate(array $model) { - // TODO: Implement validate() method. - throw new NotImplementedException; + $warnings = new MessageBag; + $successes = new MessageBag; + $errors = new MessageBag; + + if (isset($model['name']) && strlen($model['name']) == 0) { + $errors->add('name', 'Name must be longer.'); + } + if (isset($model['name']) && strlen($model['name']) > 200) { + $errors->add('name', 'Name must be shorter.'); + } + + if (isset($model['match']) && strlen(trim($model['match'])) <= 2) { + $errors->add('match', 'Needs more matches.'); + } + + if (isset($model['amount_min']) && floatval($model['amount_min']) < 0.01) { + $errors->add('amount_min', 'Minimum amount must be higher.'); + } + if (isset($model['amount_max']) && floatval($model['amount_max']) < 0.02) { + $errors->add('amount_max', 'Maximum amount must be higher.'); + } + if(isset($model['amount_min']) && isset($model['amount_max']) && floatval($model['amount_min']) > floatval($model['amount_max'])) { + $errors->add('amount_max', 'Maximum amount can not be less than minimum amount.'); + $errors->add('amount_min', 'Minimum amount can not be more than maximum amount.'); + } + + if ($model['date'] != '') { + try { + new Carbon($model['date']); + } catch (\Exception $e) { + $errors->add('date', 'Invalid date.'); + } + } + + $reminders = \Config::get('firefly.budget_periods'); + if (!isset($model['repeat_freq']) || (isset($model['repeat_freq']) && !in_array($model['repeat_freq'], $reminders))) { + $errors->add('repeat_freq', 'Invalid reminder period'); + } + + if (isset($model['skip']) && intval($model['skip']) < 0) { + $errors->add('skip', 'Invalid skip.'); + } + + $set = ['name','match','amount_min','amount_max','date','repeat_freq','skip','automatch','active']; + foreach($set as $entry) { + if(!$errors->has($entry)) { + $successes->add($entry,'OK'); + } + } + + return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } /** diff --git a/app/lib/FireflyIII/Database/RecurringTransaction.php b/app/lib/FireflyIII/Database/RecurringTransaction.php deleted file mode 100644 index b4e80c489d..0000000000 --- a/app/lib/FireflyIII/Database/RecurringTransaction.php +++ /dev/null @@ -1,137 +0,0 @@ -setUser(\Auth::user()); - } - - /** - * @param Ardent $model - * - * @return bool - */ - public function destroy(Ardent $model) - { - // TODO: Implement destroy() method. - throw new NotImplementedException; - } - - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - // TODO: Implement store() method. - throw new NotImplementedException; - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - // TODO: Implement update() method. - throw new NotImplementedException; - } - - /** - * Validates an array. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param array $model - * - * @return array - */ - public function validate(array $model) - { - // TODO: Implement validate() method. - throw new NotImplementedException; - } - - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - - /** - * Returns an object with id $id. - * - * @param int $id - * - * @return Ardent - */ - public function find($id) - { - // TODO: Implement find() method. - throw new NotImplementedException; - } - - /** - * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. - * - * @param $what - * - * @return \AccountType|null - */ - public function findByWhat($what) - { - // TODO: Implement findByWhat() method. - throw new NotImplementedException; - } - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - return $this->getUser()->recurringtransactions()->get(); - } - - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. - throw new NotImplementedException; - } -} \ No newline at end of file diff --git a/public/assets/stylesheets/sbadmin/sb.css b/public/assets/stylesheets/sbadmin/sb.css index 7317b94229..f1600b673a 100755 --- a/public/assets/stylesheets/sbadmin/sb.css +++ b/public/assets/stylesheets/sbadmin/sb.css @@ -13,6 +13,8 @@ body { background:url('../../images/error.png') no-repeat center center } +.google-visualization-table-tr-head td:first-child {width:100px;} + #wrapper { width: 100%; } From 840dfa6696fc6fc89284d6edee25b1c748289982 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 13 Nov 2014 16:13:32 +0100 Subject: [PATCH 024/193] Expanded recurring transactions. --- app/controllers/GoogleTableController.php | 77 +++++++- app/controllers/PiggybankController.php | 3 +- app/controllers/RecurringController.php | 60 +++++- app/controllers/TransactionController.php | 134 ++++--------- .../Database/Ifaces/RecurringInterface.php | 15 ++ app/lib/FireflyIII/Database/Recurring.php | 182 ++++++++++++++++-- .../Database/TransactionJournal.php | 29 +-- app/lib/FireflyIII/Shared/Toolkit/Date.php | 42 +++- app/models/RecurringTransaction.php | 8 + app/views/recurring/delete.blade.php | 32 +-- app/views/recurring/edit.blade.php | 18 +- app/views/recurring/show.blade.php | 35 ++-- public/assets/javascript/firefly/budgets.js | 3 - public/assets/javascript/firefly/gcharts.js | 5 +- public/assets/javascript/firefly/recurring.js | 9 +- 15 files changed, 459 insertions(+), 193 deletions(-) diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php index 52af4237e3..592aeb8ea9 100644 --- a/app/controllers/GoogleTableController.php +++ b/app/controllers/GoogleTableController.php @@ -100,11 +100,11 @@ class GoogleTableController extends BaseController $chart->addColumn('Name_URL', 'string'); $chart->addColumn('Name', 'string'); $chart->addColumn('Matches','string'); - $chart->addColumn('Min amount','number'); - $chart->addColumn('Max amount','number'); + $chart->addColumn('Minimum amount','number'); + $chart->addColumn('Maximum amount','number'); - /** @var \FireflyIII\Database\RecurringTransaction $repository */ - $repository = App::make('FireflyIII\Database\RecurringTransaction'); + /** @var \FireflyIII\Database\Recurring $repository */ + $repository = App::make('FireflyIII\Database\Recurring'); $set = $repository->get(); @@ -136,6 +136,75 @@ class GoogleTableController extends BaseController return Response::json($chart->getData()); } + public function transactionsByRecurring(RecurringTransaction $recurring) { + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('ID', 'number'); + $chart->addColumn('ID_Edit', 'string'); + $chart->addColumn('ID_Delete', 'string'); + $chart->addColumn('Date', 'date'); + $chart->addColumn('Description_URL', 'string'); + $chart->addColumn('Description', 'string'); + $chart->addColumn('Amount', 'number'); + $chart->addColumn('From_URL', 'string'); + $chart->addColumn('From', 'string'); + $chart->addColumn('To_URL', 'string'); + $chart->addColumn('To', 'string'); + $chart->addColumn('Budget_URL', 'string'); + $chart->addColumn('Budget', 'string'); + $chart->addColumn('Category_URL', 'string'); + $chart->addColumn('Category', 'string'); + + $journals = $recurring->transactionjournals()->get(); + + /** @var TransactionJournal $transaction */ + foreach ($journals as $journal) { + $date = $journal->date; + $descriptionURL = route('transactions.show', $journal->id); + $description = $journal->description; + /** @var Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + if (floatval($transaction->amount) > 0) { + $amount = floatval($transaction->amount); + $to = $transaction->account->name; + $toURL = route('accounts.show', $transaction->account->id); + } else { + $from = $transaction->account->name; + $fromURL = route('accounts.show', $transaction->account->id); + } + + } + if (isset($journal->budgets[0])) { + $budgetURL = route('budgets.show', $journal->budgets[0]->id); + $component = $journal->budgets[0]->name; + } else { + $budgetURL = ''; + $component = ''; + } + + if (isset($journal->categories[0])) { + $categoryURL = route('categories.show', $journal->categories[0]->id); + $category = $journal->categories[0]->name; + } else { + $categoryURL = ''; + $category = ''; + } + + + $id = $journal->id; + $edit = route('transactions.edit', $journal->id); + $delete = route('transactions.delete', $journal->id); + $chart->addRow( + $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $component, $categoryURL, + $category + ); + } + + $chart->generate(); + + return Response::json($chart->getData()); + } + /** * @param Account $account */ diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index c3e84a1f06..f0521704c2 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -1,7 +1,6 @@ with('recurringTransaction', $recurringTransaction)->with( - 'subTitle', 'Delete "' . $recurringTransaction->name . '"' - ); + 'subTitle', 'Delete "' . $recurringTransaction->name . '"' + ); } /** @@ -48,8 +47,8 @@ class RecurringController extends BaseController { //Event::fire('recurring.destroy', [$recurringTransaction]); - /** @var \FireflyIII\Database\RecurringTransaction $repository */ - $repository = App::make('FireflyIII\Database\RecurringTransaction'); + /** @var \FireflyIII\Database\Recurring $repository */ + $repository = App::make('FireflyIII\Database\Recurring'); $result = $repository->destroy($recurringTransaction); if ($result === true) { @@ -72,8 +71,8 @@ class RecurringController extends BaseController $periods = \Config::get('firefly.periods_to_text'); return View::make('recurring.edit')->with('periods', $periods)->with('recurringTransaction', $recurringTransaction)->with( - 'subTitle', 'Edit "' . $recurringTransaction->name . '"' - ); + 'subTitle', 'Edit "' . $recurringTransaction->name . '"' + ); } /** @@ -96,7 +95,11 @@ class RecurringController extends BaseController return Redirect::back(); } - throw new NotImplementedException; + + /** @var \FireflyIII\Database\Recurring $repos */ + $repos = App::make('FireflyIII\Database\Recurring'); + $repos->scanEverything($recurringTransaction); + Session::flash('success', 'Rescanned everything.'); return Redirect::back(); @@ -112,7 +115,7 @@ class RecurringController extends BaseController public function store() { - $data = Input::except('_token'); + $data = Input::except('_token'); /** @var \FireflyIII\Database\Recurring $repos */ $repos = App::make('FireflyIII\Database\Recurring'); @@ -155,6 +158,43 @@ class RecurringController extends BaseController public function update(RecurringTransaction $recurringTransaction) { - throw new NotImplementedException; + /** @var \FireflyIII\Database\Recurring $repos */ + $repos = App::make('FireflyIII\Database\Recurring'); + $data = Input::except('_token'); + + switch (Input::get('post_submit_action')) { + default: + throw new FireflyException('Cannot handle post_submit_action "' . e(Input::get('post_submit_action')) . '"'); + break; + case 'create_another': + case 'update': + $messages = $repos->validate($data); + /** @var MessageBag $messages ['errors'] */ + if ($messages['errors']->count() > 0) { + Session::flash('warnings', $messages['warnings']); + Session::flash('successes', $messages['successes']); + Session::flash('error', 'Could not save recurring transaction: ' . $messages['errors']->first()); + + return Redirect::route('recurring.edit', $recurringTransaction->id)->withInput()->withErrors($messages['errors']); + } + // store! + $repos->update($recurringTransaction, $data); + Session::flash('success', 'Recurring transaction updated!'); + + if ($data['post_submit_action'] == 'create_another') { + return Redirect::route('recurring.edit', $recurringTransaction->id); + } else { + return Redirect::route('recurring.index'); + } + case 'validate_only': + $messageBags = $repos->validate($data); + Session::flash('warnings', $messageBags['warnings']); + Session::flash('successes', $messageBags['successes']); + Session::flash('errors', $messageBags['errors']); + + return Redirect::route('recurring.edit', $recurringTransaction->id)->withInput(); + break; + } + } } \ No newline at end of file diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 2cf16b311c..c916a42e5e 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -309,60 +309,6 @@ class TransactionController extends BaseController return Redirect::route('transactions.create', $what)->withInput(); break; } - - - throw new NotImplementedException; - /* - * Collect data to process: - */ - $data = Input::except(['_token']); - $data['what'] = $what; - - switch (Input::get('post_submit_action')) { - case 'store': - case 'create_another': - /* - * Try to store: - */ - $messageBag = $this->_helper->store($data); - - /* - * Failure! - */ - if ($messageBag->count() > 0) { - Session::flash('error', 'Could not save transaction: ' . $messageBag->first()); - - return Redirect::route('transactions.create', [$what])->withInput()->withErrors($messageBag); - } - - /* - * Success! - */ - Session::flash('success', 'Transaction "' . e(Input::get('description')) . '" saved!'); - - /* - * Redirect to original location or back to the form. - */ - if (Input::get('post_submit_action') == 'create_another') { - return Redirect::route('transactions.create', $what)->withInput(); - } else { - return Redirect::route('transactions.index.' . $what); - } - - break; - case 'validate_only': - $messageBags = $this->_helper->validate($data); - - Session::flash('warnings', $messageBags['warnings']); - Session::flash('successes', $messageBags['successes']); - Session::flash('errors', $messageBags['errors']); - - return Redirect::route('transactions.create', [$what])->withInput(); - break; - default: - throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.'); - break; - } } @@ -374,46 +320,46 @@ class TransactionController extends BaseController public function update(TransactionJournal $journal) { throw new NotImplementedException; - switch (Input::get('post_submit_action')) { - case 'update': - case 'return_to_edit': - $what = strtolower($journal->transactionType->type); - $messageBag = $this->_helper->update($journal, Input::all()); - if ($messageBag->count() == 0) { - // has been saved, return to index: - Session::flash('success', 'Transaction updated!'); - Event::fire('journals.update', [$journal]); - - if (Input::get('post_submit_action') == 'return_to_edit') { - return Redirect::route('transactions.edit', $journal->id)->withInput(); - } else { - return Redirect::route('transactions.index.' . $what); - } - } else { - Session::flash('error', 'Could not update transaction: ' . $journal->errors()->first()); - - return Redirect::route('transactions.edit', $journal->id)->withInput()->withErrors( - $journal->errors() - ); - } - - break; - case 'validate_only': - $data = Input::all(); - $data['what'] = strtolower($journal->transactionType->type); - $messageBags = $this->_helper->validate($data); - - Session::flash('warnings', $messageBags['warnings']); - Session::flash('successes', $messageBags['successes']); - Session::flash('errors', $messageBags['errors']); - - return Redirect::route('transactions.edit', $journal->id)->withInput(); - break; - default: - throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.'); - break; - } - +// switch (Input::get('post_submit_action')) { +// case 'update': +// case 'return_to_edit': +// $what = strtolower($journal->transactionType->type); +// $messageBag = $this->_helper->update($journal, Input::all()); +// if ($messageBag->count() == 0) { +// // has been saved, return to index: +// Session::flash('success', 'Transaction updated!'); +// Event::fire('journals.update', [$journal]); +// +// if (Input::get('post_submit_action') == 'return_to_edit') { +// return Redirect::route('transactions.edit', $journal->id)->withInput(); +// } else { +// return Redirect::route('transactions.index.' . $what); +// } +// } else { +// Session::flash('error', 'Could not update transaction: ' . $journal->errors()->first()); +// +// return Redirect::route('transactions.edit', $journal->id)->withInput()->withErrors( +// $journal->errors() +// ); +// } +// +// break; +// case 'validate_only': +// $data = Input::all(); +// $data['what'] = strtolower($journal->transactionType->type); +// $messageBags = $this->_helper->validate($data); +// +// Session::flash('warnings', $messageBags['warnings']); +// Session::flash('successes', $messageBags['successes']); +// Session::flash('errors', $messageBags['errors']); +// +// return Redirect::route('transactions.edit', $journal->id)->withInput(); +// break; +// default: +// throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.'); +// break; +// } +// } diff --git a/app/lib/FireflyIII/Database/Ifaces/RecurringInterface.php b/app/lib/FireflyIII/Database/Ifaces/RecurringInterface.php index 9f9184db52..b820b64776 100644 --- a/app/lib/FireflyIII/Database/Ifaces/RecurringInterface.php +++ b/app/lib/FireflyIII/Database/Ifaces/RecurringInterface.php @@ -20,4 +20,19 @@ interface RecurringInterface */ public function getJournalForRecurringInRange(\RecurringTransaction $recurring, Carbon $start, Carbon $end); + /** + * @param \RecurringTransaction $recurring + * + * @return bool + */ + public function scanEverything(\RecurringTransaction $recurring); + + /** + * @param \RecurringTransaction $recurring + * @param \TransactionJournal $journal + * + * @return bool + */ + public function scan(\RecurringTransaction $recurring,\TransactionJournal $journal); + } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Recurring.php b/app/lib/FireflyIII/Database/Recurring.php index 704a13dd1e..7265f57f88 100644 --- a/app/lib/FireflyIII/Database/Recurring.php +++ b/app/lib/FireflyIII/Database/Recurring.php @@ -11,6 +11,7 @@ use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; use Illuminate\Support\MessageBag; use LaravelBook\Ardent\Ardent; +use stdObject; /** * Class Recurring @@ -36,8 +37,9 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface */ public function destroy(Ardent $model) { - // TODO: Implement destroy() method. - throw new NotImplementedException; + $model->delete(); + + return true; } /** @@ -47,8 +49,38 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface */ public function store(array $data) { - // TODO: Implement store() method. - throw new NotImplementedException; + var_dump($data); + $recurring = new \RecurringTransaction; + $recurring->user()->associate($this->getUser()); + $recurring->name = $data['name']; + $recurring->match = $data['match']; + $recurring->amount_max = floatval($data['amount_max']); + $recurring->amount_min = floatval($data['amount_min']); + + $date = new Carbon($data['date']); + + + $recurring->active = isset($data['active']) && intval($data['active']) == 1 ? 1 : 0; + $recurring->automatch = isset($data['automatch']) && intval($data['automatch']) == 1 ? 1 : 0; + $recurring->repeat_freq = $data['repeat_freq']; + + /* + * Jump to the start of the period. + */ + /** @var \FireflyIII\Shared\Toolkit\Date $toolkit */ + $toolkit = \App::make('FireflyIII\Shared\Toolkit\Date'); + $date = $toolkit->startOfPeriod($date, $data['repeat_freq']); + $recurring->date = $date; + $recurring->skip = intval($data['skip']); + + if (!$recurring->validate()) { + var_dump($recurring->errors()); + exit(); + } + + $recurring->save(); + + return $recurring; } /** @@ -59,8 +91,29 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface */ public function update(Ardent $model, array $data) { - // TODO: Implement update() method. - throw new NotImplementedException; + var_dump($data); + + $model->name = $data['name']; + $model->match = $data['match']; + $model->amount_max = floatval($data['amount_max']); + $model->amount_min = floatval($data['amount_min']); + + $date = new Carbon($data['date']); + + $model->date = $date; + $model->active = isset($data['active']) && intval($data['active']) == 1 ? 1 : 0; + $model->automatch = isset($data['automatch']) && intval($data['automatch']) == 1 ? 1 : 0; + $model->repeat_freq = $data['repeat_freq']; + $model->skip = intval($data['skip']); + + if (!$model->validate()) { + var_dump($model->errors()); + exit(); + } + + $model->save(); + + return true; } /** @@ -94,7 +147,7 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface if (isset($model['amount_max']) && floatval($model['amount_max']) < 0.02) { $errors->add('amount_max', 'Maximum amount must be higher.'); } - if(isset($model['amount_min']) && isset($model['amount_max']) && floatval($model['amount_min']) > floatval($model['amount_max'])) { + if (isset($model['amount_min']) && isset($model['amount_max']) && floatval($model['amount_min']) > floatval($model['amount_max'])) { $errors->add('amount_max', 'Maximum amount can not be less than minimum amount.'); $errors->add('amount_min', 'Minimum amount can not be more than maximum amount.'); } @@ -116,10 +169,10 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface $errors->add('skip', 'Invalid skip.'); } - $set = ['name','match','amount_min','amount_max','date','repeat_freq','skip','automatch','active']; - foreach($set as $entry) { - if(!$errors->has($entry)) { - $successes->add($entry,'OK'); + $set = ['name', 'match', 'amount_min', 'amount_max', 'date', 'repeat_freq', 'skip', 'automatch', 'active']; + foreach ($set as $entry) { + if (!$errors->has($entry)) { + $successes->add($entry, 'OK'); } } @@ -199,4 +252,111 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface return $this->getUser()->transactionjournals()->where('recurring_transaction_id', $recurring->id)->after($start)->before($end)->first(); } + + /** + * @param \RecurringTransaction $recurring + * @param \TransactionJournal $journal + * + * @return bool + */ + public function scan(\RecurringTransaction $recurring, \TransactionJournal $journal) + { + /* + * Match words. + */ + $wordMatch = false; + $matches = explode(',', $recurring->match); + $description = strtolower($journal->description); + + /* + * Attach expense account to description for more narrow matching. + */ + if (count($journal->transactions) < 2) { + $transactions = $journal->transactions()->get(); + } else { + $transactions = $journal->transactions; + } + /** @var \Transaction $transaction */ + foreach ($transactions as $transaction) { + /** @var \Account $account */ + $account = $transaction->account()->first(); + /** @var \AccountType $type */ + $type = $account->accountType()->first(); + if ($type->type == 'Expense account' || $type->type == 'Beneficiary account') { + $description .= ' ' . strtolower($account->name); + } + } + \Log::debug('Final description: ' . $description); + \Log::debug('Matches searched: ' . join(':', $matches)); + + $count = 0; + foreach ($matches as $word) { + if (!(strpos($description, strtolower($word)) === false)) { + $count++; + } + } + if ($count >= count($matches)) { + $wordMatch = true; + \Log::debug('word match is true'); + } + + + /* + * Match amount. + */ + + $amountMatch = false; + if (count($transactions) > 1) { + + $amount = max(floatval($transactions[0]->amount), floatval($transactions[1]->amount)); + $min = floatval($recurring->amount_min); + $max = floatval($recurring->amount_max); + if ($amount >= $min && $amount <= $max) { + $amountMatch = true; + \Log::debug('Amount match is true!'); + } + } + + /* + * If both, update! + */ + if ($wordMatch && $amountMatch) { + $journal->recurringTransaction()->associate($recurring); + $journal->save(); + } + } + + /** + * @param \RecurringTransaction $recurring + * + * @return bool + * @throws NotImplementedException + */ + public function scanEverything(\RecurringTransaction $recurring) + { + // get all journals that (may) be relevant. + // this is usually almost all of them. + + /** @var \FireflyIII\Database\TransactionJournal $journalRepository */ + $journalRepository = \App::make('FireflyIII\Database\TransactionJournal'); + + $set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $recurring->amount_min)->where( + 'amount', '<=', $recurring->amount_max + )->get(['transaction_journal_id']); + $ids = []; + + /** @var \Transaction $entry */ + foreach ($set as $entry) { + $ids[] = intval($entry->transaction_journal_id); + } + if (count($ids) > 0) { + $journals = $journalRepository->getByIds($ids); + /** @var \TransactionJournal $journal */ + foreach ($journals as $journal) { + $this->scan($recurring, $journal); + } + } + + return true; + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 0c2430ae62..5e5420b93b 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -355,8 +355,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData */ public function getByIds(array $ids) { - // TODO: Implement getByIds() method. - throw new NotImplementedException; + return $this->getUser()->transactionjournals()->with('transactions')->whereIn('id', $ids)->orderBy('date', 'ASC')->get(); } /** @@ -390,9 +389,10 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $end->endOfMonth(); $sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin( - 'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id' - )->where('amount', '>', 0)->where('transaction_types.type', '=', 'Withdrawal')->where('transaction_journals.date', '>=', $date->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount'); + 'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id' + )->where('amount', '>', 0)->where('transaction_types.type', '=', 'Withdrawal')->where('transaction_journals.date', '>=', $date->format('Y-m-d'))->where( + 'transaction_journals.date', '<=', $end->format('Y-m-d') + )->sum('transactions.amount'); $sum = floatval($sum); return $sum; @@ -410,9 +410,10 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $end->endOfMonth(); $sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin( - 'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id' - )->where('amount', '>', 0)->where('transaction_types.type', '=', 'Deposit')->where('transaction_journals.date', '>=', $date->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount'); + 'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id' + )->where('amount', '>', 0)->where('transaction_types.type', '=', 'Deposit')->where('transaction_journals.date', '>=', $date->format('Y-m-d'))->where( + 'transaction_journals.date', '<=', $end->format('Y-m-d') + )->sum('transactions.amount'); $sum = floatval($sum); return $sum; @@ -441,12 +442,12 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $accountID = $account->id; $query = $this->_user->transactionjournals()->with(['transactions', 'transactioncurrency', 'transactiontype'])->leftJoin( - 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' - )->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')->where('accounts.id', $accountID)->where( - 'date', '>=', $start->format('Y-m-d') - )->where('date', '<=', $end->format('Y-m-d'))->orderBy('transaction_journals.date', 'DESC')->orderBy('transaction_journals.id', 'DESC')->take( - $count - )->get(['transaction_journals.*']); + 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' + )->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')->where('accounts.id', $accountID)->where( + 'date', '>=', $start->format('Y-m-d') + )->where('date', '<=', $end->format('Y-m-d'))->orderBy('transaction_journals.date', 'DESC')->orderBy('transaction_journals.id', 'DESC')->take( + $count + )->get(['transaction_journals.*']); return $query; } diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index 845381346e..352685dfca 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -3,7 +3,7 @@ namespace FireflyIII\Shared\Toolkit; use Carbon\Carbon; -use Firefly\Exception\FireflyException; +use FireflyIII\Exception\FireflyException; /** * Class Date @@ -84,4 +84,44 @@ class Date break; } } + + /** + * @param Carbon $date + * @param $repeatFreq + * + * @return Carbon + * @throws FireflyException + */ + public function startOfPeriod(Carbon $date, $repeatFreq) + { + switch ($repeatFreq) { + default: + throw new FireflyException('Cannot do startOfPeriod for $repeat_freq ' . $repeatFreq); + break; + case 'daily': + $date->startOfDay(); + break; + case 'weekly': + $date->startOfWeek(); + break; + case 'monthly': + $date->startOfMonth(); + break; + case 'quarterly': + $date->firstOfQuarter(); + break; + case 'half-year': + $month = intval($date->format('m')); + $date->startOfYear(); + if ($month >= 7) { + $date->addMonths(6); + } + break; + case 'yearly': + $date->startOfYear(); + break; + } + + return $date; + } } \ No newline at end of file diff --git a/app/models/RecurringTransaction.php b/app/models/RecurringTransaction.php index c2c45a8ac2..556535baec 100644 --- a/app/models/RecurringTransaction.php +++ b/app/models/RecurringTransaction.php @@ -91,6 +91,14 @@ class RecurringTransaction extends Ardent return $start; } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function transactionjournals() + { + return $this->hasMany('TransactionJournal'); + } + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ diff --git a/app/views/recurring/delete.blade.php b/app/views/recurring/delete.blade.php index 44fa177b1a..c8ab0e5381 100644 --- a/app/views/recurring/delete.blade.php +++ b/app/views/recurring/delete.blade.php @@ -1,29 +1,31 @@ @extends('layouts.default') @section('content') -
-
-

- Remember that deleting something is permanent. -

-
-
- {{Form::open(['class' => 'form-horizontal','url' => route('recurring.destroy',$recurringTransaction->id)])}}
-
-

- Press "Delete permanently" If you are sure you want to delete "{{{$recurringTransaction->name}}}". -

-
+
+
+
+ Delete recurring transaction "{{{$recurringTransaction->name}}}" +
+
+

+ Are you sure? +

+

+ + Cancel +

+
+
+
- - Cancel +
diff --git a/app/views/recurring/edit.blade.php b/app/views/recurring/edit.blade.php index d9680c93f1..024e8df2f1 100644 --- a/app/views/recurring/edit.blade.php +++ b/app/views/recurring/edit.blade.php @@ -1,6 +1,6 @@ @extends('layouts.default') @section('content') -{{Form::open(['class' => 'form-horizontal','url' => route('recurring.update', $recurringTransaction->id)])}} +{{Form::model($recurringTransaction, ['class' => 'form-horizontal','url' => route('recurring.update', $recurringTransaction->id)])}}
@@ -10,12 +10,12 @@ Mandatory fields
- {{Form::ffText('name',$recurringTransaction->name)}} - {{Form::ffTags('match',join(',',explode(' ',$recurringTransaction->match)))}} - {{Form::ffAmount('amount_min',$recurringTransaction->amount_min)}} - {{Form::ffAmount('amount_max',$recurringTransaction->amount_max)}} + {{Form::ffText('name')}} + {{Form::ffTags('match')}} + {{Form::ffAmount('amount_min')}} + {{Form::ffAmount('amount_max')}} {{Form::ffDate('date',$recurringTransaction->date->format('Y-m-d'))}} - {{Form::ffSelect('repeat_freq',$periods,$recurringTransaction->repeat_freq)}} + {{Form::ffSelect('repeat_freq',$periods)}}
@@ -32,9 +32,9 @@ Optional fields
- {{Form::ffInteger('skip',$recurringTransaction->skip)}} - {{Form::ffCheckbox('automatch',1,$recurringTransaction->automatch)}} - {{Form::ffCheckbox('active',1,$recurringTransaction->active)}} + {{Form::ffInteger('skip')}} + {{Form::ffCheckbox('automatch',1)}} + {{Form::ffCheckbox('active',1)}}
diff --git a/app/views/recurring/show.blade.php b/app/views/recurring/show.blade.php index 07450a0840..3d5a738cae 100644 --- a/app/views/recurring/show.blade.php +++ b/app/views/recurring/show.blade.php @@ -38,7 +38,7 @@ Matching on - @foreach(explode(' ',$recurring->match) as $word) + @foreach(explode(',',$recurring->match) as $word) {{{$word}}} @endforeach between {{mf($recurring->amount_min)}} and {{mf($recurring->amount_max)}}. @@ -47,7 +47,7 @@ Next reminder - TODO TODO + some date
@@ -74,19 +74,8 @@ Connected transaction journals
- - - - - - - - - - - - -
DateDescriptionAmount (€)FromToBudget / categoryID
+
+
@@ -95,14 +84,14 @@ @stop @section('scripts') - -{{HTML::script('assets/javascript/typeahead/bootstrap3-typeahead.min.js')}} -{{HTML::script('assets/javascript/datatables/jquery.dataTables.min.js')}} -{{HTML::script('assets/javascript/datatables/dataTables.bootstrap.js')}} + + + +{{HTML::script('assets/javascript/firefly/gcharts.options.js')}} +{{HTML::script('assets/javascript/firefly/gcharts.js')}} + {{HTML::script('assets/javascript/firefly/recurring.js')}} -@stop -@section('styles') -{{HTML::style('assets/stylesheets/datatables/dataTables.bootstrap.css')}} @stop \ No newline at end of file diff --git a/public/assets/javascript/firefly/budgets.js b/public/assets/javascript/firefly/budgets.js index 6efcabf7b7..d3aa69725c 100644 --- a/public/assets/javascript/firefly/budgets.js +++ b/public/assets/javascript/firefly/budgets.js @@ -8,14 +8,11 @@ $(function () { if (typeof(googleTable) == 'function') { - console.log('A'); if (typeof componentID != 'undefined' && typeof repetitionID == 'undefined') { - console.log('B'); googleTable('table/component/' + componentID + '/0/transactions', 'transactions'); googleColumnChart('chart/component/' + componentID + '/spending/' + year, 'componentOverview'); } else if (typeof componentID != 'undefined' && typeof repetitionID != 'undefined') { - console.log('C'); googleTable('table/component/' + componentID + '/' + repetitionID + '/transactions', 'transactions'); } } diff --git a/public/assets/javascript/firefly/gcharts.js b/public/assets/javascript/firefly/gcharts.js index 387b4a6afd..2582f55ac5 100644 --- a/public/assets/javascript/firefly/gcharts.js +++ b/public/assets/javascript/firefly/gcharts.js @@ -200,9 +200,7 @@ function googleSankeyChart(URL, container) { Format as money */ - console.log(gdata.getNumberOfRows()) if (gdata.getNumberOfRows() < 1) { - console.log('remove'); $('#' + container).parent().parent().remove(); return; } else if (gdata.getNumberOfRows() < 6) { @@ -261,7 +259,6 @@ function googleTable(URL, container) { for (var i = 0; i < x; i++) { var label = gdata.getColumnLabel(i); - console.log('Column ' + i + ':' + label); /* Format a string using the previous column as URL. */ @@ -282,7 +279,7 @@ function googleTable(URL, container) { /* Format as money */ - if (label == 'Amount' || label == 'Balance') { + if (label == 'Amount' || label == 'Balance' || label == 'Minimum amount' || label == 'Maximum amount') { money.format(gdata, i); } diff --git a/public/assets/javascript/firefly/recurring.js b/public/assets/javascript/firefly/recurring.js index 11b33573d7..5d052dc207 100644 --- a/public/assets/javascript/firefly/recurring.js +++ b/public/assets/javascript/firefly/recurring.js @@ -1,7 +1,10 @@ $(document).ready(function () { - if (typeof(googleTable) == 'function') { - googleTable('table/recurring','recurring-table'); - } + if (typeof(googleTable) == 'function') { + googleTable('table/recurring', 'recurring-table'); + } + if (typeof(googleTable) == 'function') { + googleTable('table/recurring/' + recurringID + '/transactions', 'transaction-table'); + } } ); \ No newline at end of file From 9e2f7af59b7b4be11d8b611fb879e52a0145efe2 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 13 Nov 2014 16:14:07 +0100 Subject: [PATCH 025/193] New route for table. --- app/routes.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/routes.php b/app/routes.php index 81fa459a25..5d3633c0f1 100644 --- a/app/routes.php +++ b/app/routes.php @@ -164,6 +164,7 @@ Route::group( Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']); Route::get('/table/categories', ['uses' => 'GoogleTableController@categoryList']); Route::get('/table/recurring', ['uses' => 'GoogleTableController@recurringList']); + Route::get('/table/recurring/{recurring}/transactions', ['uses' => 'GoogleTableController@transactionsByRecurring']); Route::get('/table/transactions/{what}', ['uses' => 'GoogleTableController@transactionsList'])->where(['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers']); // google table for components (categories + budgets) From 953d68c3a2cb075fabc6d141b01a8473d666afff Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 13 Nov 2014 17:01:09 +0100 Subject: [PATCH 026/193] Build some transaction handling. --- app/controllers/TransactionController.php | 87 +++++++++-------- app/lib/FireflyIII/Database/Account.php | 19 +++- .../Database/TransactionJournal.php | 97 +++++++++++++++++-- .../FireflyIII/Database/TransactionType.php | 3 + 4 files changed, 156 insertions(+), 50 deletions(-) diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index c916a42e5e..25648fb1cf 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -2,7 +2,6 @@ use FireflyIII\Exception\FireflyException; -use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\MessageBag; /** @@ -319,47 +318,51 @@ class TransactionController extends BaseController */ public function update(TransactionJournal $journal) { - throw new NotImplementedException; -// switch (Input::get('post_submit_action')) { -// case 'update': -// case 'return_to_edit': -// $what = strtolower($journal->transactionType->type); -// $messageBag = $this->_helper->update($journal, Input::all()); -// if ($messageBag->count() == 0) { -// // has been saved, return to index: -// Session::flash('success', 'Transaction updated!'); -// Event::fire('journals.update', [$journal]); -// -// if (Input::get('post_submit_action') == 'return_to_edit') { -// return Redirect::route('transactions.edit', $journal->id)->withInput(); -// } else { -// return Redirect::route('transactions.index.' . $what); -// } -// } else { -// Session::flash('error', 'Could not update transaction: ' . $journal->errors()->first()); -// -// return Redirect::route('transactions.edit', $journal->id)->withInput()->withErrors( -// $journal->errors() -// ); -// } -// -// break; -// case 'validate_only': -// $data = Input::all(); -// $data['what'] = strtolower($journal->transactionType->type); -// $messageBags = $this->_helper->validate($data); -// -// Session::flash('warnings', $messageBags['warnings']); -// Session::flash('successes', $messageBags['successes']); -// Session::flash('errors', $messageBags['errors']); -// -// return Redirect::route('transactions.edit', $journal->id)->withInput(); -// break; -// default: -// throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.'); -// break; -// } -// + /** @var \FireflyIII\Database\TransactionJournal $repos */ + $repos = App::make('FireflyIII\Database\TransactionJournal'); + + $data = Input::except('_token'); + $data['currency'] = 'EUR'; + $data['what'] = strtolower($journal->transactionType->type); + + + switch (Input::get('post_submit_action')) { + case 'update': + case 'return_to_edit': + $messageBag = $repos->update($journal, $data); + if ($messageBag->count() == 0) { + // has been saved, return to index: + Session::flash('success', 'Transaction updated!'); + // Event::fire('journals.update', [$journal]); + + if (Input::get('post_submit_action') == 'return_to_edit') { + return Redirect::route('transactions.edit', $journal->id)->withInput(); + } else { + return Redirect::route('transactions.index', $data['what']); + } + } else { + Session::flash('error', 'Could not update transaction: ' . $journal->errors()->first()); + + return Redirect::route('transactions.edit', $journal->id)->withInput()->withErrors( + $journal->errors() + ); + } + + break; + case 'validate_only': + $messageBags = $repos->validate($data); + + Session::flash('warnings', $messageBags['warnings']); + Session::flash('successes', $messageBags['successes']); + Session::flash('errors', $messageBags['errors']); + + return Redirect::route('transactions.edit', $journal->id)->withInput(); + break; + default: + throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.'); + break; + } + } diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index 414f046379..74287f07c0 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -192,8 +192,8 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface public function openingBalanceTransaction(\Account $account) { return \TransactionJournal::withRelevantData()->accountIs($account)->leftJoin( - 'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id' - )->where('transaction_types.type', 'Opening balance')->first(['transaction_journals.*']); + 'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id' + )->where('transaction_types.type', 'Opening balance')->first(['transaction_journals.*']); } /** @@ -469,4 +469,19 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface return \Account::firstOrCreate($data); } + + public function firstRevenueAccountOrCreate($name) + { + /** @var \FireflyIII\Database\AccountType $accountTypeRepos */ + $accountTypeRepos = \App::make('FireflyIII\Database\AccountType'); + + $accountType = $accountTypeRepos->findByWhat('revenue'); + + $data = ['user_id' => $this->getUser()->id, 'account_type_id' => $accountType->id, 'name' => $name, 'active' => 1]; + + return \Account::firstOrCreate($data); + + } + + } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 5e5420b93b..c440e02405 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -92,6 +92,14 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData break; case 'opening': break; + case 'deposit': + $data['to'] = $accountRepository->find($data['account_id']); + $data['from'] = $accountRepository->firstRevenueAccountOrCreate($data['revenue_account']); + break; + case 'transfer': + $data['from'] = $accountRepository->find($data['account_from_id']); + $data['to'] = $accountRepository->find($data['account_to_id']); + break; default: throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".'); @@ -118,6 +126,10 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData throw new FireflyException($validate['errors']->first()); } + /* + * TODO store budget and category. + */ + $journal->completed = 1; $journal->save(); @@ -132,8 +144,81 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData */ public function update(Ardent $model, array $data) { - // TODO: Implement update() method. - throw new NotImplementedException; + var_dump($data); + /** @var \FireflyIII\Database\TransactionType $typeRepository */ + $typeRepository = \App::make('FireflyIII\Database\TransactionType'); + + /** @var \FireflyIII\Database\Account $accountRepository */ + $accountRepository = \App::make('FireflyIII\Database\Account'); + + /** @var \FireflyIII\Database\TransactionCurrency $currencyRepository */ + $currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency'); + + /** @var \FireflyIII\Database\Transaction $transactionRepository */ + $transactionRepository = \App::make('FireflyIII\Database\Transaction'); + + $journalType = $typeRepository->findByWhat($data['what']); + $currency = $currencyRepository->findByCode($data['currency']); + + $model->transactionType()->associate($journalType); + $model->transactionCurrency()->associate($currency); + $model->user()->associate($this->getUser()); + $model->description = $data['description']; + $model->date = $data['date']; + + /* + * This must be enough to store the journal: + */ + if (!$model->validate()) { + \Log::error($model->errors()->all()); + throw new FireflyException('store() transaction journal failed, but it should not!'); + } + $model->save(); + + /* + * Still need to find the accounts related to the transactions. + * This depends on the type of transaction. + */ + switch ($data['what']) { + case 'withdrawal': + $data['from'] = $accountRepository->find($data['account_id']); + $data['to'] = $accountRepository->firstExpenseAccountOrCreate($data['expense_account']); + break; + case 'opening': + break; + case 'deposit': + $data['to'] = $accountRepository->find($data['account_id']); + $data['from'] = $accountRepository->firstRevenueAccountOrCreate($data['revenue_account']); + break; + case 'transfer': + $data['from'] = $accountRepository->find($data['account_from_id']); + $data['to'] = $accountRepository->find($data['account_to_id']); + break; + + default: + throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".'); + break; + } + /* + * Now we can update the transactions related to this journal. + */ + $amount = floatval($data['amount']); + /** @var \Transaction $transaction */ + foreach ($model->transactions()->get() as $transaction) { + if (floatval($transaction->amount) > 0) { + // the TO transaction. + $transaction->account()->associate($data['to']); + $transaction->amount = $amount; + } else { + $transaction->account()->associate($data['from']); + $transaction->amount = $amount * -1; + } + if (!$transaction->validate()) { + throw new FireflyException('Could not validate transaction while saving.'); + } + $transaction->save(); + } + return new MessageBag; } /** @@ -391,8 +476,8 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin( 'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id' )->where('amount', '>', 0)->where('transaction_types.type', '=', 'Withdrawal')->where('transaction_journals.date', '>=', $date->format('Y-m-d'))->where( - 'transaction_journals.date', '<=', $end->format('Y-m-d') - )->sum('transactions.amount'); + 'transaction_journals.date', '<=', $end->format('Y-m-d') + )->sum('transactions.amount'); $sum = floatval($sum); return $sum; @@ -412,8 +497,8 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData $sum = \DB::table('transactions')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin( 'transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id' )->where('amount', '>', 0)->where('transaction_types.type', '=', 'Deposit')->where('transaction_journals.date', '>=', $date->format('Y-m-d'))->where( - 'transaction_journals.date', '<=', $end->format('Y-m-d') - )->sum('transactions.amount'); + 'transaction_journals.date', '<=', $end->format('Y-m-d') + )->sum('transactions.amount'); $sum = floatval($sum); return $sum; diff --git a/app/lib/FireflyIII/Database/TransactionType.php b/app/lib/FireflyIII/Database/TransactionType.php index fea091ae62..8b4aad2fef 100644 --- a/app/lib/FireflyIII/Database/TransactionType.php +++ b/app/lib/FireflyIII/Database/TransactionType.php @@ -113,6 +113,9 @@ class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCa case 'withdrawal': return \TransactionType::whereType('Withdrawal')->first(); break; + case 'deposit': + return \TransactionType::whereType('Deposit')->first(); + break; default: throw new FireflyException('Cannot find transaction type described as "' . e($what) . '".'); break; From 58d8b6f95b0c2056509b7bcf06182e93856667eb Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 13 Nov 2014 21:11:00 +0100 Subject: [PATCH 027/193] Fixed the charts, added some todo items. --- app/controllers/GoogleChartController.php | 4 +- app/controllers/SearchController.php | 16 +-- app/lib/FireflyIII/Database/Recurring.php | 1 - app/lib/FireflyIII/Search/Search.php | 107 ++++++++++++++++++++ app/models/Transaction.php | 1 + app/views/partials/menu.blade.php | 2 +- public/assets/javascript/firefly/gcharts.js | 5 + 7 files changed, 125 insertions(+), 11 deletions(-) create mode 100644 app/lib/FireflyIII/Search/Search.php diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index ad7d48710b..61c520089b 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -464,8 +464,8 @@ class GoogleChartController extends BaseController $chart->addColumn('Name', 'string'); $chart->addColumn('Amount', 'number'); - /** @var \FireflyIII\Database\RecurringTransaction $rcr */ - $rcr = App::make('FireflyIII\Database\RecurringTransaction'); + /** @var \FireflyIII\Database\Recurring $rcr */ + $rcr = App::make('FireflyIII\Database\Recurring'); /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ $dateKit = App::make('FireflyIII\Shared\Toolkit\Date'); diff --git a/app/controllers/SearchController.php b/app/controllers/SearchController.php index 6217bdcac2..e1588d8e3b 100644 --- a/app/controllers/SearchController.php +++ b/app/controllers/SearchController.php @@ -1,5 +1,4 @@ _helper->searchTransactions($words); - $accounts = $this->_helper->searchAccounts($words); - $categories = $this->_helper->searchCategories($words); - $budgets = $this->_helper->searchBudgets($words); - $tags = $this->_helper->searchTags($words); + $transactions = $searcher->searchTransactions($words); + $accounts = $searcher->searchAccounts($words); + $categories = $searcher->searchCategories($words); + $budgets = $searcher->searchBudgets($words); + $tags = $searcher->searchTags($words); $result = ['transactions' => $transactions, 'accounts' => $accounts, 'categories' => $categories, 'budgets' => $budgets, 'tags' => $tags]; } diff --git a/app/lib/FireflyIII/Database/Recurring.php b/app/lib/FireflyIII/Database/Recurring.php index 7265f57f88..2590052736 100644 --- a/app/lib/FireflyIII/Database/Recurring.php +++ b/app/lib/FireflyIII/Database/Recurring.php @@ -330,7 +330,6 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface * @param \RecurringTransaction $recurring * * @return bool - * @throws NotImplementedException */ public function scanEverything(\RecurringTransaction $recurring) { diff --git a/app/lib/FireflyIII/Search/Search.php b/app/lib/FireflyIII/Search/Search.php new file mode 100644 index 0000000000..e04cef733f --- /dev/null +++ b/app/lib/FireflyIII/Search/Search.php @@ -0,0 +1,107 @@ +accounts()->with('accounttype')->where( + function ($q) use ($words) { + foreach ($words as $word) { + $q->orWhere('name', 'LIKE', '%' . e($word) . '%'); + } + } + )->get(); + } + + /** + * @param array $words + * + * @return Collection + */ + public function searchBudgets(array $words) + { + /** @var Collection $set */ + $set = \Auth::user()->budgets()->get(); + $newSet = $set->filter( + function (\Budget $b) use ($words) { + $found = 0; + foreach ($words as $word) { + if (!(strpos(strtolower($b->name), strtolower($word)) === false)) { + $found++; + } + } + + return $found > 0; + } + ); + + return $newSet; + } + + /** + * @param array $words + * + * @return Collection + */ + public function searchCategories(array $words) + { + /** @var Collection $set */ + $set = \Auth::user()->categories()->get(); + $newSet = $set->filter( + function (\Category $c) use ($words) { + $found = 0; + foreach ($words as $word) { + if (!(strpos(strtolower($c->name), strtolower($word)) === false)) { + $found++; + } + } + + return $found > 0; + } + ); + + return $newSet; + } + + /** + * @param array $words + * + * @return Collection + */ + public function searchTags(array $words) + { + return new Collection; + } + + /** + * @param array $words + * + * @return Collection + */ + public function searchTransactions(array $words) + { + return \Auth::user()->transactionjournals()->withRelevantData()->where( + function ($q) use ($words) { + foreach ($words as $word) { + $q->orWhere('description', 'LIKE', '%' . e($word) . '%'); + } + } + )->get(); + } +} \ No newline at end of file diff --git a/app/models/Transaction.php b/app/models/Transaction.php index 07de125d31..a60d5535eb 100644 --- a/app/models/Transaction.php +++ b/app/models/Transaction.php @@ -85,6 +85,7 @@ class Transaction extends Ardent */ public function connectPiggybank(\Piggybank $piggybank = null) { + // TODO connect a piggy bank to a transaction. throw new NotImplementedException; // if (is_null($piggybank)) { // return true; diff --git a/app/views/partials/menu.blade.php b/app/views/partials/menu.blade.php index b27ec1f4ad..bf070e6cdb 100644 --- a/app/views/partials/menu.blade.php +++ b/app/views/partials/menu.blade.php @@ -41,7 +41,7 @@
@@ -34,6 +21,7 @@ var what = '{{{$what}}}'; +{{HTML::script('assets/javascript/google/TableQueryWrapper.js')}} {{HTML::script('assets/javascript/firefly/gcharts.options.js')}} {{HTML::script('assets/javascript/firefly/gcharts.js')}} diff --git a/public/assets/javascript/firefly/gcharts.js b/public/assets/javascript/firefly/gcharts.js index aec0f44a7a..bfac59511e 100644 --- a/public/assets/javascript/firefly/gcharts.js +++ b/public/assets/javascript/firefly/gcharts.js @@ -314,4 +314,21 @@ function googleTable(URL, container) { } else { console.log('No container found called "' + container + '"'); } +} + +/** + * + * @param URL + * @param container + */ +function googleTablePaged(URL, container) { + var query, options; + query = new google.visualization.Query(URL); + objContainer = document.getElementById(container); + options = {'pageSize': 5}; + + query.abort(); + var tableQueryWrapper = new TableQueryWrapper(query, objContainer, options); + tableQueryWrapper.sendAndDraw(); + } \ No newline at end of file diff --git a/public/assets/javascript/firefly/transactions.js b/public/assets/javascript/firefly/transactions.js index 7f65416544..5719db469c 100644 --- a/public/assets/javascript/firefly/transactions.js +++ b/public/assets/javascript/firefly/transactions.js @@ -15,7 +15,7 @@ if ($('input[name="category"]').length > 0) { } $(document).ready(function () { - if(typeof googleTable != 'undefined') { - googleTable('table/transactions/' + what,'transaction-table'); + if(typeof googleTablePaged != 'undefined') { + googleTablePaged('table/transactions/' + what,'transaction-table'); } }); \ No newline at end of file diff --git a/public/assets/javascript/google/TableQueryWrapper.js b/public/assets/javascript/google/TableQueryWrapper.js new file mode 100644 index 0000000000..381b3da886 --- /dev/null +++ b/public/assets/javascript/google/TableQueryWrapper.js @@ -0,0 +1,159 @@ +/** + * A wrapper for a query and a table visualization. + * The object only requests 1 page + 1 row at a time, by default, in order + * to minimize the amount of data held locally. + * Table sorting and pagination is executed by issuing + * additional requests with appropriate query parameters. + * E.g., for getting the data sorted by column 'A' the following query is + * attached to the request: 'tq=order by A'. + * + * Note: Discards query strings set by the user on the query object using + * google.visualization.Query#setQuery. + * + * DISCLAIMER: This is an example code which you can copy and change as + * required. It is used with the google visualization API table visualization + * which is assumed to be loaded to the page. For more info see: + * https://developers.google.com/chart/interactive/docs/gallery/table + * https://developers.google.com/chart/interactive/docs/reference#Query + */ + + +/** + * Constructs a new table query wrapper for the specified query, container + * and tableOptions. + * + * Note: The wrapper clones the options object to adjust some of its properties. + * In particular: + * sort {string} set to 'event'. + * page {string} set to 'event'. + * pageSize {Number} If number <= 0 set to 10. + * showRowNumber {boolean} set to true. + * firstRowNumber {number} set according to the current page. + * sortAscending {boolean} set according to the current sort. + * sortColumn {number} set according to the given sort. + * @constructor + */ +var TableQueryWrapper = function(query, container, options) { + + this.table = new google.visualization.Table(container); + this.query = query; + this.sortQueryClause = ''; + this.pageQueryClause = ''; + this.container = container; + this.currentDataTable = null; + + var self = this; + var addListener = google.visualization.events.addListener; + addListener(this.table, 'page', function(e) {self.handlePage(e)}); + addListener(this.table, 'sort', function(e) {self.handleSort(e)}); + + options = options || {}; + options = TableQueryWrapper.clone(options); + + options['sort'] = 'event'; + options['page'] = 'event'; + options['showRowNumber'] = true; + var buttonConfig = 'pagingButtonsConfiguration'; + options[buttonConfig] = options[buttonConfig] || 'both'; + options['pageSize'] = (options['pageSize'] > 0) ? options['pageSize'] : 10; + this.pageSize = options['pageSize']; + this.tableOptions = options; + this.currentPageIndex = 0; + this.setPageQueryClause(0); +}; + + +/** + * Sends the query and upon its return draws the Table visualization in the + * container. If the query refresh interval is set then the visualization will + * be redrawn upon each refresh. + */ +TableQueryWrapper.prototype.sendAndDraw = function() { + this.query.abort(); + var queryClause = this.sortQueryClause + ' ' + this.pageQueryClause; + this.query.setQuery(queryClause); + this.table.setSelection([]); + var self = this; + this.query.send(function(response) {self.handleResponse(response)}); +}; + + +/** Handles the query response after a send returned by the data source. */ +TableQueryWrapper.prototype.handleResponse = function(response) { + this.currentDataTable = null; + if (response.isError()) { + google.visualization.errors.addError(this.container, response.getMessage(), + response.getDetailedMessage(), {'showInTooltip': false}); + } else { + // make data: + //this.currentDataTable= new google.visualization.DataTable(response); + //console.log(response); + this.currentDataTable = response.getDataTable(); + this.table.draw(this.currentDataTable, this.tableOptions); + } +}; + + +/** Handles a sort event with the given properties. Will page to page=0. */ +TableQueryWrapper.prototype.handleSort = function(properties) { + var columnIndex = properties['column']; + var isAscending = properties['ascending']; + this.tableOptions['sortColumn'] = columnIndex; + this.tableOptions['sortAscending'] = isAscending; + // dataTable exists since the user clicked the table. + var colID = this.currentDataTable.getColumnId(columnIndex); + this.sortQueryClause = 'order by `' + colID + (!isAscending ? '` desc' : '`'); + // Calls sendAndDraw internally. + this.handlePage({'page': 0}); +}; + + +/** Handles a page event with the given properties. */ +TableQueryWrapper.prototype.handlePage = function(properties) { + var localTableNewPage = properties['page']; // 1, -1 or 0 + var newPage = 0; + if (localTableNewPage != 0) { + newPage = this.currentPageIndex + localTableNewPage; + } + if (this.setPageQueryClause(newPage)) { + this.sendAndDraw(); + } +}; + + +/** + * Sets the pageQueryClause and table options for a new page request. + * In case the next page is requested - checks that another page exists + * based on the previous request. + * Returns true if a new page query clause was set, false otherwise. + */ +TableQueryWrapper.prototype.setPageQueryClause = function(pageIndex) { + var pageSize = this.pageSize; + + if (pageIndex < 0) { + return false; + } + var dataTable = this.currentDataTable; + if ((pageIndex == this.currentPageIndex + 1) && dataTable) { + if (dataTable.getNumberOfRows() <= pageSize) { + return false; + } + } + this.currentPageIndex = pageIndex; + var newStartRow = this.currentPageIndex * pageSize; + // Get the pageSize + 1 so that we can know when the last page is reached. + this.pageQueryClause = 'limit ' + (pageSize + 1) + ' offset ' + newStartRow; + // Note: row numbers are 1-based yet dataTable rows are 0-based. + this.tableOptions['firstRowNumber'] = newStartRow + 1; + return true; +}; + + +/** Performs a shallow clone of the given object. */ +TableQueryWrapper.clone = function(obj) { + var newObj = {}; + for (var key in obj) { + newObj[key] = obj[key]; + } + return newObj; +}; \ No newline at end of file From 96ab112b22718cdaa8701050a2b0bc901d117ddb Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 08:52:58 +0100 Subject: [PATCH 030/193] Removed most, if not all, references to Google Charts (the tables part). --- app/controllers/GoogleTableController.php | 367 ------------------ app/lib/FireflyIII/Shared/Google/Table.php | 8 - .../FireflyIII/Shared/Google/Table/Table.php | 13 - .../Shared/Google/Table/Transactions.php | 192 --------- app/routes.php | 15 +- app/views/index.blade.php | 2 +- .../journals-large.old.blade.php} | 0 .../journals-small-index.old.blade.php} | 0 .../journals-small-noaccount.old.blade.php} | 0 .../transactions.old.blade.php} | 0 app/views/search/index.blade.php | 2 +- app/views/transactions/index.blade.php | 1 - public/assets/javascript/firefly/gcharts.js | 105 ----- .../javascript/firefly/gcharts.options.js | 7 +- .../javascript/google/TableQueryWrapper.js | 159 -------- 15 files changed, 10 insertions(+), 861 deletions(-) delete mode 100644 app/controllers/GoogleTableController.php delete mode 100644 app/lib/FireflyIII/Shared/Google/Table.php delete mode 100644 app/lib/FireflyIII/Shared/Google/Table/Table.php delete mode 100644 app/lib/FireflyIII/Shared/Google/Table/Transactions.php rename app/views/{transactions/journals-large.blade.php => lists.old/journals-large.old.blade.php} (100%) rename app/views/{transactions/journals-small-index.blade.php => lists.old/journals-small-index.old.blade.php} (100%) rename app/views/{transactions/journals-small-noaccount.blade.php => lists.old/journals-small-noaccount.old.blade.php} (100%) rename app/views/{lists/transactions.blade.php => lists.old/transactions.old.blade.php} (100%) delete mode 100644 public/assets/javascript/google/TableQueryWrapper.js diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php deleted file mode 100644 index 7ff6392524..0000000000 --- a/app/controllers/GoogleTableController.php +++ /dev/null @@ -1,367 +0,0 @@ -getAssetAccounts(); - break; - case 'expense': - $list = $acct->getExpenseAccounts(); - break; - case 'revenue': - $list = $acct->getRevenueAccounts(); - break; - } - - - $chart = App::make('gchart'); - $chart->addColumn('ID', 'number'); - $chart->addColumn('ID_Edit', 'string'); - $chart->addColumn('ID_Delete', 'string'); - $chart->addColumn('Name_URL', 'string'); - $chart->addColumn('Name', 'string'); - $chart->addColumn('Balance', 'number'); - - /** @var \Account $entry */ - foreach ($list as $entry) { - $edit = route('accounts.edit', $entry->id); - $delete = route('accounts.delete', $entry->id); - $show = route('accounts.show', $entry->id); - $chart->addRow($entry->id, $edit, $delete, $show, $entry->name, $entry->balance()); - } - - $chart->generate(); - - return Response::json($chart->getData()); - - - } - - /** - * @return \Illuminate\Http\JsonResponse - */ - public function categoryList() - { - - /** @var \FireflyIII\Database\Category $repos */ - $repos = App::make('FireflyIII\Database\Category'); - - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('ID', 'number'); - $chart->addColumn('ID_Edit', 'string'); - $chart->addColumn('ID_Delete', 'string'); - $chart->addColumn('Name_URL', 'string'); - $chart->addColumn('Name', 'string'); - - $list = $repos->get(); - - /** @var Category $entry */ - foreach ($list as $entry) { - $chart->addRow( - $entry->id, route('categories.edit', $entry->id), route('categories.delete', $entry->id), route('categories.show', $entry->id), $entry->name - ); - } - - - $chart->generate(); - - return Response::json($chart->getData()); - - } - - public function recurringList() - { - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('ID', 'number'); - $chart->addColumn('ID_Edit', 'string'); - $chart->addColumn('ID_Delete', 'string'); - $chart->addColumn('Name_URL', 'string'); - $chart->addColumn('Name', 'string'); - $chart->addColumn('Matches', 'string'); - $chart->addColumn('Minimum amount', 'number'); - $chart->addColumn('Maximum amount', 'number'); - - /** @var \FireflyIII\Database\Recurring $repository */ - $repository = App::make('FireflyIII\Database\Recurring'); - - $set = $repository->get(); - - /** @var \RecurringTransaction $entry */ - foreach ($set as $entry) { - $row = [$entry->id, route('recurring.edit', $entry->id), route('recurring.delete', $entry->id), route('recurring.show', $entry->id), $entry->name, - $entry->match, $entry->amount_min, $entry->amount_max - - ]; - $chart->addRowArray($row); - - } - - - /* - * name - match - amount_min - amount_max - date - active - automatch - repeat_freq - id - - */ - $chart->generate(); - - return Response::json($chart->getData()); - } - - /** - * @param Account $account - */ - public function transactionsByAccount(Account $account) - { - $table = new \FireflyIII\Shared\Google\Table\Transactions; - /* - * Find transactions: - */ - $accountID = $account->id; - $transactions = $account->transactions()->with( - ['transactionjournal', 'transactionjournal.transactions' => function ($q) use ($accountID) { - $q->where('account_id', '!=', $accountID); - }, 'transactionjournal.budgets', 'transactionjournal.transactiontype', 'transactionjournal.categories'] - )->before(Session::get('end'))->after( - Session::get('start') - )->orderBy('date', 'DESC')->get(); - - $collection = new Collection; - /** @var Transaction $transaction */ - foreach ($transactions as $transaction) { - - $date = $transaction->transactionJournal->date; - $descriptionURL = route('transactions.show', $transaction->transaction_journal_id); - $description = $transaction->transactionJournal->description; - $amount = floatval($transaction->amount); - - if ($transaction->transactionJournal->transactions[0]->account->id == $account->id) { - $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[1]->account->id); - $opposingAccountName = $transaction->transactionJournal->transactions[1]->account->name; - } else { - $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[0]->account->id); - $opposingAccountName = $transaction->transactionJournal->transactions[0]->account->name; - } - if (isset($transaction->transactionJournal->budgets[0])) { - $budgetURL = route('budgets.show', $transaction->transactionJournal->budgets[0]->id); - $budget = $transaction->transactionJournal->budgets[0]->name; - } else { - $budgetURL = ''; - $budget = ''; - } - - if (isset($transaction->transactionJournal->categories[0])) { - $categoryURL = route('categories.show', $transaction->transactionJournal->categories[0]->id); - $category = $transaction->transactionJournal->categories[0]->name; - } else { - $categoryURL = ''; - $category = ''; - } - - - if ($amount < 0) { - $from = $account->name; - $fromURL = route('accounts.show', $account->id); - - $to = $opposingAccountName; - $toURL = $opposingAccountURI; - } else { - $to = $account->name; - $toURL = route('accounts.show', $account->id); - - $from = $opposingAccountName; - $fromURL = $opposingAccountURI; - } - - $id = $transaction->transactionJournal->id; - $edit = route('transactions.edit', $transaction->transactionJournal->id); - $delete = route('transactions.delete', $transaction->transactionJournal->id); - $chart->addRow( - $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $budget, $categoryURL, $category - ); - } - - // Date - // Description - // Amount (€) - // From - // To - // Budget / category - // ID - - - $chart->generate(); - - return Response::json($chart->getData()); - } - - /** - * @param Component $component - * @param LimitRepetition $repetition - */ - public function transactionsByComponent(Component $component, LimitRepetition $repetition = null) - { - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('ID', 'number'); - $chart->addColumn('ID_Edit', 'string'); - $chart->addColumn('ID_Delete', 'string'); - $chart->addColumn('Date', 'date'); - $chart->addColumn('Description_URL', 'string'); - $chart->addColumn('Description', 'string'); - $chart->addColumn('Amount', 'number'); - $chart->addColumn('From_URL', 'string'); - $chart->addColumn('From', 'string'); - $chart->addColumn('To_URL', 'string'); - $chart->addColumn('To', 'string'); - $chart->addColumn('Budget_URL', 'string'); - $chart->addColumn('Budget', 'string'); - $chart->addColumn('Category_URL', 'string'); - $chart->addColumn('Category', 'string'); - - if (is_null($repetition)) { - $journals = $component->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->orderBy('date', 'DESC') - ->get(); - } else { - $journals = $component->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->after( - $repetition->startdate - )->before($repetition->enddate)->orderBy('date', 'DESC')->get(); - } - /** @var TransactionJournal $transaction */ - foreach ($journals as $journal) { - $date = $journal->date; - $descriptionURL = route('transactions.show', $journal->id); - $description = $journal->description; - /** @var Transaction $transaction */ - foreach ($journal->transactions as $transaction) { - if (floatval($transaction->amount) > 0) { - $amount = floatval($transaction->amount); - $to = $transaction->account->name; - $toURL = route('accounts.show', $transaction->account->id); - } else { - $from = $transaction->account->name; - $fromURL = route('accounts.show', $transaction->account->id); - } - - } - if (isset($journal->budgets[0])) { - $budgetURL = route('budgets.show', $journal->budgets[0]->id); - $component = $journal->budgets[0]->name; - } else { - $budgetURL = ''; - $component = ''; - } - - if (isset($journal->categories[0])) { - $categoryURL = route('categories.show', $journal->categories[0]->id); - $category = $journal->categories[0]->name; - } else { - $categoryURL = ''; - $category = ''; - } - - - $id = $journal->id; - $edit = route('transactions.edit', $journal->id); - $delete = route('transactions.delete', $journal->id); - $chart->addRow( - $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $component, $categoryURL, - $category - ); - } - - - $chart->generate(); - - return Response::json($chart->getData()); - - } - - public function transactionsByRecurring(RecurringTransaction $recurring) - { - - /** @var \FireflyIII\Shared\Google\Table\Transactions $table */ - $table = new \FireflyIII\Shared\Google\Table\Transactions; - $journals = $recurring->transactionjournals()->get(); - - $table->addData($journals); - - return $table->generate(); - } - - /** - * @param $what - * - * @return \Illuminate\Http\JsonResponse - */ - public function transactionsList($what) - { - /* - * Process some google stuff: - */ - $parameters = explode(' ',trim(Input::get('tq'))); - $limit = intval($parameters[1]); - $offset = intval($parameters[3]); - $request = explode(':',Input::get('tqx')); - $reqID = $request[1]; - - /** @var \FireflyIII\Shared\Google\Table\Transactions $table */ - $table = new \FireflyIII\Shared\Google\Table\Transactions; - $table->setPaging(true); - $table->setLimit($limit); - $table->setOffset($offset); - $table->setReqID($reqID); - - /** @var \FireflyIII\Database\TransactionJournal $repository */ - $repository = App::make('FireflyIII\Database\TransactionJournal'); - - switch ($what) { - case 'expenses': - case 'withdrawal': - $list = $repository->getWithdrawals($limit, $offset); - break; - case 'revenue': - case 'deposit': - $list = $repository->getDeposits($limit, $offset); - break; - case 'transfer': - case 'transfers': - $list = $repository->getTransfers($limit, $offset); - break; - } - - $table->addData($list); - - echo $table->generate(); - exit; - } -} \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Google/Table.php b/app/lib/FireflyIII/Shared/Google/Table.php deleted file mode 100644 index 1290430cb7..0000000000 --- a/app/lib/FireflyIII/Shared/Google/Table.php +++ /dev/null @@ -1,8 +0,0 @@ -chart = \App::make('gchart'); - $this->chart->addColumn('ID', 'number'); - $this->chart->addColumn('ID_Edit', 'string'); - $this->chart->addColumn('ID_Delete', 'string'); - $this->chart->addColumn('Date', 'date'); - $this->chart->addColumn('Description_URL', 'string'); - $this->chart->addColumn('Description', 'string'); - $this->chart->addColumn('Amount', 'number'); - $this->chart->addColumn('From_URL', 'string'); - $this->chart->addColumn('From', 'string'); - $this->chart->addColumn('To_URL', 'string'); - $this->chart->addColumn('To', 'string'); - $this->chart->addColumn('Budget_URL', 'string'); - $this->chart->addColumn('Budget', 'string'); - $this->chart->addColumn('Category_URL', 'string'); - $this->chart->addColumn('Category', 'string'); - } - - public function addData(Collection $data) - { - /** @var \TransactionJournal $entry */ - foreach ($data as $entry) { - $date = $entry->date; - $descriptionURL = route('transactions.show', $entry->id); - $description = $entry->description; - /** @var Transaction $transaction */ - foreach ($entry->transactions as $transaction) { - if (floatval($transaction->amount) > 0) { - $amount = floatval($transaction->amount); - $to = $transaction->account->name; - $toURL = route('accounts.show', $transaction->account->id); - } else { - $from = $transaction->account->name; - $fromURL = route('accounts.show', $transaction->account->id); - } - - } - if (isset($entry->budgets[0])) { - $budgetURL = route('budgets.show', $entry->budgets[0]->id); - $component = $entry->budgets[0]->name; - } else { - $budgetURL = ''; - $component = ''; - } - - if (isset($entry->categories[0])) { - $categoryURL = route('categories.show', $entry->categories[0]->id); - $category = $entry->categories[0]->name; - } else { - $categoryURL = ''; - $category = ''; - } - - - $id = $entry->id; - $edit = route('transactions.edit', $entry->id); - $delete = route('transactions.delete', $entry->id); - $this->chart->addRow( - $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $component, $categoryURL, - $category - ); - } - } - - public function generate() - { - if ($this->getPaging() && (is_null($this->getLimit()) || is_null($this->getOffset()) || is_null($this->getReqID()))) { - throw new FireflyException('Cannot page without parameters!'); - } - $this->chart->generate(); - if($this->getPaging()) { - $data = [ - 'version' => '0.6', - 'reqId' => $this->getReqID(), - 'status' => 'warning', - 'warnings' => [ - [ - 'reason' => 'data_truncated', - 'message' => 'Retrieved data was truncated', - 'detailed_message' => 'Data has been truncated due to userrequest (LIMIT in query)' - ] - ], - 'sig' => '12345', - 'table' => $this->chart->getData() - ]; - $return = '// Data table response'."\n".'google.visualization.Query.setResponse(' . json_encode($data).');'; - return $return; - //"version":"0.6","reqId":"0","status":"warning","warnings":[{"reason":"data_truncated","message":"Retrieved data was truncated","detailed_message":"Data has been truncated due to userrequest (LIMIT in query)"}],"sig":"253683512","table - } - - - - return \Response::json($this->chart->getData()); - } - - /** - * @return mixed - */ - public function getPaging() - { - return $this->paging; - } - - /** - * @param mixed $paging - */ - public function setPaging($paging) - { - $this->paging = $paging; - } - - /** - * @return int - */ - public function getLimit() - { - return $this->limit; - } - - /** - * @param int $limit - */ - public function setLimit($limit) - { - $this->limit = $limit; - } - - /** - * @return int - */ - public function getOffset() - { - return $this->offset; - } - - /** - * @param int $offset - */ - public function setOffset($offset) - { - $this->offset = $offset; - } - - /** - * @return string - */ - public function getReqID() - { - return $this->reqID; - } - - /** - * @param string $reqID - */ - public function setReqID($reqID) - { - $this->reqID = $reqID; - } - - -} \ No newline at end of file diff --git a/app/routes.php b/app/routes.php index 5d3633c0f1..7441f93923 100644 --- a/app/routes.php +++ b/app/routes.php @@ -160,15 +160,14 @@ Route::group( Route::get('/chart/component/{component}/spending/{year}', ['uses' => 'GoogleChartController@componentsAndSpending']); // google table controller - Route::get('/table/account/{account}/transactions', ['uses' => 'GoogleTableController@transactionsByAccount']); - Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']); - Route::get('/table/categories', ['uses' => 'GoogleTableController@categoryList']); - Route::get('/table/recurring', ['uses' => 'GoogleTableController@recurringList']); - Route::get('/table/recurring/{recurring}/transactions', ['uses' => 'GoogleTableController@transactionsByRecurring']); - Route::get('/table/transactions/{what}', ['uses' => 'GoogleTableController@transactionsList'])->where(['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers']); - + #Route::get('/table/account/{account}/transactions', ['uses' => 'GoogleTableController@transactionsByAccount']); + #Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']); + #Route::get('/table/categories', ['uses' => 'GoogleTableController@categoryList']); + #Route::get('/table/recurring', ['uses' => 'GoogleTableController@recurringList']); + #Route::get('/table/recurring/{recurring}/transactions', ['uses' => 'GoogleTableController@transactionsByRecurring']); + #Route::get('/table/transactions/{what}', ['uses' => 'GoogleTableController@transactionsList'])->where(['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers']); // google table for components (categories + budgets) - Route::get('/table/component/{component}/{limitrepetition}/transactions', ['uses' => 'GoogleTableController@transactionsByComponent']); + #Route::get('/table/component/{component}/{limitrepetition}/transactions', ['uses' => 'GoogleTableController@transactionsByComponent']); // home controller diff --git a/app/views/index.blade.php b/app/views/index.blade.php index 479e6ede81..c5422f830b 100644 --- a/app/views/index.blade.php +++ b/app/views/index.blade.php @@ -101,7 +101,7 @@
- @include('transactions.journals-small-index',['transactions' => $data[0],'account' => $data[1]]) + @include('lists.old.journals-small-index',['transactions' => $data[0],'account' => $data[1]])
@endforeach diff --git a/app/views/transactions/journals-large.blade.php b/app/views/lists.old/journals-large.old.blade.php similarity index 100% rename from app/views/transactions/journals-large.blade.php rename to app/views/lists.old/journals-large.old.blade.php diff --git a/app/views/transactions/journals-small-index.blade.php b/app/views/lists.old/journals-small-index.old.blade.php similarity index 100% rename from app/views/transactions/journals-small-index.blade.php rename to app/views/lists.old/journals-small-index.old.blade.php diff --git a/app/views/transactions/journals-small-noaccount.blade.php b/app/views/lists.old/journals-small-noaccount.old.blade.php similarity index 100% rename from app/views/transactions/journals-small-noaccount.blade.php rename to app/views/lists.old/journals-small-noaccount.old.blade.php diff --git a/app/views/lists/transactions.blade.php b/app/views/lists.old/transactions.old.blade.php similarity index 100% rename from app/views/lists/transactions.blade.php rename to app/views/lists.old/transactions.old.blade.php diff --git a/app/views/search/index.blade.php b/app/views/search/index.blade.php index c8940ac822..c20ec700b7 100644 --- a/app/views/search/index.blade.php +++ b/app/views/search/index.blade.php @@ -9,7 +9,7 @@ Transactions ({{$result['transactions']->count()}})
- @include('transactions.journals-small-noaccount',['transactions' => $result['transactions']]) + @include('...lists.old.journals-small-noaccount',['transactions' => $result['transactions']])
diff --git a/app/views/transactions/index.blade.php b/app/views/transactions/index.blade.php index 2e85e74aff..3410db02fe 100644 --- a/app/views/transactions/index.blade.php +++ b/app/views/transactions/index.blade.php @@ -21,7 +21,6 @@ var what = '{{{$what}}}'; -{{HTML::script('assets/javascript/google/TableQueryWrapper.js')}} {{HTML::script('assets/javascript/firefly/gcharts.options.js')}} {{HTML::script('assets/javascript/firefly/gcharts.js')}} diff --git a/public/assets/javascript/firefly/gcharts.js b/public/assets/javascript/firefly/gcharts.js index bfac59511e..f11341d821 100644 --- a/public/assets/javascript/firefly/gcharts.js +++ b/public/assets/javascript/firefly/gcharts.js @@ -226,109 +226,4 @@ function googleSankeyChart(URL, container) { } else { console.log('No container found called "' + container + '"'); } -} - -/** - * TODO fix this method so the layout is nice and dandy. - * @param URL - * @param container - */ -function googleTable(URL, container) { - if ($('#' + container).length == 1) { - $.getJSON(URL).success(function (data) { - /* - Get the data from the JSON - */ - var gdata = new google.visualization.DataTable(data); - - /* - Create a new google charts object. - */ - var chart = new google.visualization.Table(document.getElementById(container)); - - /* - Do something with formatters: - */ - var x = gdata.getNumberOfColumns(); - var columnsToHide = new Array; - var URLFormatter = new google.visualization.PatternFormat('{1}'); - - var EditButtonFormatter = new google.visualization.PatternFormat('
'); - - var money = new google.visualization.NumberFormat({ - decimalSymbol: ',', - groupingSymbol: '.', - prefix: '\u20AC ' - }); - - - for (var i = 0; i < x; i++) { - var label = gdata.getColumnLabel(i); - /* - Format a string using the previous column as URL. - */ - if (label == 'Description' || label == 'From' || label == 'Name' || label == 'To' || label == 'Budget' || label == 'Category') { - URLFormatter.format(gdata, [i - 1, i], i); - columnsToHide.push(i - 1); - } - if (label == 'ID') { - EditButtonFormatter.format(gdata, [i + 1, i + 2], i); - columnsToHide.push(i + 1, i + 2); - } - - /* - Format with buttons: - */ - - - /* - Format as money - */ - if (label == 'Amount' || label == 'Balance' || label == 'Minimum amount' || label == 'Maximum amount') { - money.format(gdata, i); - } - - } - - - //var formatter = new google.visualization.PatternFormat('{1}'); - - //formatter.format(gdata, [5, 6], 6); - //formatter.format(gdata, [7, 8], 8); - - - var view = new google.visualization.DataView(gdata); - // hide certain columns: - - view.hideColumns(columnsToHide); - - - /* - Draw it: - */ - chart.draw(view, defaultTableOptions); - - }).fail(function () { - $('#' + container).addClass('google-chart-error'); - }); - } else { - console.log('No container found called "' + container + '"'); - } -} - -/** - * - * @param URL - * @param container - */ -function googleTablePaged(URL, container) { - var query, options; - query = new google.visualization.Query(URL); - objContainer = document.getElementById(container); - options = {'pageSize': 5}; - - query.abort(); - var tableQueryWrapper = new TableQueryWrapper(query, objContainer, options); - tableQueryWrapper.sendAndDraw(); - } \ No newline at end of file diff --git a/public/assets/javascript/firefly/gcharts.options.js b/public/assets/javascript/firefly/gcharts.options.js index acba8a81bb..e4d983a85b 100644 --- a/public/assets/javascript/firefly/gcharts.options.js +++ b/public/assets/javascript/firefly/gcharts.options.js @@ -115,9 +115,4 @@ var defaultPieChartOptions = { var defaultSankeyChartOptions = { height: 400 -} -var defaultTableOptions = { - allowHtml: true, - page: 'enable', - pageSize: 50 -}; \ No newline at end of file +} \ No newline at end of file diff --git a/public/assets/javascript/google/TableQueryWrapper.js b/public/assets/javascript/google/TableQueryWrapper.js deleted file mode 100644 index 381b3da886..0000000000 --- a/public/assets/javascript/google/TableQueryWrapper.js +++ /dev/null @@ -1,159 +0,0 @@ -/** - * A wrapper for a query and a table visualization. - * The object only requests 1 page + 1 row at a time, by default, in order - * to minimize the amount of data held locally. - * Table sorting and pagination is executed by issuing - * additional requests with appropriate query parameters. - * E.g., for getting the data sorted by column 'A' the following query is - * attached to the request: 'tq=order by A'. - * - * Note: Discards query strings set by the user on the query object using - * google.visualization.Query#setQuery. - * - * DISCLAIMER: This is an example code which you can copy and change as - * required. It is used with the google visualization API table visualization - * which is assumed to be loaded to the page. For more info see: - * https://developers.google.com/chart/interactive/docs/gallery/table - * https://developers.google.com/chart/interactive/docs/reference#Query - */ - - -/** - * Constructs a new table query wrapper for the specified query, container - * and tableOptions. - * - * Note: The wrapper clones the options object to adjust some of its properties. - * In particular: - * sort {string} set to 'event'. - * page {string} set to 'event'. - * pageSize {Number} If number <= 0 set to 10. - * showRowNumber {boolean} set to true. - * firstRowNumber {number} set according to the current page. - * sortAscending {boolean} set according to the current sort. - * sortColumn {number} set according to the given sort. - * @constructor - */ -var TableQueryWrapper = function(query, container, options) { - - this.table = new google.visualization.Table(container); - this.query = query; - this.sortQueryClause = ''; - this.pageQueryClause = ''; - this.container = container; - this.currentDataTable = null; - - var self = this; - var addListener = google.visualization.events.addListener; - addListener(this.table, 'page', function(e) {self.handlePage(e)}); - addListener(this.table, 'sort', function(e) {self.handleSort(e)}); - - options = options || {}; - options = TableQueryWrapper.clone(options); - - options['sort'] = 'event'; - options['page'] = 'event'; - options['showRowNumber'] = true; - var buttonConfig = 'pagingButtonsConfiguration'; - options[buttonConfig] = options[buttonConfig] || 'both'; - options['pageSize'] = (options['pageSize'] > 0) ? options['pageSize'] : 10; - this.pageSize = options['pageSize']; - this.tableOptions = options; - this.currentPageIndex = 0; - this.setPageQueryClause(0); -}; - - -/** - * Sends the query and upon its return draws the Table visualization in the - * container. If the query refresh interval is set then the visualization will - * be redrawn upon each refresh. - */ -TableQueryWrapper.prototype.sendAndDraw = function() { - this.query.abort(); - var queryClause = this.sortQueryClause + ' ' + this.pageQueryClause; - this.query.setQuery(queryClause); - this.table.setSelection([]); - var self = this; - this.query.send(function(response) {self.handleResponse(response)}); -}; - - -/** Handles the query response after a send returned by the data source. */ -TableQueryWrapper.prototype.handleResponse = function(response) { - this.currentDataTable = null; - if (response.isError()) { - google.visualization.errors.addError(this.container, response.getMessage(), - response.getDetailedMessage(), {'showInTooltip': false}); - } else { - // make data: - //this.currentDataTable= new google.visualization.DataTable(response); - //console.log(response); - this.currentDataTable = response.getDataTable(); - this.table.draw(this.currentDataTable, this.tableOptions); - } -}; - - -/** Handles a sort event with the given properties. Will page to page=0. */ -TableQueryWrapper.prototype.handleSort = function(properties) { - var columnIndex = properties['column']; - var isAscending = properties['ascending']; - this.tableOptions['sortColumn'] = columnIndex; - this.tableOptions['sortAscending'] = isAscending; - // dataTable exists since the user clicked the table. - var colID = this.currentDataTable.getColumnId(columnIndex); - this.sortQueryClause = 'order by `' + colID + (!isAscending ? '` desc' : '`'); - // Calls sendAndDraw internally. - this.handlePage({'page': 0}); -}; - - -/** Handles a page event with the given properties. */ -TableQueryWrapper.prototype.handlePage = function(properties) { - var localTableNewPage = properties['page']; // 1, -1 or 0 - var newPage = 0; - if (localTableNewPage != 0) { - newPage = this.currentPageIndex + localTableNewPage; - } - if (this.setPageQueryClause(newPage)) { - this.sendAndDraw(); - } -}; - - -/** - * Sets the pageQueryClause and table options for a new page request. - * In case the next page is requested - checks that another page exists - * based on the previous request. - * Returns true if a new page query clause was set, false otherwise. - */ -TableQueryWrapper.prototype.setPageQueryClause = function(pageIndex) { - var pageSize = this.pageSize; - - if (pageIndex < 0) { - return false; - } - var dataTable = this.currentDataTable; - if ((pageIndex == this.currentPageIndex + 1) && dataTable) { - if (dataTable.getNumberOfRows() <= pageSize) { - return false; - } - } - this.currentPageIndex = pageIndex; - var newStartRow = this.currentPageIndex * pageSize; - // Get the pageSize + 1 so that we can know when the last page is reached. - this.pageQueryClause = 'limit ' + (pageSize + 1) + ' offset ' + newStartRow; - // Note: row numbers are 1-based yet dataTable rows are 0-based. - this.tableOptions['firstRowNumber'] = newStartRow + 1; - return true; -}; - - -/** Performs a shallow clone of the given object. */ -TableQueryWrapper.clone = function(obj) { - var newObj = {}; - for (var key in obj) { - newObj[key] = obj[key]; - } - return newObj; -}; \ No newline at end of file From a58a560bbbd586493184ee15a00746b60e6f6086 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 09:07:13 +0100 Subject: [PATCH 031/193] Fixed the tables (again) for account and for index. --- app/controllers/AccountController.php | 8 ++++- app/models/Account.php | 48 +++++++++++++++++--------- app/views/accounts/index.blade.php | 2 +- app/views/index.blade.php | 2 +- app/views/list/accounts.blade.php | 37 ++++++++++++++++++++ app/views/list/journals-tiny.blade.php | 35 +++++++++++++++++++ 6 files changed, 112 insertions(+), 20 deletions(-) create mode 100644 app/views/list/accounts.blade.php create mode 100644 app/views/list/journals-tiny.blade.php diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 0347ca71a5..8544c5fc99 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -172,6 +172,9 @@ class AccountController extends BaseController */ public function index($what = 'default') { + /** @var \FireflyIII\Database\Account $acct */ + $acct = App::make('FireflyIII\Database\Account'); + switch ($what) { default: throw new FireflyException('Cannot handle account type "' . e($what) . '".'); @@ -179,18 +182,21 @@ class AccountController extends BaseController case 'asset': $subTitleIcon = 'fa-money'; $subTitle = 'Asset accounts'; + $accounts = $acct->getAssetAccounts(); break; case 'expense': $subTitleIcon = 'fa-shopping-cart'; $subTitle = 'Expense accounts'; + $accounts = $acct->getExpenseAccounts(); break; case 'revenue': $subTitleIcon = 'fa-download'; $subTitle = 'Revenue accounts'; + $accounts = $acct->getRevenueAccounts(); break; } - return View::make('accounts.index')->with('what', $what)->with(compact('subTitleIcon'))->with(compact('subTitle')); + return View::make('accounts.index',compact('what','subTitleIcon','subTitle','accounts')); } /** diff --git a/app/models/Account.php b/app/models/Account.php index ce207b98d9..b126388ad1 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -1,4 +1,5 @@ ['required', 'between:1,100', 'alphabasic'], 'user_id' => 'required|exists:users,id', + = ['name' => ['required', 'between:1,100', 'alphabasic'], 'user_id' => 'required|exists:users,id', 'account_type_id' => 'required|exists:account_types,id', 'active' => 'required|boolean' ]; @@ -64,21 +65,11 @@ class Account extends Ardent return floatval( $this->transactions()->leftJoin( - 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' - )->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount') + 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' + )->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount') ); } - /** - * Transactions. - * - * @return \Illuminate\Database\Eloquent\Relations\HasMany - */ - public function transactions() - { - return $this->hasMany('Transaction'); - } - /** * @param TransactionJournal $journal * @@ -88,13 +79,36 @@ class Account extends Ardent { return floatval( $this->transactions()->leftJoin( - 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' - )->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d'))->where( - 'transaction_journals.created_at', '<=', $journal->created_at->format('Y-m-d H:i:s') - )->where('transaction_journals.id', '!=', $journal->id)->sum('transactions.amount') + 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' + )->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d'))->where( + 'transaction_journals.created_at', '<=', $journal->created_at->format('Y-m-d H:i:s') + )->where('transaction_journals.id', '!=', $journal->id)->sum('transactions.amount') ); } + /** + * @return Carbon + */ + public function lastActionDate() + { + $transaction = $this->transactions()->orderBy('updated_at', 'DESC')->first(); + if(is_null($transaction)) { + return null; + } + + return $transaction->updated_at; + } + + /** + * Transactions. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function transactions() + { + return $this->hasMany('Transaction'); + } + /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ diff --git a/app/views/accounts/index.blade.php b/app/views/accounts/index.blade.php index 2f43b6fbe2..555105e477 100644 --- a/app/views/accounts/index.blade.php +++ b/app/views/accounts/index.blade.php @@ -22,7 +22,7 @@
-
+ @include('list.accounts')
diff --git a/app/views/index.blade.php b/app/views/index.blade.php index c5422f830b..9fc7e6766d 100644 --- a/app/views/index.blade.php +++ b/app/views/index.blade.php @@ -101,7 +101,7 @@
- @include('lists.old.journals-small-index',['transactions' => $data[0],'account' => $data[1]]) + @include('list.journals-tiny',['transactions' => $data[0],'account' => $data[1]])
@endforeach diff --git a/app/views/list/accounts.blade.php b/app/views/list/accounts.blade.php new file mode 100644 index 0000000000..54f4ac7ecd --- /dev/null +++ b/app/views/list/accounts.blade.php @@ -0,0 +1,37 @@ + + + + + + + + + @foreach($accounts as $account) + + + + + + + + + @endforeach +
 NameCurrent balanceActiveLast activity
+
+ + +
+
{{{$account->name}}}{{mf($account->balance())}} + @if($account->active) + + @else + + @endif + + lastActionDate(); ?> + @if($active) + {{{$active->format('j F Y @ H:i')}}} + @else + Never + @endif +
\ No newline at end of file diff --git a/app/views/list/journals-tiny.blade.php b/app/views/list/journals-tiny.blade.php new file mode 100644 index 0000000000..91c2b6f2d3 --- /dev/null +++ b/app/views/list/journals-tiny.blade.php @@ -0,0 +1,35 @@ + \ No newline at end of file From 0530c0402cf581dc4349f02f85ac720e514b8e04 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 09:34:53 +0100 Subject: [PATCH 032/193] First full transaction list (again) and removed some google table references. --- app/controllers/AccountController.php | 10 ++- app/lib/FireflyIII/Database/Account.php | 20 +++++ app/models/TransactionJournal.php | 2 +- app/views/accounts/show.blade.php | 2 +- app/views/list/journals-full.blade.php | 90 ++++++++++++++++++++ public/assets/javascript/firefly/accounts.js | 8 -- public/assets/javascript/firefly/budgets.js | 10 +-- 7 files changed, 122 insertions(+), 20 deletions(-) create mode 100644 app/views/list/journals-full.blade.php diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 8544c5fc99..8efebdd130 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -220,11 +220,17 @@ class AccountController extends BaseController break; } + // get a paginated view of all transactions for this account: + /** @var \FireflyIII\Database\Account $acct */ + $acct = App::make('FireflyIII\Database\Account'); + + $journals = $acct->getTransactionJournals($account, 50); + //$data = $this->_accounts->show($account, 40); - return View::make('accounts.show')->with('account', $account)->with( + return View::make('accounts.show',compact('account','subTitleIcon','journals'))->with('account', $account)->with( 'subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"' - )->with(compact('subTitleIcon')); + ); } /** diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index 74287f07c0..9c5c7cd894 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -483,5 +483,25 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } + public function getTransactionJournals(\Account $account, $limit = 50) + { + $start = \Session::get('start'); + $end = \Session::get('end'); + $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; + $set = $this->getUser()->transactionJournals()->withRelevantData()->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transactions.account_id', $account->id)->take($limit)->offset($offset)->before($end)->after($start)->orderBy('date', 'DESC') + ->get(['transaction_journals.*']); + $count = $this->getUser()->transactionJournals()->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->before($end)->after($start)->orderBy('date', 'DESC')->where('transactions.account_id', $account->id)->count(); + $items = []; + foreach ($set as $entry) { + $items[] = $entry; + } + + return \Paginator::make($items, $count, $limit); + + + } + } \ No newline at end of file diff --git a/app/models/TransactionJournal.php b/app/models/TransactionJournal.php index fdc0ae6dab..94eb8318e6 100644 --- a/app/models/TransactionJournal.php +++ b/app/models/TransactionJournal.php @@ -213,7 +213,7 @@ class TransactionJournal extends Ardent $q->orderBy('amount', 'ASC'); }, 'transactiontype', 'components' => function ($q) { $q->orderBy('class'); - }, 'transactions.account.accounttype', 'recurringTransaction'] + }, 'transactions.account.accounttype', 'recurringTransaction','budgets','categories'] ); } diff --git a/app/views/accounts/show.blade.php b/app/views/accounts/show.blade.php index 8d5842fd67..e96f37cd3b 100644 --- a/app/views/accounts/show.blade.php +++ b/app/views/accounts/show.blade.php @@ -48,7 +48,7 @@ Transactions
-
+ @include('list.journals-full')
diff --git a/app/views/list/journals-full.blade.php b/app/views/list/journals-full.blade.php new file mode 100644 index 0000000000..c07e757bda --- /dev/null +++ b/app/views/list/journals-full.blade.php @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + @foreach($journals as $journal) + + + + + + + + + + + + + + + @endforeach +
  DescriptionAmountDateFromTo
+
+ + +
+
+ @if($journal->transactiontype->type == 'Withdrawal') + + @endif + @if($journal->transactiontype->type == 'Deposit') + + @endif + @if($journal->transactiontype->type == 'Transfer') + + @endif + @if($journal->transactiontype->type == 'Opening balance') + + @endif + + {{{$journal->description}}} + + @if($journal->transactiontype->type == 'Withdrawal') + {{mf($journal->transactions[1]->amount,false)}} + @endif + @if($journal->transactiontype->type == 'Deposit') + {{mf($journal->transactions[1]->amount,false)}} + @endif + @if($journal->transactiontype->type == 'Transfer') + {{mf($journal->transactions[1]->amount,false)}} + @endif + + {{$journal->date->format('j F Y')}} + + @if($journal->transactions[0]->account->accounttype->description == 'Cash account') + (cash) + @else + {{{$journal->transactions[0]->account->name}}} + @endif + + @if($journal->transactions[1]->account->accounttype->description == 'Cash account') + (cash) + @else + {{{$journal->transactions[1]->account->name}}} + @endif + + budgets[0]) ? $journal->budgets[0] : null; ?> + @if($budget) + {{{$budget->name}}} + @endif + + categories[0]) ? $journal->categories[0] : null; ?> + @if($category) + {{{$category->name}}} + @endif + + @if($journal->recurringTransaction) + {{{$journal->recurringTransaction->name}}} + @endif +
+ +{{$journals->links()}} \ No newline at end of file diff --git a/public/assets/javascript/firefly/accounts.js b/public/assets/javascript/firefly/accounts.js index 2387946845..31882b5442 100644 --- a/public/assets/javascript/firefly/accounts.js +++ b/public/assets/javascript/firefly/accounts.js @@ -8,13 +8,5 @@ $(function () { googleSankeyChart('chart/sankey/' + accountID + '/out', 'account-out-sankey'); googleSankeyChart('chart/sankey/' + accountID + '/in', 'account-in-sankey'); } - if (typeof(googleTable) == 'function') { - if (typeof accountID != 'undefined') { - googleTable('table/account/' + accountID + '/transactions', 'account-transactions'); - } - if (typeof what != 'undefined') { - googleTable('table/accounts/' + what, 'account-list'); - } - } }); \ No newline at end of file diff --git a/public/assets/javascript/firefly/budgets.js b/public/assets/javascript/firefly/budgets.js index d3aa69725c..027a892372 100644 --- a/public/assets/javascript/firefly/budgets.js +++ b/public/assets/javascript/firefly/budgets.js @@ -7,14 +7,8 @@ $(function () { $('.updateIncome').on('click', updateIncome); - if (typeof(googleTable) == 'function') { - if (typeof componentID != 'undefined' && typeof repetitionID == 'undefined') { - googleTable('table/component/' + componentID + '/0/transactions', 'transactions'); - googleColumnChart('chart/component/' + componentID + '/spending/' + year, 'componentOverview'); - - } else if (typeof componentID != 'undefined' && typeof repetitionID != 'undefined') { - googleTable('table/component/' + componentID + '/' + repetitionID + '/transactions', 'transactions'); - } + if (typeof componentID != 'undefined' && typeof repetitionID == 'undefined') { + googleColumnChart('chart/component/' + componentID + '/spending/' + year, 'componentOverview'); } }); From ac2ab654714050c5aee84aab201aeb0f1b3821c0 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 10:17:12 +0100 Subject: [PATCH 033/193] Got up to categories with the new tables. --- app/config/homestead/mail.php | 6 ++-- app/controllers/AccountController.php | 2 +- app/controllers/BudgetController.php | 13 ++++++++- app/controllers/CategoryController.php | 5 +++- app/lib/FireflyIII/Database/Budget.php | 38 +++++++++++++++++++++++--- app/models/Category.php | 12 ++++++++ app/views/budgets/show.blade.php | 2 +- app/views/categories/index.blade.php | 2 +- app/views/list/accounts.blade.php | 2 +- app/views/list/categories.blade.php | 28 +++++++++++++++++++ app/views/list/journals-full.blade.php | 25 +++++++++++------ 11 files changed, 114 insertions(+), 21 deletions(-) create mode 100644 app/views/list/categories.blade.php diff --git a/app/config/homestead/mail.php b/app/config/homestead/mail.php index 79a8bf2536..35d92d7f92 100644 --- a/app/config/homestead/mail.php +++ b/app/config/homestead/mail.php @@ -4,10 +4,10 @@ return [ 'driver' => 'smtp', 'host' => 'smtp.gmail.com', 'port' => 587, - 'from' => ['address' => '@gmail.com', 'name' => 'Firefly III'], + 'from' => ['address' => 'thegrumpydictator@gmail.com', 'name' => 'Firefly III'], 'encryption' => 'tls', - 'username' => '@gmail.com', - 'password' => '', + 'username' => 'thegrumpydictator@gmail.com', + 'password' => 'eyp-ort-ab-ig-york-ig-e-kne', 'sendmail' => '/usr/sbin/sendmail -bs', 'pretend' => false, ]; diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 8efebdd130..8844503c13 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -224,7 +224,7 @@ class AccountController extends BaseController /** @var \FireflyIII\Database\Account $acct */ $acct = App::make('FireflyIII\Database\Account'); - $journals = $acct->getTransactionJournals($account, 50); + $journals = $acct->getTransactionJournals($account, 10); //$data = $this->_accounts->show($account, 40); diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php index 977cfcdb0d..0e7de74c14 100644 --- a/app/controllers/BudgetController.php +++ b/app/controllers/BudgetController.php @@ -191,17 +191,28 @@ class BudgetController extends BaseController if (!is_null($repetition) && $repetition->limit->budget->id != $budget->id) { App::abort(500); } + /** @var \FireflyIII\Database\Budget $repos */ + $repos = App::make('FireflyIII\Database\Budget'); if (is_null($repetition)) { // get all other repetitions: $limits = $budget->limits()->orderBy('startdate', 'DESC')->get(); + // get all transaction journals for this budget. + $journals = $repos->getTransactionJournals($budget, 50); + $subTitle = $budget->name; } else { // get nothing? i dunno $limits = [$repetition->limit]; + // get all transaction journals for this budget and limit repetition. + $journals = []; + $subTitle = $budget->name.' in ' . $repetition->startdate->format('F Y'); + $journals = $repos->getTransactionJournalsInRepetition($budget, $repetition, 50); } + $hideBudget = true; - return View::make('budgets.show', compact('limits', 'budget', 'repetition')); + + return View::make('budgets.show', compact('limits', 'budget', 'repetition', 'journals','subTitle','hideBudget')); } /** diff --git a/app/controllers/CategoryController.php b/app/controllers/CategoryController.php index 220f476dcb..19ca21766f 100644 --- a/app/controllers/CategoryController.php +++ b/app/controllers/CategoryController.php @@ -65,7 +65,10 @@ class CategoryController extends BaseController */ public function index() { - return View::make('categories.index'); + /** @var \FireflyIII\Database\Category $repos */ + $repos = App::make('FireflyIII\Database\Category'); + $categories = $repos->get(); + return View::make('categories.index',compact('categories')); } /** diff --git a/app/lib/FireflyIII/Database/Budget.php b/app/lib/FireflyIII/Database/Budget.php index 03aa341f7b..98c1ab8b14 100644 --- a/app/lib/FireflyIII/Database/Budget.php +++ b/app/lib/FireflyIII/Database/Budget.php @@ -182,6 +182,36 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface throw new NotImplementedException; } + public function getTransactionJournals(\Budget $budget, $limit = 50) + { + $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; + $set = $budget->transactionJournals()->withRelevantData()->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); + $count = $budget->transactionJournals()->count(); + $items = []; + foreach ($set as $entry) { + $items[] = $entry; + } + + return \Paginator::make($items, $count, $limit); + + } + + public function getTransactionJournalsInRepetition(\Budget $budget, \LimitRepetition $repetition, $limit = 50) + { + $start = $repetition->startdate; + $end = $repetition->enddate; + + $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; + $set = $budget->transactionJournals()->withRelevantData()->before($end)->after($start)->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); + $count = $budget->transactionJournals()->before($end)->after($start)->count(); + $items = []; + foreach ($set as $entry) { + $items[] = $entry; + } + + return \Paginator::make($items, $count, $limit); + } + /** * @param \Budget $budget * @param Carbon $date @@ -210,10 +240,10 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface return \Auth::user()->transactionjournals()->whereNotIn( 'transaction_journals.id', function ($query) use ($start, $end) { $query->select('transaction_journals.id')->from('transaction_journals')->leftJoin( - 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' - )->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')->where( - 'transaction_journals.date', '>=', $start->format('Y-m-d') - )->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->where('components.class', 'Budget'); + 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' + )->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')->where( + 'transaction_journals.date', '>=', $start->format('Y-m-d') + )->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->where('components.class', 'Budget'); } )->before($end)->after($start)->lessThan(0)->transactionTypes(['Withdrawal'])->get(); } diff --git a/app/models/Category.php b/app/models/Category.php index c39e0642f6..e02cd71dac 100644 --- a/app/models/Category.php +++ b/app/models/Category.php @@ -31,4 +31,16 @@ class Category extends Component { return $this->belongsToMany('TransactionJournal', 'component_transaction_journal', 'component_id'); } + /** + * @return Carbon + */ + public function lastActionDate() + { + $transaction = $this->transactionjournals()->orderBy('updated_at', 'DESC')->first(); + if(is_null($transaction)) { + return null; + } + + return $transaction->date; + } } \ No newline at end of file diff --git a/app/views/budgets/show.blade.php b/app/views/budgets/show.blade.php index dbf08c7f45..4af1bea550 100644 --- a/app/views/budgets/show.blade.php +++ b/app/views/budgets/show.blade.php @@ -17,7 +17,7 @@ Transactions
-
+ @include('list.journals-full')
diff --git a/app/views/categories/index.blade.php b/app/views/categories/index.blade.php index 86cb093906..7731f88fe6 100644 --- a/app/views/categories/index.blade.php +++ b/app/views/categories/index.blade.php @@ -22,7 +22,7 @@
-
+ @include('list.categories')
diff --git a/app/views/list/accounts.blade.php b/app/views/list/accounts.blade.php index 54f4ac7ecd..263a88aa32 100644 --- a/app/views/list/accounts.blade.php +++ b/app/views/list/accounts.blade.php @@ -26,7 +26,7 @@ lastActionDate(); ?> @if($active) - {{{$active->format('j F Y @ H:i')}}} + {{{$active->format('j F Y')}}} @else Never @endif diff --git a/app/views/list/categories.blade.php b/app/views/list/categories.blade.php new file mode 100644 index 0000000000..ea64100e01 --- /dev/null +++ b/app/views/list/categories.blade.php @@ -0,0 +1,28 @@ + + + + + + + @foreach($categories as $category) + + + + + + @endforeach +
 NameLast activity
+
+ + +
+
+ {{{$category->name}}} + + lastActionDate(); ?> + @if($active) + {{{$active->format('j F Y')}}} + @else + Never + @endif +
\ No newline at end of file diff --git a/app/views/list/journals-full.blade.php b/app/views/list/journals-full.blade.php index c07e757bda..768c7b1178 100644 --- a/app/views/list/journals-full.blade.php +++ b/app/views/list/journals-full.blade.php @@ -1,3 +1,6 @@ +@if(is_object($journals)) +{{$journals->links()}} +@endif @@ -7,7 +10,9 @@ - + @if(!isset($hideBudget) || (isset($hideBudget) && $hideBudget=== false)) + + @endif @@ -64,12 +69,14 @@ {{{$journal->transactions[1]->account->name}}} @endif - + @if(!isset($hideBudget) || (isset($hideBudget) && $hideBudget=== false)) + + @endif
 Date From To
- budgets[0]) ? $journal->budgets[0] : null; ?> - @if($budget) - {{{$budget->name}}} - @endif - + budgets[0]) ? $journal->budgets[0] : null; ?> + @if($budget) + {{{$budget->name}}} + @endif + categories[0]) ? $journal->categories[0] : null; ?> @if($category) @@ -87,4 +94,6 @@ @endforeach
-{{$journals->links()}} \ No newline at end of file +@if(is_object($journals)) +{{$journals->links()}} +@endif \ No newline at end of file From f9750a64f84ed39adf039256324a492621349446 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 10:28:18 +0100 Subject: [PATCH 034/193] Fixed transactions lists. --- app/controllers/TransactionController.php | 13 +++- .../Database/TransactionJournal.php | 75 ++++++++----------- app/views/list/categories.blade.php | 2 +- app/views/transactions/index.blade.php | 14 +--- 4 files changed, 41 insertions(+), 63 deletions(-) diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index aa0aa0a5b5..5e8b103649 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -224,25 +224,31 @@ class TransactionController extends BaseController public function index($what) { + /** @var \FireflyIII\Database\TransactionJournal $repository */ + $repository = App::make('FireflyIII\Database\TransactionJournal'); + switch ($what) { case 'expenses': case 'withdrawal': $subTitleIcon = 'fa-long-arrow-left'; $subTitle = 'Expenses'; + $journals = $repository->getWithdrawalsPaginated(50); break; case 'revenue': case 'deposit': $subTitleIcon = 'fa-long-arrow-right'; $subTitle = 'Revenue, income and deposits'; + $journals = $repository->getDepositsPaginated(50); break; case 'transfer': case 'transfers': $subTitleIcon = 'fa-arrows-h'; $subTitle = 'Transfers'; + $journals = $repository->getTransfersPaginated(50); break; } - return View::make('transactions.index', compact('subTitle', 'subTitleIcon'))->with('what', $what); + return View::make('transactions.index', compact('subTitle', 'subTitleIcon','journals'))->with('what', $what); } @@ -251,9 +257,8 @@ class TransactionController extends BaseController * * @return $this */ - public function show( - TransactionJournal $journal - ) { + public function show(TransactionJournal $journal) + { return View::make('transactions.show')->with('journal', $journal)->with( 'subTitle', $journal->transactionType->type . ' "' . $journal->description . '"' ); diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 07e13e7144..7837e62b4b 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -505,24 +505,6 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData return $sum; } - /** - * Some objects. - * - * @return Collection - */ - public function getDeposits($limit = null, $offset = null) - { - $query = $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Deposit']); - if(!is_null($limit)) { - $query->take($limit); - } - if(!is_null($offset) && intval($offset) > 0) { - $query->skip($offset); - } - - return $query->get(['transaction_journals.*']); - } - /** * @param \Account $account * @param int $count @@ -546,39 +528,42 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData return $query; } - /** - * Some objects. - * - * @return Collection - */ - public function getTransfers($limit = null, $offset = null) - { - $query = $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Transfer']); + public function getWithdrawalsPaginated($limit = 50) { + $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; - if(!is_null($limit)) { - $query->take($limit); + $set = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->withRelevantData()->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); + $count = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->count(); + $items = []; + foreach ($set as $entry) { + $items[] = $entry; } - if(!is_null($offset) && intval($offset) > 0) { - $query->skip($offset); - } - return $query->get(['transaction_journals.*']); + + return \Paginator::make($items, $count, $limit); } - /** - * Some objects. - * - * @return Collection - */ - public function getWithdrawals($limit = null, $offset = null) - { - $query = $this->getUser()->transactionjournals()->withRelevantData()->transactionTypes(['Withdrawal']); + public function getDepositsPaginated($limit = 50) { + $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; - if(!is_null($limit) && intval($limit) > 0) { - $query->take($limit); + $set = $this->getUser()->transactionJournals()->transactionTypes(['Deposit'])->withRelevantData()->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); + $count = $this->getUser()->transactionJournals()->transactionTypes(['Deposit'])->count(); + $items = []; + foreach ($set as $entry) { + $items[] = $entry; } - if(!is_null($offset) && intval($offset) > 0) { - $query->skip($offset); + + return \Paginator::make($items, $count, $limit); + } + + public function getTransfersPaginated($limit = 50) { + $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; + + $set = $this->getUser()->transactionJournals()->transactionTypes(['Transfer'])->withRelevantData()->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); + $count = $this->getUser()->transactionJournals()->transactionTypes(['Transfer'])->count(); + $items = []; + foreach ($set as $entry) { + $items[] = $entry; } - return $query->get(['transaction_journals.*']); + + return \Paginator::make($items, $count, $limit); } } \ No newline at end of file diff --git a/app/views/list/categories.blade.php b/app/views/list/categories.blade.php index ea64100e01..6cfdb19eb2 100644 --- a/app/views/list/categories.blade.php +++ b/app/views/list/categories.blade.php @@ -13,7 +13,7 @@ - {{{$category->name}}} + {{{$category->name}}} lastActionDate(); ?> diff --git a/app/views/transactions/index.blade.php b/app/views/transactions/index.blade.php index 3410db02fe..46f76530df 100644 --- a/app/views/transactions/index.blade.php +++ b/app/views/transactions/index.blade.php @@ -7,7 +7,7 @@ {{{$subTitle}}}
-
+ @include('list.journals-full')
@@ -15,15 +15,3 @@ @stop -@section('scripts') - - - -{{HTML::script('assets/javascript/firefly/gcharts.options.js')}} -{{HTML::script('assets/javascript/firefly/gcharts.js')}} - - -{{HTML::script('assets/javascript/firefly/transactions.js')}} -@stop \ No newline at end of file From 11280e473d09d30047b21a19059578718cb95851 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 10:37:19 +0100 Subject: [PATCH 035/193] Catch broken journals. --- app/views/list/journals-full.blade.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/views/list/journals-full.blade.php b/app/views/list/journals-full.blade.php index 768c7b1178..b4cec4ae25 100644 --- a/app/views/list/journals-full.blade.php +++ b/app/views/list/journals-full.blade.php @@ -17,6 +17,18 @@ @foreach($journals as $journal) + @if(!isset($journal->transactions[1]) || !isset($journal->transactions[0])) + + +
+ +
+ +   + {{{$journal->description}}} + Invalid journal: Found {{$journal->transactions()->count()}} transaction(s) + + @else
@@ -91,6 +103,8 @@ + @endif + @endforeach From 78ab1e200a2ac8e6bf42ddf92a9e419a19188211 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 10:39:34 +0100 Subject: [PATCH 036/193] Remove transactions now works. --- app/lib/FireflyIII/Database/TransactionJournal.php | 4 ++-- app/views/transactions/delete.blade.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 7837e62b4b..55d4c0ac9e 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -37,8 +37,8 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData */ public function destroy(Ardent $model) { - // TODO: Implement destroy() method. - throw new NotImplementedException; + $model->delete(); + return true; } /** diff --git a/app/views/transactions/delete.blade.php b/app/views/transactions/delete.blade.php index 5bda69d486..0b74af5b55 100644 --- a/app/views/transactions/delete.blade.php +++ b/app/views/transactions/delete.blade.php @@ -23,13 +23,13 @@
@if($journal->transactiontype->type == 'Withdrawal') - Cancel + Cancel @endif @if($journal->transactiontype->type == 'Deposit') - Cancel + Cancel @endif @if($journal->transactiontype->type == 'Transfer') - Cancel + Cancel @endif
From 4bd38f97a20780b0b3a57ea8da760b5d86cc1d1f Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 10:41:35 +0100 Subject: [PATCH 037/193] Whoops. But not to worry, changed it already. --- app/config/homestead/mail.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/config/homestead/mail.php b/app/config/homestead/mail.php index 35d92d7f92..79a8bf2536 100644 --- a/app/config/homestead/mail.php +++ b/app/config/homestead/mail.php @@ -4,10 +4,10 @@ return [ 'driver' => 'smtp', 'host' => 'smtp.gmail.com', 'port' => 587, - 'from' => ['address' => 'thegrumpydictator@gmail.com', 'name' => 'Firefly III'], + 'from' => ['address' => '@gmail.com', 'name' => 'Firefly III'], 'encryption' => 'tls', - 'username' => 'thegrumpydictator@gmail.com', - 'password' => 'eyp-ort-ab-ig-york-ig-e-kne', + 'username' => '@gmail.com', + 'password' => '', 'sendmail' => '/usr/sbin/sendmail -bs', 'pretend' => false, ]; From 9adbbd872c61c067072c7aca43e95d8f82d4d95e Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 11:43:08 +0100 Subject: [PATCH 038/193] New chart for budgets. --- app/controllers/GoogleChartController.php | 27 ++++++++++++++++++++- app/routes.php | 12 +-------- public/assets/javascript/firefly/budgets.js | 3 +++ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index 61c520089b..15651be465 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -445,6 +445,32 @@ class GoogleChartController extends BaseController } + public function budgetLimitSpending(\Budget $budget, \LimitRepetition $repetition) { + $start = clone $repetition->startdate; + $end = $repetition->enddate; + + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('Day', 'date'); + $chart->addColumn('Left', 'number'); + + + $amount = $repetition->amount; + + while($start <= $end) { + /* + * Sum of expenses on this day: + */ + $sum = floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($start)->sum('amount')); + $amount += $sum; + $chart->addRow(clone $start, $amount); + $start->addDay(); + } + $chart->generate(); + return Response::json($chart->getData()); + + } + /** * @return \Illuminate\Http\JsonResponse * @throws \FireflyIII\Exception\FireflyException @@ -525,7 +551,6 @@ class GoogleChartController extends BaseController $chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']); $chart->generate(); - return Response::json($chart->getData()); } diff --git a/app/routes.php b/app/routes.php index 7441f93923..0f39b634aa 100644 --- a/app/routes.php +++ b/app/routes.php @@ -155,21 +155,11 @@ Route::group( Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']); Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']); Route::get('/chart/reports/budgets/{year}', ['uses' => 'GoogleChartController@budgetsReportChart']); + Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'GoogleChartController@budgetLimitSpending']); // google chart for components (categories + budgets combined) Route::get('/chart/component/{component}/spending/{year}', ['uses' => 'GoogleChartController@componentsAndSpending']); - // google table controller - #Route::get('/table/account/{account}/transactions', ['uses' => 'GoogleTableController@transactionsByAccount']); - #Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']); - #Route::get('/table/categories', ['uses' => 'GoogleTableController@categoryList']); - #Route::get('/table/recurring', ['uses' => 'GoogleTableController@recurringList']); - #Route::get('/table/recurring/{recurring}/transactions', ['uses' => 'GoogleTableController@transactionsByRecurring']); - #Route::get('/table/transactions/{what}', ['uses' => 'GoogleTableController@transactionsList'])->where(['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers']); - // google table for components (categories + budgets) - #Route::get('/table/component/{component}/{limitrepetition}/transactions', ['uses' => 'GoogleTableController@transactionsByComponent']); - - // home controller Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']); Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); # even though nothing is cached. diff --git a/public/assets/javascript/firefly/budgets.js b/public/assets/javascript/firefly/budgets.js index 027a892372..f31d78b637 100644 --- a/public/assets/javascript/firefly/budgets.js +++ b/public/assets/javascript/firefly/budgets.js @@ -10,6 +10,9 @@ $(function () { if (typeof componentID != 'undefined' && typeof repetitionID == 'undefined') { googleColumnChart('chart/component/' + componentID + '/spending/' + year, 'componentOverview'); } + if (typeof componentID != 'undefined' && typeof repetitionID != 'undefined') { + googleLineChart('chart/budget/' + componentID + '/' + repetitionID, 'componentOverview'); + } }); From eb8f8fa9351dd27963462f2cd5c90663125b650e Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 11:56:45 +0100 Subject: [PATCH 039/193] Expanded on categories. --- app/controllers/CategoryController.php | 9 ++++++++- app/lib/FireflyIII/Database/Category.php | 14 ++++++++++++++ app/views/categories/show.blade.php | 2 +- app/views/list/journals-full.blade.php | 6 +++++- public/assets/javascript/firefly/categories.js | 13 ++----------- 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/app/controllers/CategoryController.php b/app/controllers/CategoryController.php index 19ca21766f..cb9aa2c649 100644 --- a/app/controllers/CategoryController.php +++ b/app/controllers/CategoryController.php @@ -78,7 +78,14 @@ class CategoryController extends BaseController */ public function show(Category $category) { - return View::make('categories.show', compact('category')); + $hideCategory = true; + + /** @var \FireflyIII\Database\Category $repos */ + $repos = App::make('FireflyIII\Database\Category'); + + $journals = $repos->getTransactionJournals($category, 50); + + return View::make('categories.show', compact('category','journals','hideCategory')); } /** diff --git a/app/lib/FireflyIII/Database/Category.php b/app/lib/FireflyIII/Database/Category.php index 0e4085e439..faa11b7f65 100644 --- a/app/lib/FireflyIII/Database/Category.php +++ b/app/lib/FireflyIII/Database/Category.php @@ -170,6 +170,20 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface throw new NotImplementedException; } + public function getTransactionJournals(\Category $category, $limit = 50) + { + $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; + $set = $category->transactionJournals()->withRelevantData()->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); + $count = $category->transactionJournals()->count(); + $items = []; + foreach ($set as $entry) { + $items[] = $entry; + } + + return \Paginator::make($items, $count, $limit); + + } + /** * @param \Category $budget * @param Carbon $date diff --git a/app/views/categories/show.blade.php b/app/views/categories/show.blade.php index 594680d8ca..5cebffd6ed 100644 --- a/app/views/categories/show.blade.php +++ b/app/views/categories/show.blade.php @@ -17,7 +17,7 @@ Transactions
-
+ @include('list.journals-full')
diff --git a/app/views/list/journals-full.blade.php b/app/views/list/journals-full.blade.php index b4cec4ae25..d118ec5fa1 100644 --- a/app/views/list/journals-full.blade.php +++ b/app/views/list/journals-full.blade.php @@ -13,7 +13,9 @@ @if(!isset($hideBudget) || (isset($hideBudget) && $hideBudget=== false)) @endif - + @if(!isset($hideCategory) || (isset($hideCategory) && $hideCategory=== false)) + + @endif @foreach($journals as $journal) @@ -89,12 +91,14 @@ @endif @endif + @if(!isset($hideCategory) || (isset($hideCategory) && $hideCategory=== false)) categories[0]) ? $journal->categories[0] : null; ?> @if($category) {{{$category->name}}} @endif + @endif @if($journal->recurringTransaction) {{{$journal->recurringTransaction->name}}} diff --git a/public/assets/javascript/firefly/categories.js b/public/assets/javascript/firefly/categories.js index 502dfd7366..4827e81307 100644 --- a/public/assets/javascript/firefly/categories.js +++ b/public/assets/javascript/firefly/categories.js @@ -1,18 +1,9 @@ $(function () { - if (typeof googleTable == 'function') { - googleTable('table/categories', 'category-list'); - if (typeof(componentID) != 'undefined') { - googleTable('table/component/' + componentID + '/0/transactions','transactions'); - - if (typeof googleColumnChart == 'function') { - googleColumnChart('chart/component/' + componentID + '/spending/' + year, 'componentOverview'); - } - - } + if (typeof componentID != 'undefined' && typeof repetitionID == 'undefined') { + googleColumnChart('chart/component/' + componentID + '/spending/' + year, 'componentOverview'); } - }); \ No newline at end of file From 54685c1f5ff851bcc07e50b83488dde7416db02f Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 12:54:49 +0100 Subject: [PATCH 040/193] Some new lists for recurring transactions. --- app/controllers/RecurringController.php | 10 +++- app/views/list/journals-full.blade.php | 16 ++++--- app/views/list/recurring.blade.php | 63 +++++++++++++++++++++++++ app/views/recurring/index.blade.php | 11 +---- app/views/recurring/show.blade.php | 5 +- 5 files changed, 84 insertions(+), 21 deletions(-) create mode 100644 app/views/list/recurring.blade.php diff --git a/app/controllers/RecurringController.php b/app/controllers/RecurringController.php index 809bf7e7ad..36dd8c4d24 100644 --- a/app/controllers/RecurringController.php +++ b/app/controllers/RecurringController.php @@ -80,7 +80,11 @@ class RecurringController extends BaseController */ public function index() { - return View::make('recurring.index'); + /** @var \FireflyIII\Database\Recurring $repos */ + $repos = App::make('FireflyIII\Database\Recurring'); + + $recurring = $repos->get(); + return View::make('recurring.index',compact('recurring')); } /** @@ -110,7 +114,9 @@ class RecurringController extends BaseController */ public function show(RecurringTransaction $recurringTransaction) { - return View::make('recurring.show')->with('recurring', $recurringTransaction)->with('subTitle', $recurringTransaction->name); + $journals = $recurringTransaction->transactionjournals()->withRelevantData()->orderBy('date','DESC')->get(); + $hideRecurring = true; + return View::make('recurring.show',compact('journals','hideRecurring'))->with('recurring', $recurringTransaction)->with('subTitle', $recurringTransaction->name); } public function store() diff --git a/app/views/list/journals-full.blade.php b/app/views/list/journals-full.blade.php index d118ec5fa1..6405564a5b 100644 --- a/app/views/list/journals-full.blade.php +++ b/app/views/list/journals-full.blade.php @@ -1,4 +1,4 @@ -@if(is_object($journals)) +@if(is_object($journals) && method_exists($journals, 'links')) {{$journals->links()}} @endif @@ -16,7 +16,9 @@ @if(!isset($hideCategory) || (isset($hideCategory) && $hideCategory=== false)) @endif - + @if(!isset($hideRecurring) || (isset($hideRecurring) && $hideRecurring=== false)) + + @endif @foreach($journals as $journal) @if(!isset($journal->transactions[1]) || !isset($journal->transactions[0])) @@ -99,11 +101,13 @@ @endif @endif + @if(!isset($hideRecurring) || (isset($hideRecurring) && $hideRecurring=== false)) + @endif @@ -112,6 +116,6 @@ @endforeach
- @if($journal->recurringTransaction) - {{{$journal->recurringTransaction->name}}} - @endif + @if($journal->recurringTransaction) + {{{$journal->recurringTransaction->name}}} + @endif
-@if(is_object($journals)) +@if(is_object($journals) && method_exists($journals, 'links')) {{$journals->links()}} @endif \ No newline at end of file diff --git a/app/views/list/recurring.blade.php b/app/views/list/recurring.blade.php new file mode 100644 index 0000000000..7edf6d4e46 --- /dev/null +++ b/app/views/list/recurring.blade.php @@ -0,0 +1,63 @@ + + + + + + + + + + + + + @foreach($recurring as $entry) + + + + + + + + + + + + + @endforeach +
 NameMatches onMatching amountLast seen matchNext expected matchIs activeWill be automatchedRepeats every
+
+ + +
+
+ {{{$entry->name}}} + + @foreach(explode(' ',$entry->match) as $match) + {{{$match}}} + @endforeach + + {{mf($entry->amount_min)}} + — + {{mf($entry->amount_max)}} + + + + + + @if($entry->active) + + @else + + @endif + + @if($entry->automatch) + + @else + + @endif + + {{{$entry->repeat_freq}}} + @if($entry->skip > 0) + skips over {{$entry->skip}} + @endif +
\ No newline at end of file diff --git a/app/views/recurring/index.blade.php b/app/views/recurring/index.blade.php index ddfbf6f309..5ea3406b60 100644 --- a/app/views/recurring/index.blade.php +++ b/app/views/recurring/index.blade.php @@ -7,7 +7,7 @@ {{{$title}}}
-
+ @include('list.recurring')
@@ -15,13 +15,4 @@ @stop @section('scripts') - - -{{HTML::script('assets/javascript/firefly/gcharts.options.js')}} -{{HTML::script('assets/javascript/firefly/gcharts.js')}} - - - - -{{HTML::script('assets/javascript/firefly/recurring.js')}} @stop \ No newline at end of file diff --git a/app/views/recurring/show.blade.php b/app/views/recurring/show.blade.php index 3d5a738cae..910aa69dea 100644 --- a/app/views/recurring/show.blade.php +++ b/app/views/recurring/show.blade.php @@ -38,7 +38,7 @@ Matching on - @foreach(explode(',',$recurring->match) as $word) + @foreach(explode(' ',$recurring->match) as $word) {{{$word}}} @endforeach between {{mf($recurring->amount_min)}} and {{mf($recurring->amount_max)}}. @@ -74,8 +74,7 @@ Connected transaction journals
-
- + @include('list.journals-full')
From 9e720c3a3867f9adae9165e5041e2e2c3557d318 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 14:33:41 +0100 Subject: [PATCH 041/193] Some view fixes. --- app/controllers/RecurringController.php | 2 ++ app/lib/FireflyIII/Database/Recurring.php | 5 ++--- app/views/transactions/show.blade.php | 21 ++++++++++++++------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/app/controllers/RecurringController.php b/app/controllers/RecurringController.php index 36dd8c4d24..8a6f66ba75 100644 --- a/app/controllers/RecurringController.php +++ b/app/controllers/RecurringController.php @@ -110,7 +110,9 @@ class RecurringController extends BaseController } /** + * @param RecurringTransaction $recurringTransaction * + * @return mixed */ public function show(RecurringTransaction $recurringTransaction) { diff --git a/app/lib/FireflyIII/Database/Recurring.php b/app/lib/FireflyIII/Database/Recurring.php index 2590052736..8a400ac89c 100644 --- a/app/lib/FireflyIII/Database/Recurring.php +++ b/app/lib/FireflyIII/Database/Recurring.php @@ -339,9 +339,8 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface /** @var \FireflyIII\Database\TransactionJournal $journalRepository */ $journalRepository = \App::make('FireflyIII\Database\TransactionJournal'); - $set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $recurring->amount_min)->where( - 'amount', '<=', $recurring->amount_max - )->get(['transaction_journal_id']); + $set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $recurring->amount_min)->where('amount', '<=', $recurring->amount_max) + ->get(['transaction_journal_id']); $ids = []; /** @var \Transaction $entry */ diff --git a/app/views/transactions/show.blade.php b/app/views/transactions/show.blade.php index a4e1115466..d1b904bb60 100644 --- a/app/views/transactions/show.blade.php +++ b/app/views/transactions/show.blade.php @@ -3,7 +3,7 @@

Metadata

- +
@@ -26,12 +26,19 @@ @endif - @foreach($journal->components as $component) - - - - + @foreach($journal->budgets()->get() as $budget) + + + + @endforeach + @foreach($journal->categories()->get() as $category) + + + + + @endforeach +
Date {{{$journal->date->format('jS F Y')}}}
{{$component->class}}{{{$component->name}}}
{{$budget->class}}{{{$budget->name}}}
{{$category->class}}{{{$category->name}}}
@@ -39,7 +46,7 @@

Transactions

@foreach($journal->transactions as $t)

{{{$t->account->name}}}
{{{$t->account->accounttype->description}}}

- +
From de20563275c5788417da0fbab1f863563256185c Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 19:33:40 +0100 Subject: [PATCH 042/193] Removed all event triggers. --- .../Trigger/Budgets/EloquentBudgetTrigger.php | 6 ++--- .../Journals/EloquentJournalTrigger.php | 4 +-- .../Trigger/Limits/EloquentLimitTrigger.php | 10 +++---- .../Piggybanks/EloquentPiggybankTrigger.php | 26 +++++-------------- .../Recurring/EloquentRecurringTrigger.php | 2 +- bootstrap/start.php | 10 +++---- 6 files changed, 23 insertions(+), 35 deletions(-) diff --git a/app/lib/Firefly/Trigger/Budgets/EloquentBudgetTrigger.php b/app/lib/Firefly/Trigger/Budgets/EloquentBudgetTrigger.php index 54a389c2df..696e039b61 100644 --- a/app/lib/Firefly/Trigger/Budgets/EloquentBudgetTrigger.php +++ b/app/lib/Firefly/Trigger/Budgets/EloquentBudgetTrigger.php @@ -46,9 +46,9 @@ class EloquentBudgetTrigger */ public function subscribe(Dispatcher $events) { - $events->listen('budgets.destroy', 'Firefly\Trigger\Budgets\EloquentBudgetTrigger@destroy'); - $events->listen('budgets.store', 'Firefly\Trigger\Budgets\EloquentBudgetTrigger@store'); - $events->listen('budgets.update', 'Firefly\Trigger\Budgets\EloquentBudgetTrigger@update'); +// $events->listen('budgets.destroy', 'Firefly\Trigger\Budgets\EloquentBudgetTrigger@destroy'); +// $events->listen('budgets.store', 'Firefly\Trigger\Budgets\EloquentBudgetTrigger@store'); +// $events->listen('budgets.update', 'Firefly\Trigger\Budgets\EloquentBudgetTrigger@update'); } diff --git a/app/lib/Firefly/Trigger/Journals/EloquentJournalTrigger.php b/app/lib/Firefly/Trigger/Journals/EloquentJournalTrigger.php index b2cdbf9bde..cbb5196fae 100644 --- a/app/lib/Firefly/Trigger/Journals/EloquentJournalTrigger.php +++ b/app/lib/Firefly/Trigger/Journals/EloquentJournalTrigger.php @@ -45,8 +45,8 @@ class EloquentJournalTrigger */ public function subscribe(Dispatcher $events) { - $events->listen('journals.store', 'Firefly\Trigger\Journals\EloquentJournalTrigger@store'); - $events->listen('journals.update', 'Firefly\Trigger\Journals\EloquentJournalTrigger@update'); +// $events->listen('journals.store', 'Firefly\Trigger\Journals\EloquentJournalTrigger@store'); +// $events->listen('journals.update', 'Firefly\Trigger\Journals\EloquentJournalTrigger@update'); } diff --git a/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php b/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php index 67f1e4dd03..2633684c14 100644 --- a/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php +++ b/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php @@ -107,11 +107,11 @@ class EloquentLimitTrigger public function subscribe(Dispatcher $events) { //$events->listen('budgets.change', 'Firefly\Trigger\Limits\EloquentLimitTrigger@updateLimitRepetitions'); - $events->listen('limits.destroy', 'Firefly\Trigger\Limits\EloquentLimitTrigger@destroy'); - $events->listen('limits.store', 'Firefly\Trigger\Limits\EloquentLimitTrigger@store'); - $events->listen('limits.update', 'Firefly\Trigger\Limits\EloquentLimitTrigger@update'); - $events->listen('limits.check', 'Firefly\Trigger\Limits\EloquentLimitTrigger@checkRepeatingLimits'); - $events->listen('limits.repetition', 'Firefly\Trigger\Limits\EloquentLimitTrigger@madeRepetition'); +// $events->listen('limits.destroy', 'Firefly\Trigger\Limits\EloquentLimitTrigger@destroy'); +// $events->listen('limits.store', 'Firefly\Trigger\Limits\EloquentLimitTrigger@store'); +// $events->listen('limits.update', 'Firefly\Trigger\Limits\EloquentLimitTrigger@update'); +// $events->listen('limits.check', 'Firefly\Trigger\Limits\EloquentLimitTrigger@checkRepeatingLimits'); +// $events->listen('limits.repetition', 'Firefly\Trigger\Limits\EloquentLimitTrigger@madeRepetition'); //\Event::fire('limits.repetition', [$repetition]); } diff --git a/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php b/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php index dec66c2dcf..5a51efe653 100644 --- a/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php +++ b/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php @@ -165,25 +165,13 @@ class EloquentPiggybankTrigger */ public function subscribe(Dispatcher $events) { - $events->listen( - 'piggybanks.modifyAmountAdd', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@modifyAmountAdd' - ); - $events->listen( - 'piggybanks.modifyAmountRemove', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@modifyAmountRemove' - ); - $events->listen('piggybanks.store', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@store'); - $events->listen('piggybanks.update', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@update'); - $events->listen( - 'piggybanks.createRelatedTransfer', - 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@createRelatedTransfer' - ); - $events->listen( - 'piggybanks.updateRelatedTransfer', - 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@updateRelatedTransfer' - ); - $events->listen( - 'piggybanks.storepiggybanks.check', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@checkRepeatingPiggies' - ); +// $events->listen('piggybanks.modifyAmountAdd', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@modifyAmountAdd'); +// $events->listen('piggybanks.modifyAmountRemove', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@modifyAmountRemove'); +// $events->listen('piggybanks.store', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@store'); +// $events->listen('piggybanks.update', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@update'); +// $events->listen('piggybanks.createRelatedTransfer', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@createRelatedTransfer'); +// $events->listen('piggybanks.updateRelatedTransfer', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@updateRelatedTransfer'); +// $events->listen('piggybanks.storepiggybanks.check', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@checkRepeatingPiggies'); } diff --git a/app/lib/Firefly/Trigger/Recurring/EloquentRecurringTrigger.php b/app/lib/Firefly/Trigger/Recurring/EloquentRecurringTrigger.php index 1faface9c0..b29167bb48 100644 --- a/app/lib/Firefly/Trigger/Recurring/EloquentRecurringTrigger.php +++ b/app/lib/Firefly/Trigger/Recurring/EloquentRecurringTrigger.php @@ -99,7 +99,7 @@ class EloquentRecurringTrigger */ public function subscribe(Dispatcher $events) { - $events->listen('recurring.rescan', 'Firefly\Trigger\Recurring\EloquentRecurringTrigger@rescan'); + //$events->listen('recurring.rescan', 'Firefly\Trigger\Recurring\EloquentRecurringTrigger@rescan'); } /** diff --git a/bootstrap/start.php b/bootstrap/start.php index ba5d06556b..b103864ddc 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -87,10 +87,10 @@ require $framework . '/Illuminate/Foundation/start.php'; */ // do something with events: -Event::subscribe('Firefly\Trigger\Limits\EloquentLimitTrigger'); -Event::subscribe('Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger'); -Event::subscribe('Firefly\Trigger\Budgets\EloquentBudgetTrigger'); -Event::subscribe('Firefly\Trigger\Recurring\EloquentRecurringTrigger'); -Event::subscribe('Firefly\Trigger\Journals\EloquentJournalTrigger'); +//Event::subscribe('Firefly\Trigger\Limits\EloquentLimitTrigger'); +//Event::subscribe('Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger'); +//Event::subscribe('Firefly\Trigger\Budgets\EloquentBudgetTrigger'); +//Event::subscribe('Firefly\Trigger\Recurring\EloquentRecurringTrigger'); +//Event::subscribe('Firefly\Trigger\Journals\EloquentJournalTrigger'); return $app; From 7b7743c03e9eeac79bb5aed7892d94a935d211a1 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 19:33:50 +0100 Subject: [PATCH 043/193] Fixed some bugs --- app/lib/FireflyIII/Database/Account.php | 18 ++++++-- app/lib/FireflyIII/Database/AccountType.php | 3 ++ app/lib/FireflyIII/Database/Budget.php | 3 +- app/lib/FireflyIII/Database/Category.php | 5 +++ .../Database/TransactionJournal.php | 45 ++++++++++++++++++- 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index 9c5c7cd894..6b31029726 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -464,6 +464,16 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface $accountType = $accountTypeRepos->findByWhat('expense'); + // if name is "", find cash account: + if (strlen($name) == 0) { + $cashAccountType = $accountTypeRepos->findByWhat('cash'); + + // find or create cash account: + return \Account::firstOrCreate( + ['name' => 'Cash account', 'account_type_id' => $cashAccountType->id, 'active' => 1, 'user_id' => $this->getUser()->id,] + ); + } + $data = ['user_id' => $this->getUser()->id, 'account_type_id' => $accountType->id, 'name' => $name, 'active' => 1]; return \Account::firstOrCreate($data); @@ -488,9 +498,11 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface $start = \Session::get('start'); $end = \Session::get('end'); $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; - $set = $this->getUser()->transactionJournals()->withRelevantData()->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transactions.account_id', $account->id)->take($limit)->offset($offset)->before($end)->after($start)->orderBy('date', 'DESC') - ->get(['transaction_journals.*']); + $set = $this->getUser()->transactionJournals()->withRelevantData()->leftJoin( + 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' + )->where('transactions.account_id', $account->id)->take($limit)->offset($offset)->before($end)->after($start)->orderBy('date', 'DESC')->get( + ['transaction_journals.*'] + ); $count = $this->getUser()->transactionJournals()->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') ->before($end)->after($start)->orderBy('date', 'DESC')->where('transactions.account_id', $account->id)->count(); $items = []; diff --git a/app/lib/FireflyIII/Database/AccountType.php b/app/lib/FireflyIII/Database/AccountType.php index 0c5341d1c5..302b8b2335 100644 --- a/app/lib/FireflyIII/Database/AccountType.php +++ b/app/lib/FireflyIII/Database/AccountType.php @@ -113,6 +113,9 @@ class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls case 'revenue': return \AccountType::whereType('Revenue account')->first(); break; + case 'cash': + return \AccountType::whereType('Cash account')->first(); + break; case 'initial': return \AccountType::whereType('Initial balance account')->first(); break; diff --git a/app/lib/FireflyIII/Database/Budget.php b/app/lib/FireflyIII/Database/Budget.php index 98c1ab8b14..ef901d29ec 100644 --- a/app/lib/FireflyIII/Database/Budget.php +++ b/app/lib/FireflyIII/Database/Budget.php @@ -142,8 +142,7 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface */ public function find($id) { - // TODO: Implement find() method. - throw new NotImplementedException; + return $this->getUser()->budgets()->find($id); } /** diff --git a/app/lib/FireflyIII/Database/Category.php b/app/lib/FireflyIII/Database/Category.php index faa11b7f65..253dd3ab99 100644 --- a/app/lib/FireflyIII/Database/Category.php +++ b/app/lib/FireflyIII/Database/Category.php @@ -170,6 +170,11 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface throw new NotImplementedException; } + public function firstOrCreate($name) + { + return \Category::firstOrCreate(['user_id' => $this->getUser()->id, 'name' => $name]); + } + public function getTransactionJournals(\Category $category, $limit = 50) { $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 55d4c0ac9e..2367a18ad0 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -48,7 +48,6 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData */ public function store(array $data) { - /** @var \FireflyIII\Database\TransactionType $typeRepository */ $typeRepository = \App::make('FireflyIII\Database\TransactionType'); @@ -127,12 +126,33 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData } /* - * TODO store budget and category. + * Store the budget. */ + if(isset($data['budget_id']) && intval($data['budget_id']) > 0) { + /** @var \FireflyIII\Database\Budget $budgetRepository */ + $budgetRepository = \App::make('FireflyIII\Database\Budget'); + $budget = $budgetRepository->find(intval($data['budget_id'])); + if($budget) { + $journal->budgets()->save($budget); + } + } + if(strlen($data['category']) > 0) { + /** @var \FireflyIII\Database\Category $categoryRepository */ + $categoryRepository = \App::make('FireflyIII\Database\Category'); + $category = $categoryRepository->firstOrCreate($data['category']); + if($category) { + $journal->categories()->save($category); + } + } $journal->completed = 1; $journal->save(); + /* + * Trigger a search for a relevant recurring transaction. + */ + + return $journal; } @@ -199,6 +219,27 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".'); break; } + + /* + * Store the budget. + */ + if(isset($data['budget_id']) && intval($data['budget_id']) > 0) { + /** @var \FireflyIII\Database\Budget $budgetRepository */ + $budgetRepository = \App::make('FireflyIII\Database\Budget'); + $budget = $budgetRepository->find(intval($data['budget_id'])); + if($budget) { + $model->budgets()->sync([$budget->id]); + } + } + if(strlen($data['category']) > 0) { + /** @var \FireflyIII\Database\Category $categoryRepository */ + $categoryRepository = \App::make('FireflyIII\Database\Category'); + $category = $categoryRepository->firstOrCreate($data['category']); + if($category) { + $model->categories()->sync([$category->id]); + } + } + /* * Now we can update the transactions related to this journal. */ From 3e02b50ea1216ddf319e1f260986dea5ca336020 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 14 Nov 2014 19:58:01 +0100 Subject: [PATCH 044/193] All kinds of todo items because otherwise I'd forget them. --- bootstrap/start.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/bootstrap/start.php b/bootstrap/start.php index b103864ddc..dd65f6590a 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -93,4 +93,18 @@ require $framework . '/Illuminate/Foundation/start.php'; //Event::subscribe('Firefly\Trigger\Recurring\EloquentRecurringTrigger'); //Event::subscribe('Firefly\Trigger\Journals\EloquentJournalTrigger'); +// TODO event that creates a relationship between transaction journals and recurring events when created. +// TODO event that updates the relationship between transaction journals and recurring events when edited. +// TODO event that creates a LimitRepetition when a Limit is created. +// TODO event for when a transfer gets created and set an associated piggy bank; save as Piggy bank event. +// TODO when this transfer gets edited, retro-actively edit the event and THUS also the piggy bank. +// TODO event for when a transfer gets deleted; also delete related piggy bank event. +// TODO event for when money is added to a piggy bank. +// TODO event for when money is removed from a piggy bank. +// TODO event to create the first repetition (for non-repeating piggy banks) when the piggy bank is created. +// TODO event for when the non-repeating piggy bank is updated because the single repetition must also be changed. +// (also make piggy bank events "invalid" when they start falling outside of the date-scope of the piggy bank, +// although this not changes the amount in the piggy bank). +// TODO check if recurring transactions are being updated when journals are updated (aka no longer fitting, thus removed). +// TODO think about reminders. return $app; From 6832f2ebd0470eb30a8749223b90f6f35a26932e Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 15 Nov 2014 07:46:01 +0100 Subject: [PATCH 045/193] Lots of code cleanup. --- app/controllers/CategoryController.php | 44 ++++-- app/controllers/RecurringController.php | 12 +- app/lib/FireflyIII/Database/Category.php | 12 +- app/lib/FireflyIII/Shared/Toolkit/Date.php | 40 ++++++ app/models/Piggybank.php | 66 +++++---- app/models/RecurringTransaction.php | 82 +++++++---- app/models/Transaction.php | 23 --- app/views/categories/create.blade.php | 60 +++----- app/views/charts/info.blade.php | 12 -- app/views/emails/auth/reminder.blade.php | 15 -- app/views/layouts/guest.blade.php | 4 +- app/views/limits/create.blade.php | 98 ------------- app/views/limits/delete.blade.php | 62 -------- app/views/limits/edit.blade.php | 115 --------------- app/views/list/recurring.blade.php | 14 +- .../lists.old/journals-large.old.blade.php | 63 --------- .../journals-small-index.old.blade.php | 27 ---- .../journals-small-noaccount.old.blade.php | 33 ----- .../lists.old/transactions.old.blade.php | 120 ---------------- app/views/paginated/transactions.blade.php | 3 - app/views/piggybanks/show.blade.php | 133 +----------------- app/views/recurring/show.blade.php | 24 +++- app/views/search/index.blade.php | 2 +- 23 files changed, 245 insertions(+), 819 deletions(-) delete mode 100644 app/views/charts/info.blade.php delete mode 100644 app/views/emails/auth/reminder.blade.php delete mode 100644 app/views/limits/create.blade.php delete mode 100644 app/views/limits/delete.blade.php delete mode 100644 app/views/limits/edit.blade.php delete mode 100644 app/views/lists.old/journals-large.old.blade.php delete mode 100644 app/views/lists.old/journals-small-index.old.blade.php delete mode 100644 app/views/lists.old/journals-small-noaccount.old.blade.php delete mode 100644 app/views/lists.old/transactions.old.blade.php delete mode 100644 app/views/paginated/transactions.blade.php diff --git a/app/controllers/CategoryController.php b/app/controllers/CategoryController.php index cb9aa2c649..ec05e23798 100644 --- a/app/controllers/CategoryController.php +++ b/app/controllers/CategoryController.php @@ -93,19 +93,43 @@ class CategoryController extends BaseController */ public function store() { - $category = $this->_repository->store(Input::all()); - if ($category->validate()) { - Session::flash('success', 'Category "' . $category->name . '" created!'); + $data = Input::all(); + /** @var \FireflyIII\Database\Category $repos */ + $repos = App::make('FireflyIII\Database\Category'); - if (Input::get('create') == '1') { - return Redirect::route('categories.create'); - } + switch ($data['post_submit_action']) { + default: + throw new FireflyException('Cannot handle post_submit_action "' . e($data['post_submit_action']) . '"'); + break; + case 'create_another': + case 'store': + $messages = $repos->validate($data); + /** @var MessageBag $messages ['errors'] */ + if ($messages['errors']->count() > 0) { + Session::flash('warnings', $messages['warnings']); + Session::flash('successes', $messages['successes']); + Session::flash('error', 'Could not save category: ' . $messages['errors']->first()); - return Redirect::route('categories.index'); - } else { - Session::flash('error', 'Could not save the new category!'); + return Redirect::route('categories.create')->withInput()->withErrors($messages['errors']); + } + // store! + $repos->store($data); + Session::flash('success', 'New category stored!'); - return Redirect::route('categories.create')->withInput(); + if ($data['post_submit_action'] == 'create_another') { + return Redirect::route('categories.create')->withInput(); + } else { + return Redirect::route('categories.index'); + } + break; + case 'validate_only': + $messageBags = $repos->validate($data); + Session::flash('warnings', $messageBags['warnings']); + Session::flash('successes', $messageBags['successes']); + Session::flash('errors', $messageBags['errors']); + + return Redirect::route('categories.create')->withInput(); + break; } } diff --git a/app/controllers/RecurringController.php b/app/controllers/RecurringController.php index 8a6f66ba75..a4027bcb00 100644 --- a/app/controllers/RecurringController.php +++ b/app/controllers/RecurringController.php @@ -1,4 +1,5 @@ get(); - return View::make('recurring.index',compact('recurring')); + + return View::make('recurring.index', compact('recurring')); } /** @@ -116,9 +118,13 @@ class RecurringController extends BaseController */ public function show(RecurringTransaction $recurringTransaction) { - $journals = $recurringTransaction->transactionjournals()->withRelevantData()->orderBy('date','DESC')->get(); + $journals = $recurringTransaction->transactionjournals()->withRelevantData()->orderBy('date', 'DESC')->get(); $hideRecurring = true; - return View::make('recurring.show',compact('journals','hideRecurring'))->with('recurring', $recurringTransaction)->with('subTitle', $recurringTransaction->name); + + + return View::make('recurring.show', compact('journals', 'hideRecurring','finalDate'))->with('recurring', $recurringTransaction)->with( + 'subTitle', $recurringTransaction->name + ); } public function store() diff --git a/app/lib/FireflyIII/Database/Category.php b/app/lib/FireflyIII/Database/Category.php index 253dd3ab99..7056754dd8 100644 --- a/app/lib/FireflyIII/Database/Category.php +++ b/app/lib/FireflyIII/Database/Category.php @@ -46,8 +46,16 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface */ public function store(array $data) { - // TODO: Implement store() method. - throw new NotImplementedException; + $category = new \Category; + $category->name = $data['name']; + $category->class = 'Category'; + $category->user()->associate($this->getUser()); + if(!$category->validate()) { + var_dump($category->errors()); + exit(); + } + $category->save(); + return $category; } /** diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index 352685dfca..194305a829 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -83,6 +83,7 @@ class Date $currentEnd->addYear()->subDay(); break; } + return $currentEnd; } /** @@ -124,4 +125,43 @@ class Date return $date; } + + /** + * @param Carbon $date + * @param $repeatFreq + * @param int $substract + * + * @return Carbon + * @throws FireflyException + */ + public function substractPeriod(Carbon $date, $repeatFreq, $substract = 1) + { + switch ($repeatFreq) { + default: + throw new FireflyException('Cannot do addPeriod for $repeat_freq ' . $repeatFreq); + break; + case 'daily': + $date->subDays($substract); + break; + case 'weekly': + $date->subWeeks($substract); + break; + case 'monthly': + $date->subMonths($substract); + break; + case 'quarterly': + $months = $substract * 3; + $date->subMonths($months); + break; + case 'half-year': + $months = $substract * 6; + $date->subMonths($months); + break; + case 'yearly': + $date->subYears($substract); + break; + } + + return $date; + } } \ No newline at end of file diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php index 03ec278c47..890e1ea270 100644 --- a/app/models/Piggybank.php +++ b/app/models/Piggybank.php @@ -90,7 +90,15 @@ class Piggybank extends Ardent */ public function currentRelevantRep() { - $query = $this->piggybankrepetitions()->where( + if($this->currentRep) { + return $this->currentRep; + } + if ($this->repeats == 0) { + $rep = $this->piggybankrepetitions()->first(); + $this->currentRep = $rep; + return $rep; + } else { + $query = $this->piggybankrepetitions()->where( function ($q) { $q->where( @@ -100,12 +108,12 @@ class Piggybank extends Ardent $q->orWhere('startdate', '<=', $today->format('Y-m-d')); } )->where( - function ($q) { - $today = new Carbon; - $q->whereNull('targetdate'); - $q->orWhere('targetdate', '>=', $today->format('Y-m-d')); - } - ); + function ($q) { + $today = new Carbon; + $q->whereNull('targetdate'); + $q->orWhere('targetdate', '>=', $today->format('Y-m-d')); + } + ); } )->orWhere( function ($q) { @@ -114,9 +122,11 @@ class Piggybank extends Ardent $q->where('targetdate', '>=', $today->format('Y-m-d')); } )->orderBy('startdate', 'ASC'); - $result = $query->first(); + $result = $query->first(); + $this->currentRep = $result; - return $result; + return $result; + } } @@ -155,26 +165,26 @@ class Piggybank extends Ardent public function repetitionForDate(Carbon $date) { $query = $this->piggybankrepetitions()->where( - function ($q) use ($date) { + function ($q) use ($date) { - $q->where( - function ($q) use ($date) { - $q->whereNull('startdate'); - $q->orWhere('startdate', '<=', $date->format('Y-m-d')); - } - )->where( - function ($q) use ($date) { - $q->whereNull('targetdate'); - $q->orWhere('targetdate', '>=', $date->format('Y-m-d')); - } - ); - } - )->orWhere( - function ($q) use ($date) { - $q->where('startdate', '>=', $date->format('Y-m-d')); - $q->where('targetdate', '>=', $date->format('Y-m-d')); - } - )->orderBy('startdate', 'ASC'); + $q->where( + function ($q) use ($date) { + $q->whereNull('startdate'); + $q->orWhere('startdate', '<=', $date->format('Y-m-d')); + } + )->where( + function ($q) use ($date) { + $q->whereNull('targetdate'); + $q->orWhere('targetdate', '>=', $date->format('Y-m-d')); + } + ); + } + )->orWhere( + function ($q) use ($date) { + $q->where('startdate', '>=', $date->format('Y-m-d')); + $q->where('targetdate', '>=', $date->format('Y-m-d')); + } + )->orderBy('startdate', 'ASC'); $result = $query->first(); return $result; diff --git a/app/models/RecurringTransaction.php b/app/models/RecurringTransaction.php index 556535baec..56cd8d81c8 100644 --- a/app/models/RecurringTransaction.php +++ b/app/models/RecurringTransaction.php @@ -51,44 +51,66 @@ class RecurringTransaction extends Ardent return ['created_at', 'updated_at', 'date']; } + public function lastFoundMatch() { + $last = $this->transactionjournals()->orderBy('date','DESC')->first(); + if($last) { + return $last->date; + } + return null; + } /** - * @return Carbon + * Find the next expected match based on the set journals and the date stuff from the recurring + * transaction. */ - public function next() + public function nextExpectedMatch() { - $today = new Carbon; - $start = clone $this->date; - $skip = $this->skip == 0 ? 1 : $this->skip; - if ($today < $start) { - return $start; - } - while ($start <= $this->date) { - switch ($this->repeat_freq) { - case 'daily': - $start->addDays($skip); - break; - case 'weekly': - $start->addWeeks($skip); - break; - case 'monthly': - $start->addMonths($skip); - break; - case 'quarterly': - $start->addMonths($skip * 3); - break; - case 'half-year': - $start->addMonths($skip * 6); - break; - case 'yearly': - $start->addYears($skip); - break; + /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ + $dateKit = App::make('FireflyIII\Shared\Toolkit\Date'); + /* + * The date Firefly tries to find. If this stays null, it's "unknown". + */ + $finalDate = null; + + /* + * $today is the start of the next period, to make sure FF3 won't miss anything + * when the current period has a transaction journal. + */ + $today = $dateKit->addPeriod(new Carbon, $this->repeat_freq, 0); + + /* + * FF3 loops from the $start of the recurring transaction, and to make sure + * $skip works, it adds one (for modulo). + */ + $skip = $this->skip + 1; + $start = $dateKit->startOfPeriod(new Carbon, $this->repeat_freq); + /* + * go back exactly one month/week/etc because FF3 does not care about 'next' + * recurring transactions if they're too far into the past. + */ + // echo 'Repeat freq is: ' . $recurringTransaction->repeat_freq . '
'; + + // echo 'Start: ' . $start . '
'; + + $counter = 0; + while ($start <= $today) { + if (($counter % $skip) == 0) { + // do something. + $end = $dateKit->endOfPeriod(clone $start, $this->repeat_freq); + $journalCount = $this->transactionjournals()->before($end)->after($start)->count(); + if ($journalCount == 0) { + $finalDate = clone $start; + break; + } } - } - return $start; + // add period for next round! + $start = $dateKit->addPeriod($start, $this->repeat_freq, 0); + $counter++; + } + return $finalDate; } /** diff --git a/app/models/Transaction.php b/app/models/Transaction.php index a60d5535eb..6a85e97864 100644 --- a/app/models/Transaction.php +++ b/app/models/Transaction.php @@ -78,29 +78,6 @@ class Transaction extends Ardent return $this->belongsToMany('Component'); } - /** - * @param Piggybank $piggybank - * - * @return bool - */ - public function connectPiggybank(\Piggybank $piggybank = null) - { - // TODO connect a piggy bank to a transaction. - throw new NotImplementedException; - // if (is_null($piggybank)) { - // return true; - // } - // /** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggyRepository */ - // $piggyRepository = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface'); - // if ($this->account_id == $piggybank->account_id) { - // $this->piggybank()->associate($piggybank); - // $this->save(); - // \Event::fire('piggybanks.createRelatedTransfer', [$piggybank, $this->transactionJournal, $this]); - // return true; - // } - // return false; - } - /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ diff --git a/app/views/categories/create.blade.php b/app/views/categories/create.blade.php index bf8c855596..77868e12f4 100644 --- a/app/views/categories/create.blade.php +++ b/app/views/categories/create.blade.php @@ -1,57 +1,37 @@ @extends('layouts.default') @section('content') -
-
-

Use categories to group your expenses

-

- Use categories to group expenses by hobby, for certain types of groceries or what bills are for. - Expenses grouped in categories do not have to reoccur every month or every week, like budgets. -

-
-
{{Form::open(['class' => 'form-horizontal','url' => route('categories.store')])}}
-
-

Mandatory fields

- -
- -
- - @if($errors->has('name')) -

{{$errors->first('name')}}

- @else - For example: bike, utilities, daily groceries - @endif +
+
+
+ Mandatory fields +
+
+ {{Form::ffText('name')}}
- +

+ +

-
-
-
+
- -
- -
-
- -
+ +
+
+ Options +
+
+ {{Form::ffOptionsList('create','category')}}
-
-
- -
-
diff --git a/app/views/charts/info.blade.php b/app/views/charts/info.blade.php deleted file mode 100644 index 00e590e129..0000000000 --- a/app/views/charts/info.blade.php +++ /dev/null @@ -1,12 +0,0 @@ -
Amount {{mf($t->amount)}}
- - - - - @foreach($rows as $name => $entry) - - - - - @endforeach -
Total{{mf($sum*-1)}}
{{{$name}}}{{mf($entry['amount']*-1)}}
\ No newline at end of file diff --git a/app/views/emails/auth/reminder.blade.php b/app/views/emails/auth/reminder.blade.php deleted file mode 100644 index 276f8c59f2..0000000000 --- a/app/views/emails/auth/reminder.blade.php +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - -

Password Reset

- -
- To reset your password, complete this form: {{ URL::to('password/reset', array($token)) }}.
- This link will expire in {{ Config::get('auth.reminder.expire', 60) }} minutes. -
- - - \ No newline at end of file diff --git a/app/views/layouts/guest.blade.php b/app/views/layouts/guest.blade.php index df2a721548..8485ddaccb 100644 --- a/app/views/layouts/guest.blade.php +++ b/app/views/layouts/guest.blade.php @@ -5,7 +5,7 @@ - Firefly + Firefly III {{HTML::style('assets/stylesheets/bootstrap/bootstrap.min.css')}} {{HTML::style('assets/stylesheets/metisMenu/metisMenu.min.css')}} @@ -25,4 +25,4 @@ @yield('content')
- \ No newline at end of file + \ No newline at end of file diff --git a/app/views/limits/create.blade.php b/app/views/limits/create.blade.php deleted file mode 100644 index a3a13c4dcf..0000000000 --- a/app/views/limits/create.blade.php +++ /dev/null @@ -1,98 +0,0 @@ -@extends('layouts.default') -@section('content') -
-
-

- Firefly uses an "envelope - system" for your budgets, which means that for each period of time (for example a month) a virtual - "envelope" can be created containing a certain amount of money. Money spent within a budget is removed from - the envelope. -

- -

- Firefly gives you the opportunity to create such an envelope when you create a budget. However, you can - always add more of them. -

-
-
- -{{Form::open(['class' => 'form-horizontal','url' => route('budgets.limits.store',$prefilled['budget_id'])])}} -{{Form::hidden('from',e(Input::get('from')))}} - - -
-
-

Mandatory fields

- -
- {{ Form::label('budget_id', 'Budget', ['class' => 'col-sm-4 control-label'])}} -
- {{Form::select('budget_id',$budgets,Input::old('budget_id') ?: $prefilled['budget_id'], ['class' => - 'form-control'])}} - @if($errors->has('budget_id')) -

{{$errors->first('name')}}

- @else - Select one of your existing budgets. - @endif -
-
- -
- {{ Form::label('startdate', 'Start date', ['class' => 'col-sm-4 control-label'])}} -
- - This date indicates when the envelope "starts". The date you select - here will correct itself to the nearest [period] you select below. -
-
- -
- - -
- {{Form::select('period',$periods,Input::old('period') ?: $prefilled['repeat_freq'],['class' => 'form-control'])}} - How long will the envelope last? A week, a month, or even longer? -
-
-
- - -
-
- -
- If you want, Firefly can automatically recreate the "envelope" and fill it again - when the timespan above has expired. Be careful with this option though. It makes it easier - to fall back to old habits. - Instead, you should recreate the envelope yourself each [period]. -
-
- - -
- {{ Form::label('amount', 'Amount', ['class' => 'col-sm-4 control-label'])}} -
- - Of course, there needs to be money in the envelope. -
-
- -
- {{ Form::label('submit', ' ', ['class' => 'col-sm-4 control-label'])}} -
- - -
-
- -
-
- -{{Form::close()}} - - -@stop \ No newline at end of file diff --git a/app/views/limits/delete.blade.php b/app/views/limits/delete.blade.php deleted file mode 100644 index 4c3bd9b8b7..0000000000 --- a/app/views/limits/delete.blade.php +++ /dev/null @@ -1,62 +0,0 @@ -@extends('layouts.default') -@section('content') -
-
-

Remember that deleting something is permanent.

- -
- -
- -{{Form::open(['class' => 'form-horizontal','url' => route('budgets.limits.destroy',$limit->id)])}} - -
-
-

 

-

- This form allows you to delete the envelope for budget {{{$limit->budget->name}}}, with a content of - {{mf($limit->amount,false)}} - @if($limit->repeats == 0) - in {{$limit->limitrepetitions[0]->startdate->format('M Y')}} ({{$limit->repeat_freq}}). - @endif -

-

- Destroying an envelope does not remove any transactions from the budget. -

-

- Are you sure? -

- -
-
- - @if(Input::get('from') == 'date') - Cancel - @else - Cancel - @endif -
-
-
- @if($limit->repeats == 1) -
-

Auto repeating

-

- This envelope is set to repeat itself; creating a new period whenever the previous period - has passed. If you change this envelope, you'll also change the following (automatically created) - envelopes. - {{$limit->limitrepetitions()->count() }} -

-
    - @foreach($limit->limitrepetitions()->orderBy('startdate','DESC')->get() as $rep) -
  • Evenlope for {{$rep->periodShow()}}, {{mf($rep->amount,false)}}
  • - @endforeach -
-
- @endif -
- - -{{Form::close()}} - -@stop diff --git a/app/views/limits/edit.blade.php b/app/views/limits/edit.blade.php deleted file mode 100644 index 7ba95b132b..0000000000 --- a/app/views/limits/edit.blade.php +++ /dev/null @@ -1,115 +0,0 @@ -@extends('layouts.default') -@section('content') -
-
-

- Firefly uses an "envelope - system" for your budgets, which means that for each period of time (for example a month) a virtual - "envelope" can be created containing a certain amount of money. Money spent within a budget is removed from - the envelope. -

- -

- This form allows you to edit the envelope for budget {{{$limit->budget->name}}}, with a content of - {{mf($limit->amount,false)}} - @if($limit->repeats == 0) - in {{$limit->limitrepetitions[0]->startdate->format('M Y')}} ({{$limit->repeat_freq}}). - @endif -

-
-
- -{{Form::open(['class' => 'form-horizontal','url' => route('budgets.limits.update',$limit->id)])}} -{{Form::hidden('from',e(Input::get('from')))}} -
-
-

Mandatory fields

- -
- {{ Form::label('budget_id', 'Budget', ['class' => 'col-sm-4 control-label'])}} -
- {{Form::select('budget_id',$budgets,Input::old('budget_id') ?: $limit->component_id, ['class' => - 'form-control'])}} - @if($errors->has('budget_id')) -

{{$errors->first('name')}}

- @else - Select one of your existing budgets. - @endif -
-
- -
- {{ Form::label('startdate', 'Start date', ['class' => 'col-sm-4 control-label'])}} -
- - This date indicates when the envelope "starts". The date you select - here will correct itself to the nearest [period] you select below. -
-
- -
- - -
- {{Form::select('period',$periods,Input::old('period') ?: $limit->repeat_freq,['class' => 'form-control'])}} - How long will the envelope last? A week, a month, or even longer? -
-
-
- - -
-
- -
- If you want, Firefly can automatically recreate the "envelope" and fill it again - when the timespan above has expired. Be careful with this option though. It makes it easier - to fall back to old habits. - Instead, you should recreate the envelope yourself each [period]. -
-
- - -
- {{ Form::label('amount', 'Amount', ['class' => 'col-sm-4 control-label'])}} -
- - Of course, there needs to be money in the envelope. -
-
- -
- {{ Form::label('submit', ' ', ['class' => 'col-sm-4 control-label'])}} -
- - -
-
- -
- @if($limit->repeats == 1) -
-

Auto repeating

-

- This envelope is set to repeat itself; creating a new period whenever the previous period - has passed. If you change this envelope, you'll also change the following (automatically created) - envelopes. - {{$limit->limitrepetitions()->count() }} -

-
    - @foreach($limit->limitrepetitions()->orderBy('startdate','DESC')->get() as $rep) -
  • Evenlope for {{$rep->periodShow()}}, {{mf($rep->amount,false)}}
  • - @endforeach -
-
- @endif -
- -{{Form::close()}} - - -@stop diff --git a/app/views/list/recurring.blade.php b/app/views/list/recurring.blade.php index 7edf6d4e46..624914c97f 100644 --- a/app/views/list/recurring.blade.php +++ b/app/views/list/recurring.blade.php @@ -32,10 +32,20 @@ {{mf($entry->amount_max)}} - + lastFoundMatch();?> + @if($lastMatch) + {{$lastMatch->format('j F Y')}} + @else + Unknown + @endif - + nextExpectedMatch();?> + @if($nextExpectedMatch) + {{$nextExpectedMatch->format('j F Y')}} + @else + Unknown + @endif @if($entry->active) diff --git a/app/views/lists.old/journals-large.old.blade.php b/app/views/lists.old/journals-large.old.blade.php deleted file mode 100644 index 8ff26bcad0..0000000000 --- a/app/views/lists.old/journals-large.old.blade.php +++ /dev/null @@ -1,63 +0,0 @@ - - - - - @foreach($journals as $journal) - - - - - - - - - - @endforeach -
- @if($journal->transactiontype->type == 'Withdrawal') - - @endif - @if($journal->transactiontype->type == 'Deposit') - - @endif - @if($journal->transactiontype->type == 'Transfer') - - @endif - @if($journal->transactiontype->type == 'Opening balance') - - @endif - - bud / cat - {{{$journal->description}}} - @if($journal->transactiontype->type == 'Withdrawal') - {{mf($journal->transactions[1]->amount,false)}} - @endif - @if($journal->transactiontype->type == 'Deposit') - {{mf($journal->transactions[1]->amount,false)}} - @endif - @if($journal->transactiontype->type == 'Transfer') - {{mf($journal->transactions[1]->amount,false)}} - @endif - - @if($journal->transactions[0]->account->accounttype->description == 'Cash account') - (cash) - @else - {{{$journal->transactions[0]->account->name}}} - @endif - - @if($journal->transactions[1]->account->accounttype->description == 'Cash account') - (cash) - @else - {{{$journal->transactions[1]->account->name}}} - @endif - - -
- -{{$journals->links()}} \ No newline at end of file diff --git a/app/views/lists.old/journals-small-index.old.blade.php b/app/views/lists.old/journals-small-index.old.blade.php deleted file mode 100644 index e8e5be5a4f..0000000000 --- a/app/views/lists.old/journals-small-index.old.blade.php +++ /dev/null @@ -1,27 +0,0 @@ - \ No newline at end of file diff --git a/app/views/lists.old/journals-small-noaccount.old.blade.php b/app/views/lists.old/journals-small-noaccount.old.blade.php deleted file mode 100644 index 0cb8c04855..0000000000 --- a/app/views/lists.old/journals-small-noaccount.old.blade.php +++ /dev/null @@ -1,33 +0,0 @@ - \ No newline at end of file diff --git a/app/views/lists.old/transactions.old.blade.php b/app/views/lists.old/transactions.old.blade.php deleted file mode 100644 index ceb0f54757..0000000000 --- a/app/views/lists.old/transactions.old.blade.php +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - @foreach($journals as $journal) - @if(isset($journal->transactions[0]) && isset($journal->transactions[1])) - id) - class="success" - @endif - > - - - - - - - - - - @else - - @endif - @endforeach - @if(isset($sum) && $sum == true) - @if($expenses != 0) - - - - - @endif - @if($incomes != 0) - - - - - @endif - @if($transfers != 0) - - - - - @endif - @endif - - -
ADateDescriptionAmount (€)FromToB
- @if($journal->transactiontype->type == 'Withdrawal') - - @endif - @if($journal->transactiontype->type == 'Deposit') - - @endif - @if($journal->transactiontype->type == 'Transfer') - - @endif - @if($journal->transactiontype->type == 'Opening balance') - - @endif - - @foreach($journal->components as $component) - @if($component->class == 'Budget') - - @endif - @if($component->class == 'Category') - - @endif - @endforeach - - @if(!is_null($journal->recurringTransaction)) - - @endif - - {{$journal->date->format('d F Y')}} - {{{$journal->description}}} - @if($journal->transactiontype->type == 'Withdrawal') - {{mf($journal->transactions[1]->amount,false)}} - transactions[1]->amount;?> - @endif - @if($journal->transactiontype->type == 'Deposit') - {{mf($journal->transactions[1]->amount,false)}} - transactions[1]->amount;?> - @endif - @if($journal->transactiontype->type == 'Transfer') - {{mf($journal->transactions[1]->amount,false)}} - transactions[1]->amount;?> - @endif - - {{{$journal->transactions[0]->account->name}}} - - {{{$journal->transactions[1]->account->name}}} - - @if($journal->transactiontype->type != 'Opening balance') - - @endif -
Expenses:{{mf($expenses)}}
Incomes:{{mf($incomes)}}
Transfers:{{mf($transfers,false)}}
\ No newline at end of file diff --git a/app/views/paginated/transactions.blade.php b/app/views/paginated/transactions.blade.php deleted file mode 100644 index 223541781e..0000000000 --- a/app/views/paginated/transactions.blade.php +++ /dev/null @@ -1,3 +0,0 @@ -{{$journals->links()}} -@include('lists.transactions') -{{$journals->links()}} \ No newline at end of file diff --git a/app/views/piggybanks/show.blade.php b/app/views/piggybanks/show.blade.php index 4a6df0a352..813f8ed5db 100644 --- a/app/views/piggybanks/show.blade.php +++ b/app/views/piggybanks/show.blade.php @@ -8,7 +8,7 @@ Events
-
+
@@ -30,11 +30,11 @@ Saved so far - {{mf(0)}} + {{mf($piggybank->currentRelevantRep()->currentamount)}} Left to save - {{mf(0)}} + {{mf($piggybank->targetamount-$piggybank->currentRelevantRep()->currentamount)}} Start date @@ -72,11 +72,11 @@ Reminders left - 12 + 12 Expected amount per reminder - {{mf(0)}} + {{mf(0)}} @@ -84,129 +84,6 @@ - -{{-- -
-
-
- Edit - Delete - - @if(min(max($balance,$leftOnAccount),$piggybank->targetamount) > 0) - Add money - @endif - - @if($piggybank->currentRelevantRep()->currentamount > 0) - Remove money - @endif -
-
-
-
-
-

General information

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldValue
Account{{{$piggybank->account->name}}}
Target amount{{mf($piggybank->targetamount)}}
Start date - @if(is_null($piggybank->startdate)) - No start date - @else - {{$piggybank->startdate->format('jS F Y')}} - @endif -
Target date - @if(is_null($piggybank->targetdate)) - No target date - @else - {{$piggybank->targetdate->format('jS F Y')}} - @endif -
Repeats every - @if(!is_null($piggybank->rep_length)) - Every {{$piggybank->rep_every}} {{$piggybank->rep_length}}(s) - @if(!is_null($piggybank->rep_times)) - ({{$piggybank->rep_times}} times) - @else - (indefinitely) - @endif - @else - Does not repeat - @endif -
Reminder - @if(is_null($piggybank->reminder)) - (no reminder) - @else - Every {{$piggybank->reminder_skip}} {{$piggybank->reminder}}(s) - @endif -
-
-
-

Piggy bank instances info

- @foreach($piggybank->piggybankrepetitions()->orderBy('startdate')->get() as $rep) - - - - - - - - - - - - - - - - - - - - - -
FieldValue
ID#{{$rep->id}}
Current amount{{mf($rep->currentamount)}} of {{mf($piggybank->targetamount)}}
Start date - @if(is_null($rep->startdate)) - No start date - @else - {{$rep->startdate->format('jS F Y')}} - @endif -
Target date - @if(is_null($rep->targetdate)) - No target date - @else - {{$rep->targetdate->format('jS F Y')}} - @endif -
- @endforeach -
-
---}} @stop @section('scripts') diff --git a/app/views/recurring/show.blade.php b/app/views/recurring/show.blade.php index 910aa69dea..a1f229b27d 100644 --- a/app/views/recurring/show.blade.php +++ b/app/views/recurring/show.blade.php @@ -46,8 +46,15 @@ - Next reminder - some date + Next expected match + + nextExpectedMatch();?> + @if($nextExpectedMatch) + {{$nextExpectedMatch->format('j F Y')}} + @else + Unknown + @endif + @@ -67,6 +74,19 @@ +
+
+
+
+ Chart +
+
+ +
+
+
+
+
diff --git a/app/views/search/index.blade.php b/app/views/search/index.blade.php index c20ec700b7..c02339ef15 100644 --- a/app/views/search/index.blade.php +++ b/app/views/search/index.blade.php @@ -1,7 +1,7 @@ @extends('layouts.default') @section('content') @if(!is_null($query)) -
+
@if(isset($result['transactions']) && $result['transactions']->count() > 0)
From 6eb91886908bc3a8e572aee517fa0359e5a9bf92 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 15 Nov 2014 09:23:07 +0100 Subject: [PATCH 046/193] Cleaned up preferences view. --- app/views/preferences/index.blade.php | 137 +++++++++++++------------- app/views/start.blade.php | 41 -------- 2 files changed, 66 insertions(+), 112 deletions(-) delete mode 100644 app/views/start.blade.php diff --git a/app/views/preferences/index.blade.php b/app/views/preferences/index.blade.php index b9b273a565..36f761a2c7 100644 --- a/app/views/preferences/index.blade.php +++ b/app/views/preferences/index.blade.php @@ -3,87 +3,82 @@ {{Form::open(['class' => 'form-horizontal'])}} - -
-
-

Home screen accounts

-

Which accounts should be displayed on the home page?

- @foreach($accounts as $account) -
-
-
- +
+
+
+ Home screen accounts +
+
+

Which accounts should be displayed on the home page?

+ @foreach($accounts as $account) +
+
+
+ +
+
+ @endforeach +
+
+
+
+
+
+ Home view range +
+
+

By default, Firefly will show you one month of data.

+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
- @endforeach - - +
- -
-

Home view range

-

By default, Firefly will show you one month of data.

-
- -
- -
- -
- -
- -
- -
- -
- -
- -
- - - - -
-
- - - - -
-
-

Submit

- +
diff --git a/app/views/start.blade.php b/app/views/start.blade.php deleted file mode 100644 index 907a489bd8..0000000000 --- a/app/views/start.blade.php +++ /dev/null @@ -1,41 +0,0 @@ -@extends('layouts.default') -@section('content') -
-
-

Firefly
- Welcome! -

-
-
- -
-
-

- Welcome to Firefly! To get started, choose either of the two options below. -

-
-
- -
-
-

Start fresh

-

- Click the link below to create your first account, and get started with Firefly. -

-

- Start with a new account -

-
- -
-

Migrate from another Firefly

-

- If you've used Firefly before and have another database around, follow this link to import - your data from a previous version. -

-

- Import your old data -

-
-
-@stop \ No newline at end of file From 8c949e6190950cf42522528ff4b126038df7dae9 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 15 Nov 2014 09:32:25 +0100 Subject: [PATCH 047/193] Events that keep track of piggy bank money add/remove --- app/controllers/PiggybankController.php | 14 +++++++ app/lib/FireflyIII/Event/Piggybank.php | 56 +++++++++++++++++++++++++ bootstrap/start.php | 1 + 3 files changed, 71 insertions(+) create mode 100644 app/lib/FireflyIII/Event/Piggybank.php diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index f0521704c2..2f2310c75a 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -19,6 +19,7 @@ class PiggybankController extends BaseController } /** + * Add money to piggy bank * @param Piggybank $piggybank * * @return $this @@ -150,6 +151,7 @@ class PiggybankController extends BaseController } /** + * POST add money to piggy bank * @param Piggybank $piggybank * * @return \Illuminate\Http\RedirectResponse @@ -170,6 +172,12 @@ class PiggybankController extends BaseController $repetition = $piggybank->currentRelevantRep(); $repetition->currentamount += $amount; $repetition->save(); + + /* + * Create event! + */ + Event::fire('piggybank.addMoney',[$piggybank, $amount]); + Session::flash('success', 'Added ' . mf($amount, false) . ' to "' . e($piggybank->name) . '".'); } else { Session::flash('error', 'Could not add ' . mf($amount, false) . ' to "' . e($piggybank->name) . '".'); @@ -193,6 +201,12 @@ class PiggybankController extends BaseController $repetition = $piggybank->currentRelevantRep(); $repetition->currentamount -= $amount; $repetition->save(); + + /* + * Create event! + */ + Event::fire('piggybank.removeMoney',[$piggybank, $amount]); + Session::flash('success', 'Removed ' . mf($amount, false) . ' from "' . e($piggybank->name) . '".'); } else { Session::flash('error', 'Could not remove ' . mf($amount, false) . ' from "' . e($piggybank->name) . '".'); diff --git a/app/lib/FireflyIII/Event/Piggybank.php b/app/lib/FireflyIII/Event/Piggybank.php new file mode 100644 index 0000000000..0a2da1922b --- /dev/null +++ b/app/lib/FireflyIII/Event/Piggybank.php @@ -0,0 +1,56 @@ + 0) { + $event = new \PiggybankEvent; + $event->piggybank()->associate($piggybank); + $event->amount = floatval($amount); + $event->date = new Carbon; + if(!$event->validate()) { + var_dump($event->errors()); + exit(); + } + $event->save(); + } + } + + /** + * @param \Piggybank $piggybank + * @param float $amount + */ + public function removeMoney(\Piggybank $piggybank, $amount = 0.0) { + $amount = $amount * -1; + if($amount < 0) { + $event = new \PiggybankEvent; + $event->piggybank()->associate($piggybank); + $event->amount = floatval($amount); + $event->date = new Carbon; + if(!$event->validate()) { + var_dump($event->errors()); + exit(); + } + $event->save(); + } + } + + /** + * @param Dispatcher $events + */ + public function subscribe(Dispatcher $events) + { + $events->listen('piggybank.addMoney', 'FireflyIII\Event\Piggybank@addMoney'); + $events->listen('piggybank.removeMoney', 'FireflyIII\Event\Piggybank@removeMoney'); + } +} \ No newline at end of file diff --git a/bootstrap/start.php b/bootstrap/start.php index dd65f6590a..d476cc0f57 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -92,6 +92,7 @@ require $framework . '/Illuminate/Foundation/start.php'; //Event::subscribe('Firefly\Trigger\Budgets\EloquentBudgetTrigger'); //Event::subscribe('Firefly\Trigger\Recurring\EloquentRecurringTrigger'); //Event::subscribe('Firefly\Trigger\Journals\EloquentJournalTrigger'); +Event::subscribe('FireflyIII\Event\Piggybank'); // TODO event that creates a relationship between transaction journals and recurring events when created. // TODO event that updates the relationship between transaction journals and recurring events when edited. From 61aba29df75e10d5da8d6d7e8fc6fb4eadd15d3a Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 15 Nov 2014 11:36:27 +0100 Subject: [PATCH 048/193] More stuffs. Too lazy to explain. --- app/controllers/GoogleChartController.php | 77 +++++++++++++++---- app/controllers/PiggybankController.php | 28 +++++-- app/lib/FireflyIII/Database/Piggybank.php | 2 + app/lib/FireflyIII/Form/Form.php | 3 + app/lib/FireflyIII/Shared/Toolkit/Date.php | 2 + app/models/Piggybank.php | 23 +++++- app/views/list/piggybank-events.blade.php | 18 +++++ app/views/piggybanks/edit.blade.php | 4 +- app/views/piggybanks/show.blade.php | 30 +++++++- app/views/recurring/show.blade.php | 1 + bootstrap/start.php | 2 - public/assets/javascript/firefly/recurring.js | 8 +- 12 files changed, 162 insertions(+), 36 deletions(-) create mode 100644 app/views/list/piggybank-events.blade.php diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index 15651be465..464e24e20e 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -336,6 +336,34 @@ class GoogleChartController extends BaseController } + public function budgetLimitSpending(\Budget $budget, \LimitRepetition $repetition) + { + $start = clone $repetition->startdate; + $end = $repetition->enddate; + + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('Day', 'date'); + $chart->addColumn('Left', 'number'); + + + $amount = $repetition->amount; + + while ($start <= $end) { + /* + * Sum of expenses on this day: + */ + $sum = floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($start)->sum('amount')); + $amount += $sum; + $chart->addRow(clone $start, $amount); + $start->addDay(); + } + $chart->generate(); + + return Response::json($chart->getData()); + + } + /** * @return \Illuminate\Http\JsonResponse */ @@ -445,28 +473,44 @@ class GoogleChartController extends BaseController } - public function budgetLimitSpending(\Budget $budget, \LimitRepetition $repetition) { - $start = clone $repetition->startdate; - $end = $repetition->enddate; + /** + * @param RecurringTransaction $recurring + */ + public function recurringOverview(RecurringTransaction $recurring) + { + + /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ + $dateKit = App::make('FireflyIII\Shared\Toolkit\Date'); /** @var \Grumpydictator\Gchart\GChart $chart */ $chart = App::make('gchart'); - $chart->addColumn('Day', 'date'); - $chart->addColumn('Left', 'number'); + $chart->addColumn('Date', 'date'); + $chart->addColumn('Max amount', 'number'); + $chart->addColumn('Min amount', 'number'); + $chart->addColumn('Current entry', 'number'); - - $amount = $repetition->amount; - - while($start <= $end) { - /* - * Sum of expenses on this day: - */ - $sum = floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($start)->sum('amount')); - $amount += $sum; - $chart->addRow(clone $start, $amount); - $start->addDay(); + // get first transaction or today for start: + $first = $recurring->transactionjournals()->orderBy('date', 'ASC')->first(); + if ($first) { + $start = $first->date; + } else { + $start = new Carbon; } + $end = new Carbon; + while ($start <= $end) { + $result = $recurring->transactionjournals()->before($end)->after($start)->first(); + if($result) { + $amount = $result->getAmount(); + } else { + $amount = 0; + } + unset($result); + $chart->addRow(clone $start, $recurring->amount_max, $recurring->amount_min, $amount); + $start = $dateKit->addPeriod($start, $recurring->repeat_freq, 0); + } + $chart->generate(); + return Response::json($chart->getData()); } @@ -551,6 +595,7 @@ class GoogleChartController extends BaseController $chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']); $chart->generate(); + return Response::json($chart->getData()); } diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index 2f2310c75a..e1bca56ab6 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -20,6 +20,7 @@ class PiggybankController extends BaseController /** * Add money to piggy bank + * * @param Piggybank $piggybank * * @return $this @@ -109,7 +110,7 @@ class PiggybankController extends BaseController * Flash some data to fill the form. */ $prefilled = ['name' => $piggybank->name, 'account_id' => $piggybank->account_id, 'targetamount' => $piggybank->targetamount, - 'targetdate' => $piggybank->targetdate, 'remind_me' => intval($piggybank->remind_me) == 1 ? true : false]; + 'targetdate' => !is_null($piggybank->targetdate) ? $piggybank->targetdate->format('Y-m-d') : null,'reminder' => $piggybank->reminder, 'remind_me' => intval($piggybank->remind_me) == 1 ? true : false]; Session::flash('prefilled', $prefilled); return View::make('piggybanks.edit', compact('piggybank', 'accounts', 'periods', 'prefilled'))->with('title', 'Piggybanks')->with( @@ -152,6 +153,7 @@ class PiggybankController extends BaseController /** * POST add money to piggy bank + * * @param Piggybank $piggybank * * @return \Illuminate\Http\RedirectResponse @@ -176,7 +178,7 @@ class PiggybankController extends BaseController /* * Create event! */ - Event::fire('piggybank.addMoney',[$piggybank, $amount]); + Event::fire('piggybank.addMoney', [$piggybank, $amount]); Session::flash('success', 'Added ' . mf($amount, false) . ' to "' . e($piggybank->name) . '".'); } else { @@ -205,7 +207,7 @@ class PiggybankController extends BaseController /* * Create event! */ - Event::fire('piggybank.removeMoney',[$piggybank, $amount]); + Event::fire('piggybank.removeMoney', [$piggybank, $amount]); Session::flash('success', 'Removed ' . mf($amount, false) . ' from "' . e($piggybank->name) . '".'); } else { @@ -228,7 +230,21 @@ class PiggybankController extends BaseController public function show(Piggybank $piggybank) { - return View::make('piggybanks.show', compact('piggybank'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc')->with( + $events = $piggybank->piggybankevents()->orderBy('date', 'DESC')->get(); + + /* + * Number of reminders: + */ + $remindersCount = $piggybank->countFutureReminders(); + if ($remindersCount > 0) { + $amountPerReminder = ($piggybank->targetamount - $piggybank->currentRelevantRep()->currentamount) / $remindersCount; + } else { + $amountPerReminder = ($piggybank->targetamount - $piggybank->currentRelevantRep()->currentamount); + } + + return View::make('piggybanks.show', compact('amountPerReminder', 'remindersCount', 'piggybank', 'events'))->with('title', 'Piggy banks')->with( + 'mainTitleIcon', 'fa-sort-amount-asc' + )->with( 'subTitle', $piggybank->name ); @@ -296,7 +312,7 @@ class PiggybankController extends BaseController default: throw new FireflyException('Cannot handle post_submit_action "' . e(Input::get('post_submit_action')) . '"'); break; - case 'create_another': + case 'return_to_edit': case 'update': $messages = $repos->validate($data); /** @var MessageBag $messages ['errors'] */ @@ -311,7 +327,7 @@ class PiggybankController extends BaseController $repos->update($piggyBank, $data); Session::flash('success', 'Piggy bank updated!'); - if ($data['post_submit_action'] == 'create_another') { + if ($data['post_submit_action'] == 'return_to_edit') { return Redirect::route('piggybanks.edit', $piggyBank->id); } else { return Redirect::route('piggybanks.index'); diff --git a/app/lib/FireflyIII/Database/Piggybank.php b/app/lib/FireflyIII/Database/Piggybank.php index 439d26f9de..b54c2c9710 100644 --- a/app/lib/FireflyIII/Database/Piggybank.php +++ b/app/lib/FireflyIII/Database/Piggybank.php @@ -79,10 +79,12 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface $model->reminder_skip = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0; $model->order = isset($data['order']) ? $data['order'] : 0; $model->remind_me = isset($data['remind_me']) ? intval($data['remind_me']) : 0; + $model->reminder = isset($data['reminder']) ? $data['reminder'] : 'month'; if (!$model->validate()) { var_dump($model->errors()); exit(); } + $model->save(); return true; diff --git a/app/lib/FireflyIII/Form/Form.php b/app/lib/FireflyIII/Form/Form.php index 171c0a7d96..a5a30fe4f8 100644 --- a/app/lib/FireflyIII/Form/Form.php +++ b/app/lib/FireflyIII/Form/Form.php @@ -111,6 +111,9 @@ class Form $options['id'] = 'ffInput_' . $name; $options['autocomplete'] = 'off'; $label = self::label($name, $options); + + + /* * Make label and placeholder look nice. */ diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index 194305a829..a41f40b5f9 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -30,9 +30,11 @@ class Date case 'daily': $date->addDays($add); break; + case 'week': case 'weekly': $date->addWeeks($add); break; + case 'month': case 'monthly': $date->addMonths($add); break; diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php index 890e1ea270..172c91c689 100644 --- a/app/models/Piggybank.php +++ b/app/models/Piggybank.php @@ -70,6 +70,20 @@ class Piggybank extends Ardent return $this->belongsTo('Account'); } + public function countFutureReminders() { + /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ + $dateKit = App::make('FireflyIII\Shared\Toolkit\Date'); + + $start = new Carbon; + $end = !is_null($this->targetdate) ? clone $this->targetdate : new Carbon; + $reminders = 0; + while($start <= $end) { + $reminders++; + $start = $dateKit->addPeriod($start, $this->reminder, $this->reminder_skip); + } + return $reminders; + } + public function createRepetition(Carbon $start = null, Carbon $target = null) { $rep = new \PiggybankRepetition; @@ -90,15 +104,16 @@ class Piggybank extends Ardent */ public function currentRelevantRep() { - if($this->currentRep) { + if ($this->currentRep) { return $this->currentRep; } if ($this->repeats == 0) { - $rep = $this->piggybankrepetitions()->first(); + $rep = $this->piggybankrepetitions()->first(); $this->currentRep = $rep; + return $rep; } else { - $query = $this->piggybankrepetitions()->where( + $query = $this->piggybankrepetitions()->where( function ($q) { $q->where( @@ -122,7 +137,7 @@ class Piggybank extends Ardent $q->where('targetdate', '>=', $today->format('Y-m-d')); } )->orderBy('startdate', 'ASC'); - $result = $query->first(); + $result = $query->first(); $this->currentRep = $result; return $result; diff --git a/app/views/list/piggybank-events.blade.php b/app/views/list/piggybank-events.blade.php new file mode 100644 index 0000000000..0493b986c7 --- /dev/null +++ b/app/views/list/piggybank-events.blade.php @@ -0,0 +1,18 @@ + + + + + + @foreach($events as $event) + + + + + @endforeach +
DateAmount
{{$event->date->format('j F Y')}} + @if($event->amount < 0) + Removed {{mf($event->amount*-1,false)}} + @else + Added {{mf($event->amount,false)}} + @endif +
\ No newline at end of file diff --git a/app/views/piggybanks/edit.blade.php b/app/views/piggybanks/edit.blade.php index e8ae4435ac..0f6b179842 100644 --- a/app/views/piggybanks/edit.blade.php +++ b/app/views/piggybanks/edit.blade.php @@ -1,6 +1,6 @@ @extends('layouts.default') @section('content') -{{Form::open(['class' => 'form-horizontal','url' => route('piggybanks.update',$piggybank->id)])}} +{{Form::model($piggybank, ['class' => 'form-horizontal','url' => route('piggybanks.update',$piggybank->id)])}}
@@ -30,7 +30,7 @@
{{Form::ffDate('targetdate')}} {{Form::ffCheckbox('remind_me','1',$prefilled['remind_me'],['label' => 'Remind me'])}} - {{Form::ffSelect('reminder',$periods,'month',['label' => 'Remind every'])}} + {{Form::ffSelect('reminder',$periods,$prefilled['reminder'],['label' => 'Remind every'])}}
diff --git a/app/views/piggybanks/show.blade.php b/app/views/piggybanks/show.blade.php index 813f8ed5db..27a307933d 100644 --- a/app/views/piggybanks/show.blade.php +++ b/app/views/piggybanks/show.blade.php @@ -8,15 +8,29 @@ Events
-
+
-
Details + + +
+
+ + +
+
+
@@ -72,15 +86,23 @@ - + - +
Reminders left12 {{$remindersCount}}
Expected amount per reminder{{mf(0)}} {{mf($amountPerReminder)}}
+
+
+ Table +
+
+ @include('list.piggybank-events') +
+
diff --git a/app/views/recurring/show.blade.php b/app/views/recurring/show.blade.php index a1f229b27d..ff82f65402 100644 --- a/app/views/recurring/show.blade.php +++ b/app/views/recurring/show.blade.php @@ -81,6 +81,7 @@ Chart
+
diff --git a/bootstrap/start.php b/bootstrap/start.php index d476cc0f57..3a43913112 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -100,8 +100,6 @@ Event::subscribe('FireflyIII\Event\Piggybank'); // TODO event for when a transfer gets created and set an associated piggy bank; save as Piggy bank event. // TODO when this transfer gets edited, retro-actively edit the event and THUS also the piggy bank. // TODO event for when a transfer gets deleted; also delete related piggy bank event. -// TODO event for when money is added to a piggy bank. -// TODO event for when money is removed from a piggy bank. // TODO event to create the first repetition (for non-repeating piggy banks) when the piggy bank is created. // TODO event for when the non-repeating piggy bank is updated because the single repetition must also be changed. // (also make piggy bank events "invalid" when they start falling outside of the date-scope of the piggy bank, diff --git a/public/assets/javascript/firefly/recurring.js b/public/assets/javascript/firefly/recurring.js index 5d052dc207..177dada460 100644 --- a/public/assets/javascript/firefly/recurring.js +++ b/public/assets/javascript/firefly/recurring.js @@ -2,9 +2,13 @@ $(document).ready(function () { if (typeof(googleTable) == 'function') { googleTable('table/recurring', 'recurring-table'); + + if (typeof(recurringID) != 'undefined') { + googleTable('table/recurring/' + recurringID + '/transactions', 'transaction-table'); + } } - if (typeof(googleTable) == 'function') { - googleTable('table/recurring/' + recurringID + '/transactions', 'transaction-table'); + if (typeof(googleLineChart) == 'function' && typeof(recurringID) != 'undefined') { + googleLineChart('chart/recurring/' + recurringID, 'recurring-overview'); } } ); \ No newline at end of file From 2d9c89375a9fc89a4b525c8f9b20c5b1b6be491d Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 16 Nov 2014 10:31:19 +0100 Subject: [PATCH 049/193] New chart and lots of stuff for piggy banks --- app/controllers/PiggybankController.php | 2 +- app/controllers/TransactionController.php | 36 +++- ...4_11_15_112449_extend_piggybank_events.php | 33 ++++ app/lib/FireflyIII/Database/Piggybank.php | 19 +- .../Database/TransactionJournal.php | 1 - app/lib/FireflyIII/Event/Piggybank.php | 185 +++++++++++++++++- app/models/PiggybankEvent.php | 8 + app/models/TransactionJournal.php | 8 + app/routes.php | 1 + app/views/list/piggybank-events.blade.php | 9 +- app/views/transactions/show.blade.php | 1 + 11 files changed, 284 insertions(+), 19 deletions(-) create mode 100644 app/database/migrations/2014_11_15_112449_extend_piggybank_events.php diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index e1bca56ab6..f7395fd13f 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -230,7 +230,7 @@ class PiggybankController extends BaseController public function show(Piggybank $piggybank) { - $events = $piggybank->piggybankevents()->orderBy('date', 'DESC')->get(); + $events = $piggybank->piggybankevents()->orderBy('date', 'DESC')->orderBy('id','DESC')->get(); /* * Number of reminders: diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 5e8b103649..77b47374ae 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -100,10 +100,16 @@ class TransactionController extends BaseController { $type = $transactionJournal->transactionType->type; + /* + * Trigger creation of new piggy bank event + */ + Event::fire('piggybank.destroyTransfer', [$transactionJournal]); + /** @var \FireflyIII\Database\TransactionJournal $repository */ $repository = App::make('FireflyIII\Database\TransactionJournal'); $repository->destroy($transactionJournal); + switch ($type) { case 'Withdrawal': return Redirect::route('transactions.index', 'withdrawal'); @@ -126,6 +132,9 @@ class TransactionController extends BaseController */ public function edit(TransactionJournal $journal) { + /* + * TODO the piggybank id must be filled in when relevant. + */ /* * All the repositories we need: */ @@ -199,9 +208,17 @@ class TransactionController extends BaseController $prefilled['amount'] = floatval($journal->transactions[1]->amount); break; case 'transfer': - $prefilled['account_from_id'] = $journal->transactions[1]->account->id; - $prefilled['account_to_id'] = $journal->transactions[0]->account->id; - $prefilled['amount'] = floatval($journal->transactions[1]->amount); + if (floatval($journal->transactions[0]->amount) < 0) { + // zero = from account. + $prefilled['account_from_id'] = $journal->transactions[0]->account->id; + $prefilled['account_to_id'] = $journal->transactions[1]->account->id; + $prefilled['amount'] = floatval($journal->transactions[1]->amount); + } else { + // one = from account + $prefilled['account_from_id'] = $journal->transactions[1]->account->id; + $prefilled['account_to_id'] = $journal->transactions[0]->account->id; + $prefilled['amount'] = floatval($journal->transactions[0]->amount); + } break; } @@ -248,7 +265,7 @@ class TransactionController extends BaseController break; } - return View::make('transactions.index', compact('subTitle', 'subTitleIcon','journals'))->with('what', $what); + return View::make('transactions.index', compact('subTitle', 'subTitleIcon', 'journals'))->with('what', $what); } @@ -295,9 +312,17 @@ class TransactionController extends BaseController return Redirect::route('transactions.create', $what)->withInput()->withErrors($messages['errors']); } // store! - $repository->store($data); + $journal = $repository->store($data); Session::flash('success', 'New transaction stored!'); + /* + * Trigger a search for the related (if selected) + * piggy bank and store an event. + */ + if (!is_null(Input::get('piggybank_id')) && intval(Input::get('piggybank_id')) > 0) { + Event::fire('piggybank.createTransfer', [$journal, intval(Input::get('piggybank_id'))]); + } + if ($data['post_submit_action'] == 'create_another') { return Redirect::route('transactions.create', $what)->withInput(); } else { @@ -339,6 +364,7 @@ class TransactionController extends BaseController // has been saved, return to index: Session::flash('success', 'Transaction updated!'); // Event::fire('journals.update', [$journal]); + Event::fire('piggybank.updateTransfer', [$journal]); if (Input::get('post_submit_action') == 'return_to_edit') { return Redirect::route('transactions.edit', $journal->id)->withInput(); diff --git a/app/database/migrations/2014_11_15_112449_extend_piggybank_events.php b/app/database/migrations/2014_11_15_112449_extend_piggybank_events.php new file mode 100644 index 0000000000..c92d1f0343 --- /dev/null +++ b/app/database/migrations/2014_11_15_112449_extend_piggybank_events.php @@ -0,0 +1,33 @@ +integer('transaction_journal_id')->unsigned()->nullable(); + $table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('set null'); + } + ); + } + +} diff --git a/app/lib/FireflyIII/Database/Piggybank.php b/app/lib/FireflyIII/Database/Piggybank.php index b54c2c9710..491ff71ba2 100644 --- a/app/lib/FireflyIII/Database/Piggybank.php +++ b/app/lib/FireflyIII/Database/Piggybank.php @@ -2,6 +2,7 @@ namespace FireflyIII\Database; use Carbon\Carbon; +use Firefly\Exception\FireflyException; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\PiggybankInterface; @@ -196,8 +197,10 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface */ public function find($id) { - // TODO: Implement find() method. - throw new NotImplementedException; + return \Piggybank:: + leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id') + ->where('piggybanks.id','=',$id) + ->where('accounts.user_id', $this->getUser()->id)->first(['piggybanks.*']); } /** @@ -234,6 +237,18 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface throw new NotImplementedException; } + public function findRepetitionByDate(\Piggybank $piggybank, Carbon $date) + { + $reps = $piggybank->piggybankrepetitions()->get(); + if ($reps->count() == 1) { + return $reps->first(); + } + if ($reps->count() == 0) { + throw new FireflyException('Should always find a piggy bank repetition.'); + } + throw new NotImplementedException; + } + /** * @param \Account $account * diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 2367a18ad0..0f4a145a06 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -164,7 +164,6 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData */ public function update(Ardent $model, array $data) { - var_dump($data); /** @var \FireflyIII\Database\TransactionType $typeRepository */ $typeRepository = \App::make('FireflyIII\Database\TransactionType'); diff --git a/app/lib/FireflyIII/Event/Piggybank.php b/app/lib/FireflyIII/Event/Piggybank.php index 0a2da1922b..d946cc3bd8 100644 --- a/app/lib/FireflyIII/Event/Piggybank.php +++ b/app/lib/FireflyIII/Event/Piggybank.php @@ -6,19 +6,21 @@ namespace FireflyIII\Event; use Carbon\Carbon; use Illuminate\Events\Dispatcher; -class Piggybank { +class Piggybank +{ /** * @param \Piggybank $piggybank * @param float $amount */ - public function addMoney(\Piggybank $piggybank, $amount = 0.0) { - if($amount > 0) { + public function addMoney(\Piggybank $piggybank, $amount = 0.0) + { + if ($amount > 0) { $event = new \PiggybankEvent; $event->piggybank()->associate($piggybank); $event->amount = floatval($amount); - $event->date = new Carbon; - if(!$event->validate()) { + $event->date = new Carbon; + if (!$event->validate()) { var_dump($event->errors()); exit(); } @@ -26,18 +28,130 @@ class Piggybank { } } + /** + * @param \TransactionJournal $journal + * @param int $piggybankId + */ + public function createTransfer(\TransactionJournal $journal, $piggybankId = 0) + { + /** @var \FireflyIII\Database\Piggybank $repository */ + $repository = \App::make('FireflyIII\Database\Piggybank'); + + /** @var \Piggybank $piggyBank */ + $piggyBank = $repository->find($piggybankId); + + /** @var \PiggybankRepetition $repetition */ + $repetition = $repository->findRepetitionByDate($piggyBank, $journal->date); + + \Log::debug( + 'Connecting transfer "' . $journal->description . '" (#' . $journal->id . ') to piggy bank "' . $piggyBank->name . '" (#' . $piggyBank->id . ').' + ); + + // some variables to double check the connection. + $start = $piggyBank->startdate; + $end = $piggyBank->targetdate; + $amount = floatval($piggyBank->targetamount); + $leftToSave = $amount - floatval($repetition->currentamount); + $relevantTransaction = null; + /** @var \Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + if ($transaction->account_id == $piggyBank->account_id) { + $relevantTransaction = $transaction; + } + } + if (is_null($relevantTransaction)) { + return; + } + \Log::debug('Relevant transaction is #' . $relevantTransaction->id . ' with amount ' . $relevantTransaction->amount); + + // if FF3 should save this connection depends on some variables: + if ($start && $end && $journal->date >= $start && $journal->date <= $end) { + if ($relevantTransaction->amount < 0) { // amount removed from account, so removed from piggy bank. + \Log::debug('Remove from piggy bank.'); + $continue = ($relevantTransaction->amount * -1 <= floatval($repetition->currentamount)); + \Log::debug( + 'relevantTransaction.amount *-1 = ' . ($relevantTransaction->amount * -1) . ' >= current = ' . floatval($repetition->currentamount) + ); + } else { // amount added + \Log::debug('Add from piggy bank.'); + $continue = $relevantTransaction->amount <= $leftToSave; + } + if ($continue) { + \Log::debug('Update repetition.'); + $repetition->currentamount += floatval($relevantTransaction->amount); + $repetition->save(); + + $event = new \PiggybankEvent; + $event->piggybank()->associate($piggyBank); + $event->transactionjournal()->associate($journal); + $event->amount = floatval($relevantTransaction->amount); + $event->date = new Carbon; + if (!$event->validate()) { + var_dump($event->errors()); + exit(); + } + $event->save(); + } + } + } + + public function destroyTransfer(\TransactionJournal $journal) + { + if ($journal->piggybankevents()->count() > 0) { + + /** @var \FireflyIII\Database\Piggybank $repository */ + $repository = \App::make('FireflyIII\Database\Piggybank'); + + /** @var \Piggybank $piggyBank */ + $piggyBank = $journal->piggybankevents()->first()->piggybank()->first(); + + /** @var \PiggybankRepetition $repetition */ + $repetition = $repository->findRepetitionByDate($piggyBank, $journal->date); + + $relevantTransaction = null; + /** @var \Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + if ($transaction->account_id == $piggyBank->account_id) { + $relevantTransaction = $transaction; + } + } + if (is_null($relevantTransaction)) { + return; + } + + $repetition->currentamount += floatval($relevantTransaction->amount * -1); + $repetition->save(); + + + $event = new \PiggybankEvent; + $event->piggybank()->associate($piggyBank); + $event->amount = floatval($relevantTransaction->amount * -1); + $event->date = new Carbon; + if (!$event->validate()) { + var_dump($event->errors()); + exit(); + } + $event->save(); + } + } + + /* + * + */ + /** * @param \Piggybank $piggybank * @param float $amount */ - public function removeMoney(\Piggybank $piggybank, $amount = 0.0) { + public function removeMoney(\Piggybank $piggybank, $amount = 0.0) + { $amount = $amount * -1; - if($amount < 0) { + if ($amount < 0) { $event = new \PiggybankEvent; $event->piggybank()->associate($piggybank); $event->amount = floatval($amount); - $event->date = new Carbon; - if(!$event->validate()) { + $event->date = new Carbon; + if (!$event->validate()) { var_dump($event->errors()); exit(); } @@ -52,5 +166,58 @@ class Piggybank { { $events->listen('piggybank.addMoney', 'FireflyIII\Event\Piggybank@addMoney'); $events->listen('piggybank.removeMoney', 'FireflyIII\Event\Piggybank@removeMoney'); + $events->listen('piggybank.createTransfer', 'FireflyIII\Event\Piggybank@createTransfer'); + $events->listen('piggybank.destroyTransfer', 'FireflyIII\Event\Piggybank@destroyTransfer'); + $events->listen('piggybank.updateTransfer', 'FireflyIII\Event\Piggybank@updateTransfer'); + } + + public function updateTransfer(\TransactionJournal $journal) + { + + if ($journal->piggybankevents()->count() > 0) { + + $event = $journal->piggybankevents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->first(); + $eventSum = floatval($journal->piggybankevents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->sum('amount')); + + /** @var \FireflyIII\Database\Piggybank $repository */ + $repository = \App::make('FireflyIII\Database\Piggybank'); + + /** @var \Piggybank $piggyBank */ + $piggyBank = $journal->piggybankevents()->first()->piggybank()->first(); + + /** @var \PiggybankRepetition $repetition */ + $repetition = $repository->findRepetitionByDate($piggyBank, $journal->date); + + $relevantTransaction = null; + /** @var \Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + if ($transaction->account_id == $piggyBank->account_id) { + $relevantTransaction = $transaction; + } + } + if (is_null($relevantTransaction)) { + return; + } + + $diff = floatval($relevantTransaction->amount) - floatval($eventSum); + /* + * Create an event to remove /add the difference from the piggy + */ + $repetition->currentamount += $diff; + $repetition->save(); + + + $event = new \PiggybankEvent; + $event->piggybank()->associate($piggyBank); + $event->transactionJournal()->associate($journal); + $event->amount = $diff; + $event->date = new Carbon; + if (!$event->validate()) { + var_dump($event->errors()); + exit(); + } + $event->save(); + } + } } \ No newline at end of file diff --git a/app/models/PiggybankEvent.php b/app/models/PiggybankEvent.php index ceb3c1bf91..b33a8567cc 100644 --- a/app/models/PiggybankEvent.php +++ b/app/models/PiggybankEvent.php @@ -41,4 +41,12 @@ class PiggybankEvent extends Ardent return $this->belongsTo('Piggybank'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function transactionJournal() + { + return $this->belongsTo('TransactionJournal'); + } + } \ No newline at end of file diff --git a/app/models/TransactionJournal.php b/app/models/TransactionJournal.php index 94eb8318e6..b996cb2d69 100644 --- a/app/models/TransactionJournal.php +++ b/app/models/TransactionJournal.php @@ -138,6 +138,14 @@ class TransactionJournal extends Ardent return $query->where('date', '>=', $date->format('Y-m-d')); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function piggybankevents() + { + return $this->hasMany('PiggybankEvent'); + } + /** * @param $query * @param Carbon $date diff --git a/app/routes.php b/app/routes.php index 0f39b634aa..1400d74167 100644 --- a/app/routes.php +++ b/app/routes.php @@ -154,6 +154,7 @@ Route::group( Route::get('/chart/sankey/{account}/in', ['uses' => 'GoogleChartController@accountSankeyInChart']); Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']); Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']); + Route::get('/chart/recurring/{recurring}', ['uses' => 'GoogleChartController@recurringOverview']); Route::get('/chart/reports/budgets/{year}', ['uses' => 'GoogleChartController@budgetsReportChart']); Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'GoogleChartController@budgetLimitSpending']); diff --git a/app/views/list/piggybank-events.blade.php b/app/views/list/piggybank-events.blade.php index 0493b986c7..dfba52ee4f 100644 --- a/app/views/list/piggybank-events.blade.php +++ b/app/views/list/piggybank-events.blade.php @@ -5,7 +5,14 @@ @foreach($events as $event) - {{$event->date->format('j F Y')}} + + @if(!is_null($event->transaction_journal_id)) + {{$event->date->format('j F Y')}} + @else + {{$event->date->format('j F Y')}} + @endif + + @if($event->amount < 0) Removed {{mf($event->amount*-1,false)}} diff --git a/app/views/transactions/show.blade.php b/app/views/transactions/show.blade.php index d1b904bb60..f13a0b65c5 100644 --- a/app/views/transactions/show.blade.php +++ b/app/views/transactions/show.blade.php @@ -40,6 +40,7 @@ @endforeach +
From 8c254554eb28cb46eff9e4716e14af8c2f0ef13b Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 16 Nov 2014 10:36:23 +0100 Subject: [PATCH 050/193] Display bug for piggy banks with no reminders. --- app/models/Piggybank.php | 4 ++++ app/views/piggybanks/show.blade.php | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php index 172c91c689..623d82f74d 100644 --- a/app/models/Piggybank.php +++ b/app/models/Piggybank.php @@ -74,6 +74,10 @@ class Piggybank extends Ardent /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ $dateKit = App::make('FireflyIII\Shared\Toolkit\Date'); + if(is_null($this->reminder)) { + return 0; + } + $start = new Carbon; $end = !is_null($this->targetdate) ? clone $this->targetdate : new Carbon; $reminders = 0; diff --git a/app/views/piggybanks/show.blade.php b/app/views/piggybanks/show.blade.php index 27a307933d..1d23179eda 100644 --- a/app/views/piggybanks/show.blade.php +++ b/app/views/piggybanks/show.blade.php @@ -70,6 +70,7 @@ @endif + @if(!is_null($piggybank->reminder)) Reminder @@ -84,14 +85,17 @@ @endif - - Reminders left - {{$remindersCount}} - - - Expected amount per reminder - {{mf($amountPerReminder)}} - + @endif + @if($remindersCount > 0) + + Reminders left + {{$remindersCount}} + + + Expected amount per reminder + {{mf($amountPerReminder)}} + + @endif
From fb0d463040ba207f1004f8e3845871b2fd33da22 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 16 Nov 2014 20:03:53 +0100 Subject: [PATCH 051/193] Chart for piggy banks --- app/controllers/GoogleChartController.php | 25 ++++++++++++++++++- app/views/piggybanks/show.blade.php | 9 +++++++ .../assets/javascript/firefly/piggybanks.js | 12 ++++++--- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index 464e24e20e..8e9456aa6d 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -473,6 +473,29 @@ class GoogleChartController extends BaseController } + public function piggyBankHistory(\Piggybank $piggybank) + { + /** @var \Grumpydictator\Gchart\GChart $chart */ + $chart = App::make('gchart'); + $chart->addColumn('Date', 'date'); + $chart->addColumn('Balance', 'number'); + $sum = 0; + + $set = \DB::table('piggybank_events') + ->where('piggybank_id',$piggybank->id) + ->groupBy('date') + ->get(['date',DB::Raw('SUM(`amount`) AS `sum`')]); + + foreach($set as $entry) { + $chart->addRow(new Carbon($entry->date), floatval($entry->sum)); + } + + $chart->generate(); + + return Response::json($chart->getData()); + + } + /** * @param RecurringTransaction $recurring */ @@ -499,7 +522,7 @@ class GoogleChartController extends BaseController $end = new Carbon; while ($start <= $end) { $result = $recurring->transactionjournals()->before($end)->after($start)->first(); - if($result) { + if ($result) { $amount = $result->getAmount(); } else { $amount = 0; diff --git a/app/views/piggybanks/show.blade.php b/app/views/piggybanks/show.blade.php index 1d23179eda..33daa08e89 100644 --- a/app/views/piggybanks/show.blade.php +++ b/app/views/piggybanks/show.blade.php @@ -113,4 +113,13 @@ @stop @section('scripts') + + + + +{{HTML::script('assets/javascript/firefly/gcharts.options.js')}} +{{HTML::script('assets/javascript/firefly/gcharts.js')}} +{{HTML::script('assets/javascript/firefly/piggybanks.js')}} @stop diff --git a/public/assets/javascript/firefly/piggybanks.js b/public/assets/javascript/firefly/piggybanks.js index 3d4d4739c0..f97c71339f 100644 --- a/public/assets/javascript/firefly/piggybanks.js +++ b/public/assets/javascript/firefly/piggybanks.js @@ -1,17 +1,21 @@ $(function () { - $('.addMoney').on('click',addMoney); - $('.removeMoney').on('click',removeMoney); + $('.addMoney').on('click', addMoney); + $('.removeMoney').on('click', removeMoney); + + if (typeof(googleLineChart) == 'function' && typeof(piggyBankID) != 'undefined') { + googleLineChart('chart/piggyhistory/' + piggyBankID, 'piggybank-history'); + } }); function addMoney(e) { - var pigID = parseInt($(e.target).data('id')); + var pigID = parseInt($(e.target).data('id')); $('#moneyManagementModal').empty().load('piggybanks/add/' + pigID).modal('show'); return false; } function removeMoney(e) { - var pigID = parseInt($(e.target).data('id')); + var pigID = parseInt($(e.target).data('id')); $('#moneyManagementModal').empty().load('piggybanks/remove/' + pigID).modal('show'); return false; From 651101912c6740fad4290476d7fa8157d1238d7b Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 16 Nov 2014 20:05:03 +0100 Subject: [PATCH 052/193] Route for chart. --- app/routes.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/routes.php b/app/routes.php index 1400d74167..1e1975d34a 100644 --- a/app/routes.php +++ b/app/routes.php @@ -157,6 +157,7 @@ Route::group( Route::get('/chart/recurring/{recurring}', ['uses' => 'GoogleChartController@recurringOverview']); Route::get('/chart/reports/budgets/{year}', ['uses' => 'GoogleChartController@budgetsReportChart']); Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'GoogleChartController@budgetLimitSpending']); + Route::get('/chart/piggyhistory/{piggybank}',['uses' => 'GoogleChartController@piggyBankHistory']); // google chart for components (categories + budgets combined) Route::get('/chart/component/{component}/spending/{year}', ['uses' => 'GoogleChartController@componentsAndSpending']); From 82c9a75578f45376fa20c22056160f9f767e2a2e Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 16 Nov 2014 22:55:34 +0100 Subject: [PATCH 053/193] Expand piggy banks --- app/controllers/PiggybankController.php | 8 +- app/controllers/TransactionController.php | 2 +- app/lib/FireflyIII/Database/Piggybank.php | 3 +- app/lib/FireflyIII/Event/Piggybank.php | 138 +++++++++++---------- app/views/list/piggybank-events.blade.php | 8 ++ app/views/transactions/show.blade.php | 140 +++++++++++++--------- 6 files changed, 173 insertions(+), 126 deletions(-) diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index f7395fd13f..e8460051a2 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -276,7 +276,13 @@ class PiggybankController extends BaseController return Redirect::route('piggybanks.create')->withInput()->withErrors($messages['errors']); } // store! - $repos->store($data); + $piggyBank = $repos->store($data); + + /* + * Create the relevant repetition per Event. + */ + Event::fire('piggybank.storePiggybank',[$piggyBank]); + Session::flash('success', 'New piggy bank stored!'); if ($data['post_submit_action'] == 'create_another') { diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 77b47374ae..abc61a94aa 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -320,7 +320,7 @@ class TransactionController extends BaseController * piggy bank and store an event. */ if (!is_null(Input::get('piggybank_id')) && intval(Input::get('piggybank_id')) > 0) { - Event::fire('piggybank.createTransfer', [$journal, intval(Input::get('piggybank_id'))]); + Event::fire('piggybank.storeTransfer', [$journal, intval(Input::get('piggybank_id'))]); } if ($data['post_submit_action'] == 'create_another') { diff --git a/app/lib/FireflyIII/Database/Piggybank.php b/app/lib/FireflyIII/Database/Piggybank.php index 491ff71ba2..804dcc307c 100644 --- a/app/lib/FireflyIII/Database/Piggybank.php +++ b/app/lib/FireflyIII/Database/Piggybank.php @@ -59,8 +59,7 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface exit; } $piggybank->save(); - \Event::fire('piggybanks.store', [$piggybank]); - $piggybank->save(); + return $piggybank; } /** diff --git a/app/lib/FireflyIII/Event/Piggybank.php b/app/lib/FireflyIII/Event/Piggybank.php index d946cc3bd8..d881b0ece2 100644 --- a/app/lib/FireflyIII/Event/Piggybank.php +++ b/app/lib/FireflyIII/Event/Piggybank.php @@ -28,11 +28,75 @@ class Piggybank } } + public function destroyTransfer(\TransactionJournal $journal) + { + if ($journal->piggybankevents()->count() > 0) { + + /** @var \FireflyIII\Database\Piggybank $repository */ + $repository = \App::make('FireflyIII\Database\Piggybank'); + + /** @var \Piggybank $piggyBank */ + $piggyBank = $journal->piggybankevents()->first()->piggybank()->first(); + + /** @var \PiggybankRepetition $repetition */ + $repetition = $repository->findRepetitionByDate($piggyBank, $journal->date); + + $relevantTransaction = null; + /** @var \Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + if ($transaction->account_id == $piggyBank->account_id) { + $relevantTransaction = $transaction; + } + } + if (is_null($relevantTransaction)) { + return; + } + + $repetition->currentamount += floatval($relevantTransaction->amount * -1); + $repetition->save(); + + + $event = new \PiggybankEvent; + $event->piggybank()->associate($piggyBank); + $event->amount = floatval($relevantTransaction->amount * -1); + $event->date = new Carbon; + if (!$event->validate()) { + var_dump($event->errors()); + exit(); + } + $event->save(); + } + } + + /** + * @param \Piggybank $piggybank + * @param float $amount + */ + public function removeMoney(\Piggybank $piggybank, $amount = 0.0) + { + $amount = $amount * -1; + if ($amount < 0) { + $event = new \PiggybankEvent; + $event->piggybank()->associate($piggybank); + $event->amount = floatval($amount); + $event->date = new Carbon; + if (!$event->validate()) { + var_dump($event->errors()); + exit(); + } + $event->save(); + } + } + + /* + * + */ + /** * @param \TransactionJournal $journal * @param int $piggybankId */ - public function createTransfer(\TransactionJournal $journal, $piggybankId = 0) + public function storeTransfer(\TransactionJournal $journal, $piggybankId = 0) { /** @var \FireflyIII\Database\Piggybank $repository */ $repository = \App::make('FireflyIII\Database\Piggybank'); @@ -95,67 +159,14 @@ class Piggybank } } - public function destroyTransfer(\TransactionJournal $journal) - { - if ($journal->piggybankevents()->count() > 0) { - - /** @var \FireflyIII\Database\Piggybank $repository */ - $repository = \App::make('FireflyIII\Database\Piggybank'); - - /** @var \Piggybank $piggyBank */ - $piggyBank = $journal->piggybankevents()->first()->piggybank()->first(); - - /** @var \PiggybankRepetition $repetition */ - $repetition = $repository->findRepetitionByDate($piggyBank, $journal->date); - - $relevantTransaction = null; - /** @var \Transaction $transaction */ - foreach ($journal->transactions as $transaction) { - if ($transaction->account_id == $piggyBank->account_id) { - $relevantTransaction = $transaction; - } - } - if (is_null($relevantTransaction)) { - return; - } - - $repetition->currentamount += floatval($relevantTransaction->amount * -1); + public function storePiggybank(\Piggybank $piggybank) { + if(intval($piggybank->repeats) == 0) { + $repetition = new \PiggybankRepetition; + $repetition->piggybank()->associate($piggybank); + $repetition->startdate = $piggybank->startdate; + $repetition->targetdate = $piggybank->targetdate; + $repetition->currentamount = 0; $repetition->save(); - - - $event = new \PiggybankEvent; - $event->piggybank()->associate($piggyBank); - $event->amount = floatval($relevantTransaction->amount * -1); - $event->date = new Carbon; - if (!$event->validate()) { - var_dump($event->errors()); - exit(); - } - $event->save(); - } - } - - /* - * - */ - - /** - * @param \Piggybank $piggybank - * @param float $amount - */ - public function removeMoney(\Piggybank $piggybank, $amount = 0.0) - { - $amount = $amount * -1; - if ($amount < 0) { - $event = new \PiggybankEvent; - $event->piggybank()->associate($piggybank); - $event->amount = floatval($amount); - $event->date = new Carbon; - if (!$event->validate()) { - var_dump($event->errors()); - exit(); - } - $event->save(); } } @@ -166,7 +177,8 @@ class Piggybank { $events->listen('piggybank.addMoney', 'FireflyIII\Event\Piggybank@addMoney'); $events->listen('piggybank.removeMoney', 'FireflyIII\Event\Piggybank@removeMoney'); - $events->listen('piggybank.createTransfer', 'FireflyIII\Event\Piggybank@createTransfer'); + $events->listen('piggybank.storeTransfer', 'FireflyIII\Event\Piggybank@storeTransfer'); + $events->listen('piggybank.storePiggybank', 'FireflyIII\Event\Piggybank@storePiggybank'); $events->listen('piggybank.destroyTransfer', 'FireflyIII\Event\Piggybank@destroyTransfer'); $events->listen('piggybank.updateTransfer', 'FireflyIII\Event\Piggybank@updateTransfer'); } @@ -176,7 +188,7 @@ class Piggybank if ($journal->piggybankevents()->count() > 0) { - $event = $journal->piggybankevents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->first(); + $event = $journal->piggybankevents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->first(); $eventSum = floatval($journal->piggybankevents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->sum('amount')); /** @var \FireflyIII\Database\Piggybank $repository */ diff --git a/app/views/list/piggybank-events.blade.php b/app/views/list/piggybank-events.blade.php index dfba52ee4f..e80ddc4c61 100644 --- a/app/views/list/piggybank-events.blade.php +++ b/app/views/list/piggybank-events.blade.php @@ -1,10 +1,18 @@ + @if(isset($showPiggybank) && $showPiggybank === true) + + @endif @foreach($events as $event) + @if(isset($showPiggybank) && $showPiggybank === true) + + @endif
Piggy bankDate Amount
+ {{{$event->piggybank->name}}} + @if(!is_null($event->transaction_journal_id)) {{$event->date->format('j F Y')}} diff --git a/app/views/transactions/show.blade.php b/app/views/transactions/show.blade.php index f13a0b65c5..b4c3eb5414 100644 --- a/app/views/transactions/show.blade.php +++ b/app/views/transactions/show.blade.php @@ -2,71 +2,93 @@ @section('content')
-

Metadata

- - - - - - - - - - - - - - - - - - @foreach($journal->budgets()->get() as $budget) - - - - - @endforeach - @foreach($journal->categories()->get() as $category) - - - - - @endforeach +
+
+ Metadata +
+
+
Date{{{$journal->date->format('jS F Y')}}}
Currency{{{$journal->transactioncurrency->code}}}
Type{{{$journal->transactiontype->type}}}
Completed - @if($journal->completed == 1) - Yes - @else - No - @endif -
{{$budget->class}}{{{$budget->name}}}
{{$category->class}}{{{$category->name}}}
+ + + + + + + + + + + + + + + + + @foreach($journal->budgets()->get() as $budget) + + + + + @endforeach + @foreach($journal->categories()->get() as $category) + + + + + @endforeach -
Date{{{$journal->date->format('jS F Y')}}}
Currency{{{$journal->transactioncurrency->code}}}
Type{{{$journal->transactiontype->type}}}
Completed + @if($journal->completed == 1) + Yes + @else + No + @endif +
{{$budget->class}}{{{$budget->name}}}
{{$category->class}}{{{$category->name}}}
- +
+
+
+ + @if(count($journal->piggybankevents) > 0) +
+
+ Piggy banks +
+
+ @include('list.piggybank-events',['events' => $journal->piggybankevents,'showPiggybank' => true]) +
+
+ + @endif
-
-

Transactions

- @foreach($journal->transactions as $t) -

{{{$t->account->name}}}
{{{$t->account->accounttype->description}}}

- - - - - - - - - - @if(!is_null($t->description)) - - - - - @endif -
Amount{{mf($t->amount)}}
New balance{{mf($t->account->balanceBeforeJournal($journal))}} → {{mf($t->account->balanceBeforeJournal($journal) + $t->amount)}}
Description{{{$t->description}}}
- @endforeach + @foreach($journal->transactions as $t) +
+
+ {{{$t->account->name}}}
{{{$t->account->accounttype->description}}} +
+
+ + + + + + + + + + @if(!is_null($t->description)) + + + + + @endif +
Amount{{mf($t->amount)}}
New balance{{mf($t->account->balanceBeforeJournal($journal))}} → {{mf($t->account->balanceBeforeJournal($journal) + $t->amount)}}
Description{{{$t->description}}}
+
+
+ @endforeach
+
From 314abbea8b44cc5c94cbbc01ac49dd91e166ac57 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 17 Nov 2014 07:33:18 +0100 Subject: [PATCH 054/193] Code cleanup. --- app/controllers/AccountController.php | 28 ++-- app/controllers/BudgetController.php | 4 +- app/controllers/CategoryController.php | 9 +- app/controllers/GoogleChartController.php | 7 +- app/controllers/PiggybankController.php | 7 +- app/controllers/RecurringController.php | 3 +- app/lib/FireflyIII/Database/Account.php | 4 +- app/lib/FireflyIII/Database/Budget.php | 6 +- app/lib/FireflyIII/Database/Category.php | 7 +- .../Database/Ifaces/RecurringInterface.php | 16 +-- app/lib/FireflyIII/Database/Piggybank.php | 6 +- .../Database/TransactionJournal.php | 76 ++++++----- app/lib/FireflyIII/Event/Piggybank.php | 23 ++-- app/lib/FireflyIII/Form/Form.php | 123 +++++++++--------- app/lib/FireflyIII/Shared/Toolkit/Date.php | 1 + app/models/Account.php | 59 ++++----- app/models/AccountMeta.php | 1 + app/models/AccountType.php | 21 +-- app/models/Budget.php | 30 ++--- app/models/Category.php | 56 ++++---- app/models/Component.php | 31 ++--- app/models/Importentry.php | 29 +++-- app/models/Importmap.php | 27 ++-- app/models/Limit.php | 37 +++--- app/models/LimitRepetition.php | 39 +++--- app/models/Piggybank.php | 83 ++++++------ app/models/PiggybankEvent.php | 28 ++-- app/models/PiggybankRepetition.php | 29 +++-- app/models/Preference.php | 23 ++-- app/models/RecurringTransaction.php | 75 ++++++----- app/models/Reminder.php | 26 ++-- app/models/Transaction.php | 55 ++++---- app/models/TransactionCurrency.php | 17 +-- app/models/TransactionJournal.php | 88 +++++++------ app/models/TransactionType.php | 16 +-- app/models/User.php | 44 +++---- app/start/global.php | 5 +- bootstrap/paths.php | 4 +- bootstrap/start.php | 8 +- 39 files changed, 593 insertions(+), 558 deletions(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 8844503c13..427a40e561 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -46,8 +46,8 @@ class AccountController extends BaseController public function delete(Account $account) { return View::make('accounts.delete')->with('account', $account)->with( - 'subTitle', 'Delete ' . strtolower($account->accountType->type) . ' "' . $account->name . '"' - ); + 'subTitle', 'Delete ' . strtolower($account->accountType->type) . ' "' . $account->name . '"' + ); } /** @@ -158,10 +158,10 @@ class AccountController extends BaseController } return View::make('accounts.edit')->with('account', $account)->with('openingBalance', $openingBalance)->with(compact('subTitleIcon'))->with( - 'subTitle', 'Edit ' . strtolower( - $account->accountType->type - ) . ' "' . $account->name . '"' - ); + 'subTitle', 'Edit ' . strtolower( + $account->accountType->type + ) . ' "' . $account->name . '"' + ); } /** @@ -182,21 +182,21 @@ class AccountController extends BaseController case 'asset': $subTitleIcon = 'fa-money'; $subTitle = 'Asset accounts'; - $accounts = $acct->getAssetAccounts(); + $accounts = $acct->getAssetAccounts(); break; case 'expense': $subTitleIcon = 'fa-shopping-cart'; $subTitle = 'Expense accounts'; - $accounts = $acct->getExpenseAccounts(); + $accounts = $acct->getExpenseAccounts(); break; case 'revenue': $subTitleIcon = 'fa-download'; $subTitle = 'Revenue accounts'; - $accounts = $acct->getRevenueAccounts(); + $accounts = $acct->getRevenueAccounts(); break; } - return View::make('accounts.index',compact('what','subTitleIcon','subTitle','accounts')); + return View::make('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts')); } /** @@ -228,9 +228,9 @@ class AccountController extends BaseController //$data = $this->_accounts->show($account, 40); - return View::make('accounts.show',compact('account','subTitleIcon','journals'))->with('account', $account)->with( - 'subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"' - ); + return View::make('accounts.show', compact('account', 'subTitleIcon', 'journals'))->with('account', $account)->with( + 'subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"' + ); } /** @@ -240,7 +240,7 @@ class AccountController extends BaseController public function store() { - $data = Input::all(); + $data = Input::all(); $data['what'] = isset($data['what']) && $data['what'] != '' ? $data['what'] : 'asset'; /** @var \FireflyIII\Database\Account $acct */ $acct = App::make('FireflyIII\Database\Account'); diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php index 0e7de74c14..c4617ffde5 100644 --- a/app/controllers/BudgetController.php +++ b/app/controllers/BudgetController.php @@ -206,13 +206,13 @@ class BudgetController extends BaseController $limits = [$repetition->limit]; // get all transaction journals for this budget and limit repetition. $journals = []; - $subTitle = $budget->name.' in ' . $repetition->startdate->format('F Y'); + $subTitle = $budget->name . ' in ' . $repetition->startdate->format('F Y'); $journals = $repos->getTransactionJournalsInRepetition($budget, $repetition, 50); } $hideBudget = true; - return View::make('budgets.show', compact('limits', 'budget', 'repetition', 'journals','subTitle','hideBudget')); + return View::make('budgets.show', compact('limits', 'budget', 'repetition', 'journals', 'subTitle', 'hideBudget')); } /** diff --git a/app/controllers/CategoryController.php b/app/controllers/CategoryController.php index ec05e23798..200a2fc2c0 100644 --- a/app/controllers/CategoryController.php +++ b/app/controllers/CategoryController.php @@ -66,9 +66,10 @@ class CategoryController extends BaseController public function index() { /** @var \FireflyIII\Database\Category $repos */ - $repos = App::make('FireflyIII\Database\Category'); + $repos = App::make('FireflyIII\Database\Category'); $categories = $repos->get(); - return View::make('categories.index',compact('categories')); + + return View::make('categories.index', compact('categories')); } /** @@ -85,7 +86,7 @@ class CategoryController extends BaseController $journals = $repos->getTransactionJournals($category, 50); - return View::make('categories.show', compact('category','journals','hideCategory')); + return View::make('categories.show', compact('category', 'journals', 'hideCategory')); } /** @@ -93,7 +94,7 @@ class CategoryController extends BaseController */ public function store() { - $data = Input::all(); + $data = Input::all(); /** @var \FireflyIII\Database\Category $repos */ $repos = App::make('FireflyIII\Database\Category'); diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index 8e9456aa6d..a822f6deca 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -481,12 +481,9 @@ class GoogleChartController extends BaseController $chart->addColumn('Balance', 'number'); $sum = 0; - $set = \DB::table('piggybank_events') - ->where('piggybank_id',$piggybank->id) - ->groupBy('date') - ->get(['date',DB::Raw('SUM(`amount`) AS `sum`')]); + $set = \DB::table('piggybank_events')->where('piggybank_id', $piggybank->id)->groupBy('date')->get(['date', DB::Raw('SUM(`amount`) AS `sum`')]); - foreach($set as $entry) { + foreach ($set as $entry) { $chart->addRow(new Carbon($entry->date), floatval($entry->sum)); } diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index e8460051a2..60f030519d 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -110,7 +110,8 @@ class PiggybankController extends BaseController * Flash some data to fill the form. */ $prefilled = ['name' => $piggybank->name, 'account_id' => $piggybank->account_id, 'targetamount' => $piggybank->targetamount, - 'targetdate' => !is_null($piggybank->targetdate) ? $piggybank->targetdate->format('Y-m-d') : null,'reminder' => $piggybank->reminder, 'remind_me' => intval($piggybank->remind_me) == 1 ? true : false]; + 'targetdate' => !is_null($piggybank->targetdate) ? $piggybank->targetdate->format('Y-m-d') : null, 'reminder' => $piggybank->reminder, + 'remind_me' => intval($piggybank->remind_me) == 1 ? true : false]; Session::flash('prefilled', $prefilled); return View::make('piggybanks.edit', compact('piggybank', 'accounts', 'periods', 'prefilled'))->with('title', 'Piggybanks')->with( @@ -230,7 +231,7 @@ class PiggybankController extends BaseController public function show(Piggybank $piggybank) { - $events = $piggybank->piggybankevents()->orderBy('date', 'DESC')->orderBy('id','DESC')->get(); + $events = $piggybank->piggybankevents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->get(); /* * Number of reminders: @@ -281,7 +282,7 @@ class PiggybankController extends BaseController /* * Create the relevant repetition per Event. */ - Event::fire('piggybank.storePiggybank',[$piggyBank]); + Event::fire('piggybank.storePiggybank', [$piggyBank]); Session::flash('success', 'New piggy bank stored!'); diff --git a/app/controllers/RecurringController.php b/app/controllers/RecurringController.php index a4027bcb00..1e586146ab 100644 --- a/app/controllers/RecurringController.php +++ b/app/controllers/RecurringController.php @@ -1,5 +1,4 @@ with('recurring', $recurringTransaction)->with( + return View::make('recurring.show', compact('journals', 'hideRecurring', 'finalDate'))->with('recurring', $recurringTransaction)->with( 'subTitle', $recurringTransaction->name ); } diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index 6b31029726..b4960b41dd 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -501,8 +501,8 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface $set = $this->getUser()->transactionJournals()->withRelevantData()->leftJoin( 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' )->where('transactions.account_id', $account->id)->take($limit)->offset($offset)->before($end)->after($start)->orderBy('date', 'DESC')->get( - ['transaction_journals.*'] - ); + ['transaction_journals.*'] + ); $count = $this->getUser()->transactionJournals()->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') ->before($end)->after($start)->orderBy('date', 'DESC')->where('transactions.account_id', $account->id)->count(); $items = []; diff --git a/app/lib/FireflyIII/Database/Budget.php b/app/lib/FireflyIII/Database/Budget.php index ef901d29ec..6cb68ae838 100644 --- a/app/lib/FireflyIII/Database/Budget.php +++ b/app/lib/FireflyIII/Database/Budget.php @@ -198,10 +198,12 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface public function getTransactionJournalsInRepetition(\Budget $budget, \LimitRepetition $repetition, $limit = 50) { $start = $repetition->startdate; - $end = $repetition->enddate; + $end = $repetition->enddate; $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; - $set = $budget->transactionJournals()->withRelevantData()->before($end)->after($start)->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); + $set = $budget->transactionJournals()->withRelevantData()->before($end)->after($start)->take($limit)->offset($offset)->orderBy('date', 'DESC')->get( + ['transaction_journals.*'] + ); $count = $budget->transactionJournals()->before($end)->after($start)->count(); $items = []; foreach ($set as $entry) { diff --git a/app/lib/FireflyIII/Database/Category.php b/app/lib/FireflyIII/Database/Category.php index 7056754dd8..5857f84326 100644 --- a/app/lib/FireflyIII/Database/Category.php +++ b/app/lib/FireflyIII/Database/Category.php @@ -46,15 +46,16 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface */ public function store(array $data) { - $category = new \Category; - $category->name = $data['name']; + $category = new \Category; + $category->name = $data['name']; $category->class = 'Category'; $category->user()->associate($this->getUser()); - if(!$category->validate()) { + if (!$category->validate()) { var_dump($category->errors()); exit(); } $category->save(); + return $category; } diff --git a/app/lib/FireflyIII/Database/Ifaces/RecurringInterface.php b/app/lib/FireflyIII/Database/Ifaces/RecurringInterface.php index b820b64776..5ff9a7aabb 100644 --- a/app/lib/FireflyIII/Database/Ifaces/RecurringInterface.php +++ b/app/lib/FireflyIII/Database/Ifaces/RecurringInterface.php @@ -20,6 +20,14 @@ interface RecurringInterface */ public function getJournalForRecurringInRange(\RecurringTransaction $recurring, Carbon $start, Carbon $end); + /** + * @param \RecurringTransaction $recurring + * @param \TransactionJournal $journal + * + * @return bool + */ + public function scan(\RecurringTransaction $recurring, \TransactionJournal $journal); + /** * @param \RecurringTransaction $recurring * @@ -27,12 +35,4 @@ interface RecurringInterface */ public function scanEverything(\RecurringTransaction $recurring); - /** - * @param \RecurringTransaction $recurring - * @param \TransactionJournal $journal - * - * @return bool - */ - public function scan(\RecurringTransaction $recurring,\TransactionJournal $journal); - } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Piggybank.php b/app/lib/FireflyIII/Database/Piggybank.php index 804dcc307c..c4104d07ea 100644 --- a/app/lib/FireflyIII/Database/Piggybank.php +++ b/app/lib/FireflyIII/Database/Piggybank.php @@ -59,6 +59,7 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface exit; } $piggybank->save(); + return $piggybank; } @@ -197,9 +198,8 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface public function find($id) { return \Piggybank:: - leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id') - ->where('piggybanks.id','=',$id) - ->where('accounts.user_id', $this->getUser()->id)->first(['piggybanks.*']); + leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where('piggybanks.id', '=', $id)->where('accounts.user_id', $this->getUser()->id) + ->first(['piggybanks.*']); } /** diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 0f4a145a06..36c22c6116 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -38,6 +38,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData public function destroy(Ardent $model) { $model->delete(); + return true; } @@ -128,19 +129,19 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData /* * Store the budget. */ - if(isset($data['budget_id']) && intval($data['budget_id']) > 0) { + if (isset($data['budget_id']) && intval($data['budget_id']) > 0) { /** @var \FireflyIII\Database\Budget $budgetRepository */ $budgetRepository = \App::make('FireflyIII\Database\Budget'); - $budget = $budgetRepository->find(intval($data['budget_id'])); - if($budget) { + $budget = $budgetRepository->find(intval($data['budget_id'])); + if ($budget) { $journal->budgets()->save($budget); } } - if(strlen($data['category']) > 0) { + if (strlen($data['category']) > 0) { /** @var \FireflyIII\Database\Category $categoryRepository */ $categoryRepository = \App::make('FireflyIII\Database\Category'); - $category = $categoryRepository->firstOrCreate($data['category']); - if($category) { + $category = $categoryRepository->firstOrCreate($data['category']); + if ($category) { $journal->categories()->save($category); } } @@ -222,19 +223,19 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData /* * Store the budget. */ - if(isset($data['budget_id']) && intval($data['budget_id']) > 0) { + if (isset($data['budget_id']) && intval($data['budget_id']) > 0) { /** @var \FireflyIII\Database\Budget $budgetRepository */ $budgetRepository = \App::make('FireflyIII\Database\Budget'); - $budget = $budgetRepository->find(intval($data['budget_id'])); - if($budget) { + $budget = $budgetRepository->find(intval($data['budget_id'])); + if ($budget) { $model->budgets()->sync([$budget->id]); } } - if(strlen($data['category']) > 0) { + if (strlen($data['category']) > 0) { /** @var \FireflyIII\Database\Category $categoryRepository */ $categoryRepository = \App::make('FireflyIII\Database\Category'); - $category = $categoryRepository->firstOrCreate($data['category']); - if($category) { + $category = $categoryRepository->firstOrCreate($data['category']); + if ($category) { $model->categories()->sync([$category->id]); } } @@ -545,6 +546,22 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData return $sum; } + public function getDepositsPaginated($limit = 50) + { + $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; + + $set = $this->getUser()->transactionJournals()->transactionTypes(['Deposit'])->withRelevantData()->take($limit)->offset($offset)->orderBy( + 'date', 'DESC' + )->get(['transaction_journals.*']); + $count = $this->getUser()->transactionJournals()->transactionTypes(['Deposit'])->count(); + $items = []; + foreach ($set as $entry) { + $items[] = $entry; + } + + return \Paginator::make($items, $count, $limit); + } + /** * @param \Account $account * @param int $count @@ -568,12 +585,15 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData return $query; } - public function getWithdrawalsPaginated($limit = 50) { + public function getTransfersPaginated($limit = 50) + { $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; - $set = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->withRelevantData()->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); - $count = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->count(); - $items = []; + $set = $this->getUser()->transactionJournals()->transactionTypes(['Transfer'])->withRelevantData()->take($limit)->offset($offset)->orderBy( + 'date', 'DESC' + )->get(['transaction_journals.*']); + $count = $this->getUser()->transactionJournals()->transactionTypes(['Transfer'])->count(); + $items = []; foreach ($set as $entry) { $items[] = $entry; } @@ -581,25 +601,15 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData return \Paginator::make($items, $count, $limit); } - public function getDepositsPaginated($limit = 50) { + public function getWithdrawalsPaginated($limit = 50) + { $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; - $set = $this->getUser()->transactionJournals()->transactionTypes(['Deposit'])->withRelevantData()->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); - $count = $this->getUser()->transactionJournals()->transactionTypes(['Deposit'])->count(); - $items = []; - foreach ($set as $entry) { - $items[] = $entry; - } - - return \Paginator::make($items, $count, $limit); - } - - public function getTransfersPaginated($limit = 50) { - $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; - - $set = $this->getUser()->transactionJournals()->transactionTypes(['Transfer'])->withRelevantData()->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); - $count = $this->getUser()->transactionJournals()->transactionTypes(['Transfer'])->count(); - $items = []; + $set = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->withRelevantData()->take($limit)->offset($offset)->orderBy( + 'date', 'DESC' + )->get(['transaction_journals.*']); + $count = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->count(); + $items = []; foreach ($set as $entry) { $items[] = $entry; } diff --git a/app/lib/FireflyIII/Event/Piggybank.php b/app/lib/FireflyIII/Event/Piggybank.php index d881b0ece2..9a4b0ff845 100644 --- a/app/lib/FireflyIII/Event/Piggybank.php +++ b/app/lib/FireflyIII/Event/Piggybank.php @@ -92,6 +92,18 @@ class Piggybank * */ + public function storePiggybank(\Piggybank $piggybank) + { + if (intval($piggybank->repeats) == 0) { + $repetition = new \PiggybankRepetition; + $repetition->piggybank()->associate($piggybank); + $repetition->startdate = $piggybank->startdate; + $repetition->targetdate = $piggybank->targetdate; + $repetition->currentamount = 0; + $repetition->save(); + } + } + /** * @param \TransactionJournal $journal * @param int $piggybankId @@ -159,17 +171,6 @@ class Piggybank } } - public function storePiggybank(\Piggybank $piggybank) { - if(intval($piggybank->repeats) == 0) { - $repetition = new \PiggybankRepetition; - $repetition->piggybank()->associate($piggybank); - $repetition->startdate = $piggybank->startdate; - $repetition->targetdate = $piggybank->targetdate; - $repetition->currentamount = 0; - $repetition->save(); - } - } - /** * @param Dispatcher $events */ diff --git a/app/lib/FireflyIII/Form/Form.php b/app/lib/FireflyIII/Form/Form.php index a5a30fe4f8..82dee3b288 100644 --- a/app/lib/FireflyIII/Form/Form.php +++ b/app/lib/FireflyIII/Form/Form.php @@ -31,67 +31,6 @@ class Form } - /** - * @param $name - * @param null $value - * @param array $options - * - * @return string - * @throws FireflyException - */ - public static function ffBalance($name, $value = null, array $options = []) - { - $options['step'] = 'any'; - - return self::ffInput('amount', $name, $value, $options); - - } - - /** - * @param $name - * @param int $value - * @param null $checked - * @param array $options - * - * @return string - * @throws FireflyException - */ - public static function ffCheckbox($name, $value = 1, $checked = null, $options = []) - { - $options['checked'] = $checked ? true : null; - - return self::ffInput('checkbox', $name, $value, $options); - } - - /** - * @param $name - * @param null $value - * @param array $options - * - * @return string - * @throws FireflyException - */ - public static function ffDate($name, $value = null, array $options = []) - { - return self::ffInput('date', $name, $value, $options); - } - - /** - * @param $name - * @param null $value - * @param array $options - * - * @return string - * @throws FireflyException - */ - public static function ffInteger($name, $value = null, array $options = []) - { - $options['step'] = '1'; - - return self::ffInput('number', $name, $value, $options); - - } - /** * @param $type * @param $name @@ -113,7 +52,6 @@ class Form $label = self::label($name, $options); - /* * Make label and placeholder look nice. */ @@ -272,6 +210,67 @@ class Form } + /** + * @param $name + * @param null $value + * @param array $options + * + * @return string + * @throws FireflyException + */ + public static function ffBalance($name, $value = null, array $options = []) + { + $options['step'] = 'any'; + + return self::ffInput('amount', $name, $value, $options); + + } + + /** + * @param $name + * @param int $value + * @param null $checked + * @param array $options + * + * @return string + * @throws FireflyException + */ + public static function ffCheckbox($name, $value = 1, $checked = null, $options = []) + { + $options['checked'] = $checked ? true : null; + + return self::ffInput('checkbox', $name, $value, $options); + } + + /** + * @param $name + * @param null $value + * @param array $options + * + * @return string + * @throws FireflyException + */ + public static function ffDate($name, $value = null, array $options = []) + { + return self::ffInput('date', $name, $value, $options); + } + + /** + * @param $name + * @param null $value + * @param array $options + * + * @return string + * @throws FireflyException + */ + public static function ffInteger($name, $value = null, array $options = []) + { + $options['step'] = '1'; + + return self::ffInput('number', $name, $value, $options); + + } + /** * Return buttons for update/validate/return. * diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index a41f40b5f9..6e01172b8f 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -85,6 +85,7 @@ class Date $currentEnd->addYear()->subDay(); break; } + return $currentEnd; } diff --git a/app/models/Account.php b/app/models/Account.php index b126388ad1..496b14bbed 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -3,28 +3,29 @@ use Carbon\Carbon; use LaravelBook\Ardent\Ardent as Ardent; use LaravelBook\Ardent\Builder; + /** * Account * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property integer $user_id - * @property integer $account_type_id - * @property string $name - * @property boolean $active - * @property-read \AccountType $accountType + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property integer $user_id + * @property integer $account_type_id + * @property string $name + * @property boolean $active + * @property-read \AccountType $accountType * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions - * @property-read \Illuminate\Database\Eloquent\Collection|\Piggybank[] $piggybanks - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\Account whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereAccountTypeId($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereName($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereActive($value) - * @method static \Account accountTypeIn($types) + * @property-read \Illuminate\Database\Eloquent\Collection|\Piggybank[] $piggybanks + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\Account whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereAccountTypeId($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereName($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereActive($value) + * @method static \Account accountTypeIn($types) */ class Account extends Ardent { @@ -70,6 +71,16 @@ class Account extends Ardent ); } + /** + * Transactions. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function transactions() + { + return $this->hasMany('Transaction'); + } + /** * @param TransactionJournal $journal * @@ -92,23 +103,13 @@ class Account extends Ardent public function lastActionDate() { $transaction = $this->transactions()->orderBy('updated_at', 'DESC')->first(); - if(is_null($transaction)) { + if (is_null($transaction)) { return null; } return $transaction->updated_at; } - /** - * Transactions. - * - * @return \Illuminate\Database\Eloquent\Relations\HasMany - */ - public function transactions() - { - return $this->hasMany('Transaction'); - } - /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ diff --git a/app/models/AccountMeta.php b/app/models/AccountMeta.php index dc8a8452b9..73d7f9f973 100644 --- a/app/models/AccountMeta.php +++ b/app/models/AccountMeta.php @@ -1,6 +1,7 @@ transactionjournals()->orderBy('updated_at', 'DESC')->first(); + if (is_null($transaction)) { + return null; + } + + return $transaction->date; + } + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ @@ -31,16 +45,4 @@ class Category extends Component { return $this->belongsToMany('TransactionJournal', 'component_transaction_journal', 'component_id'); } - /** - * @return Carbon - */ - public function lastActionDate() - { - $transaction = $this->transactionjournals()->orderBy('updated_at', 'DESC')->first(); - if(is_null($transaction)) { - return null; - } - - return $transaction->date; - } } \ No newline at end of file diff --git a/app/models/Component.php b/app/models/Component.php index b70d981ccf..ea5398035d 100644 --- a/app/models/Component.php +++ b/app/models/Component.php @@ -1,25 +1,26 @@ leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->leftJoin( - 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' - )->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')->leftJoin( - 'limits', 'limits.component_id', '=', 'components.id' - )->leftJoin('limit_repetitions', 'limit_repetitions.limit_id', '=', 'limits.id')->where( - 'transaction_journals.date', '>=', $this->startdate->format('Y-m-d') - )->where('transaction_journals.date', '<=', $this->enddate->format('Y-m-d'))->where('transactions.amount', '>', 0)->where( - 'limit_repetitions.id', '=', $this->id - )->sum('transactions.amount'); + 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' + )->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')->leftJoin( + 'limits', 'limits.component_id', '=', 'components.id' + )->leftJoin('limit_repetitions', 'limit_repetitions.limit_id', '=', 'limits.id')->where( + 'transaction_journals.date', '>=', $this->startdate->format('Y-m-d') + )->where('transaction_journals.date', '<=', $this->enddate->format('Y-m-d'))->where('transactions.amount', '>', 0)->where( + 'limit_repetitions.id', '=', $this->id + )->sum('transactions.amount'); return floatval($sum); } diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php index 623d82f74d..f949e38e07 100644 --- a/app/models/Piggybank.php +++ b/app/models/Piggybank.php @@ -2,45 +2,46 @@ use Carbon\Carbon; use LaravelBook\Ardent\Ardent as Ardent; + /** * Piggybank * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property integer $account_id - * @property string $name - * @property float $targetamount - * @property \Carbon\Carbon $startdate - * @property \Carbon\Carbon $targetdate - * @property boolean $repeats - * @property string $rep_length - * @property integer $rep_every - * @property integer $rep_times - * @property string $reminder - * @property integer $reminder_skip - * @property boolean $remind_me - * @property integer $order - * @property-read \Account $account + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property integer $account_id + * @property string $name + * @property float $targetamount + * @property \Carbon\Carbon $startdate + * @property \Carbon\Carbon $targetdate + * @property boolean $repeats + * @property string $rep_length + * @property integer $rep_every + * @property integer $rep_times + * @property string $reminder + * @property integer $reminder_skip + * @property integer $order + * @property boolean $remind_me + * @property-read \Account $account * @property-read \Illuminate\Database\Eloquent\Collection|\PiggybankRepetition[] $piggybankrepetitions - * @property-read \Illuminate\Database\Eloquent\Collection|\PiggybankEvent[] $piggybankevents - * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereAccountId($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereName($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereTargetamount($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereStartdate($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereTargetdate($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepeats($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepLength($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepEvery($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepTimes($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminder($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminderSkip($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRemindMe($value) - * @method static \Illuminate\Database\Query\Builder|\Piggybank whereOrder($value) + * @property-read \Illuminate\Database\Eloquent\Collection|\PiggybankEvent[] $piggybankevents + * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereAccountId($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereName($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereTargetamount($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereStartdate($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereTargetdate($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepeats($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepLength($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepEvery($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepTimes($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminder($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminderSkip($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereOrder($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRemindMe($value) */ class Piggybank extends Ardent { @@ -70,21 +71,23 @@ class Piggybank extends Ardent return $this->belongsTo('Account'); } - public function countFutureReminders() { + public function countFutureReminders() + { /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ $dateKit = App::make('FireflyIII\Shared\Toolkit\Date'); - if(is_null($this->reminder)) { + if (is_null($this->reminder)) { return 0; } - $start = new Carbon; - $end = !is_null($this->targetdate) ? clone $this->targetdate : new Carbon; + $start = new Carbon; + $end = !is_null($this->targetdate) ? clone $this->targetdate : new Carbon; $reminders = 0; - while($start <= $end) { + while ($start <= $end) { $reminders++; $start = $dateKit->addPeriod($start, $this->reminder, $this->reminder_skip); } + return $reminders; } diff --git a/app/models/PiggybankEvent.php b/app/models/PiggybankEvent.php index b33a8567cc..d8edc9fa0c 100644 --- a/app/models/PiggybankEvent.php +++ b/app/models/PiggybankEvent.php @@ -2,22 +2,26 @@ use LaravelBook\Ardent\Ardent as Ardent; + /** * PiggybankEvent * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property integer $piggybank_id - * @property \Carbon\Carbon $date - * @property float $amount + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property integer $piggybank_id + * @property \Carbon\Carbon $date + * @property float $amount + * @property integer $transaction_journal_id * @property-read \Piggybank $piggybank - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereId($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent wherePiggybankId($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereDate($value) - * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereAmount($value) + * @property-read \TransactionJournal $transactionJournal + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereId($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent wherePiggybankId($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereDate($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereAmount($value) + * @method static \Illuminate\Database\Query\Builder|\PiggybankEvent whereTransactionJournalId($value) */ class PiggybankEvent extends Ardent { diff --git a/app/models/PiggybankRepetition.php b/app/models/PiggybankRepetition.php index 99e0ee85a6..7360fa26ad 100644 --- a/app/models/PiggybankRepetition.php +++ b/app/models/PiggybankRepetition.php @@ -1,24 +1,25 @@ transactionjournals()->orderBy('date','DESC')->first(); - if($last) { + public function lastFoundMatch() + { + $last = $this->transactionjournals()->orderBy('date', 'DESC')->first(); + if ($last) { return $last->date; } + return null; } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function transactionjournals() + { + return $this->hasMany('TransactionJournal'); + } + /** * Find the next expected match based on the set journals and the date stuff from the recurring * transaction. @@ -110,15 +122,8 @@ class RecurringTransaction extends Ardent $start = $dateKit->addPeriod($start, $this->repeat_freq, 0); $counter++; } - return $finalDate; - } - /** - * @return \Illuminate\Database\Eloquent\Relations\HasMany - */ - public function transactionjournals() - { - return $this->hasMany('TransactionJournal'); + return $finalDate; } /** diff --git a/app/models/Reminder.php b/app/models/Reminder.php index e8fb4154cd..fac62d9d48 100644 --- a/app/models/Reminder.php +++ b/app/models/Reminder.php @@ -6,21 +6,25 @@ use LaravelBook\Ardent\Ardent; /** * Reminder * - * @property integer $id + * @property integer $id * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at - * @property integer $user_id + * @property integer $user_id * @property \Carbon\Carbon $startdate * @property \Carbon\Carbon $enddate - * @property boolean $active - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\Reminder whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereStartdate($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereEnddate($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereActive($value) + * @property boolean $active + * @property string $title + * @property string $data + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\Reminder whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereStartdate($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereEnddate($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereActive($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereTitle($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereData($value) */ class Reminder extends Ardent { diff --git a/app/models/Transaction.php b/app/models/Transaction.php index 6a85e97864..dcdf22871d 100644 --- a/app/models/Transaction.php +++ b/app/models/Transaction.php @@ -1,7 +1,6 @@ hasMany('PiggybankEvent'); + } + /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ @@ -138,14 +148,6 @@ class TransactionJournal extends Ardent return $query->where('date', '>=', $date->format('Y-m-d')); } - /** - * @return \Illuminate\Database\Eloquent\Relations\HasMany - */ - public function piggybankevents() - { - return $this->hasMany('PiggybankEvent'); - } - /** * @param $query * @param Carbon $date @@ -221,7 +223,7 @@ class TransactionJournal extends Ardent $q->orderBy('amount', 'ASC'); }, 'transactiontype', 'components' => function ($q) { $q->orderBy('class'); - }, 'transactions.account.accounttype', 'recurringTransaction','budgets','categories'] + }, 'transactions.account.accounttype', 'recurringTransaction', 'budgets', 'categories'] ); } diff --git a/app/models/TransactionType.php b/app/models/TransactionType.php index 0fea66cadd..9633bc07e1 100644 --- a/app/models/TransactionType.php +++ b/app/models/TransactionType.php @@ -5,15 +5,15 @@ use LaravelBook\Ardent\Ardent; /** * TransactionType * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $type + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $type * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionJournals - * @method static \Illuminate\Database\Query\Builder|\TransactionType whereId($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionType whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionType whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\TransactionType whereType($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionType whereId($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionType whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionType whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\TransactionType whereType($value) */ class TransactionType extends Ardent { diff --git a/app/models/User.php b/app/models/User.php index 15de4c9168..88b46873c4 100644 --- a/app/models/User.php +++ b/app/models/User.php @@ -9,29 +9,29 @@ use LaravelBook\Ardent\Ardent; /** * User * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $email - * @property string $password - * @property string $reset - * @property string $remember_token - * @property boolean $migrated - * @property-read \Illuminate\Database\Eloquent\Collection|\Account[] $accounts - * @property-read \Illuminate\Database\Eloquent\Collection|\Budget[] $budgets - * @property-read \Illuminate\Database\Eloquent\Collection|\Category[] $categories - * @property-read \Illuminate\Database\Eloquent\Collection|\Component[] $components - * @property-read \Illuminate\Database\Eloquent\Collection|\Preference[] $preferences + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $email + * @property string $password + * @property string $reset + * @property string $remember_token + * @property boolean $migrated + * @property-read \Illuminate\Database\Eloquent\Collection|\Account[] $accounts + * @property-read \Illuminate\Database\Eloquent\Collection|\Budget[] $budgets + * @property-read \Illuminate\Database\Eloquent\Collection|\Category[] $categories + * @property-read \Illuminate\Database\Eloquent\Collection|\Component[] $components + * @property-read \Illuminate\Database\Eloquent\Collection|\Preference[] $preferences * @property-read \Illuminate\Database\Eloquent\Collection|\RecurringTransaction[] $recurringtransactions - * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals - * @method static \Illuminate\Database\Query\Builder|\User whereId($value) - * @method static \Illuminate\Database\Query\Builder|\User whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\User whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\User whereEmail($value) - * @method static \Illuminate\Database\Query\Builder|\User wherePassword($value) - * @method static \Illuminate\Database\Query\Builder|\User whereReset($value) - * @method static \Illuminate\Database\Query\Builder|\User whereRememberToken($value) - * @method static \Illuminate\Database\Query\Builder|\User whereMigrated($value) + * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals + * @method static \Illuminate\Database\Query\Builder|\User whereId($value) + * @method static \Illuminate\Database\Query\Builder|\User whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\User whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\User whereEmail($value) + * @method static \Illuminate\Database\Query\Builder|\User wherePassword($value) + * @method static \Illuminate\Database\Query\Builder|\User whereReset($value) + * @method static \Illuminate\Database\Query\Builder|\User whereRememberToken($value) + * @method static \Illuminate\Database\Query\Builder|\User whereMigrated($value) */ class User extends Ardent implements UserInterface, RemindableInterface { diff --git a/app/start/global.php b/app/start/global.php index 6968b4dfba..5604f492bb 100644 --- a/app/start/global.php +++ b/app/start/global.php @@ -14,10 +14,7 @@ ClassLoader::addDirectories( [ - app_path() . '/commands', - app_path() . '/controllers', - app_path() . '/models', - app_path() . '/database/seeds', + app_path() . '/commands', app_path() . '/controllers', app_path() . '/models', app_path() . '/database/seeds', ] ); diff --git a/bootstrap/paths.php b/bootstrap/paths.php index 289ed916e0..5600950eee 100644 --- a/bootstrap/paths.php +++ b/bootstrap/paths.php @@ -1,6 +1,6 @@ __DIR__ . '/../app/storage', -); +]; diff --git a/bootstrap/start.php b/bootstrap/start.php index 3a43913112..3de22ae845 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -38,10 +38,7 @@ $app = new Illuminate\Foundation\Application; */ $env = $app->detectEnvironment( - [ - 'local' => ['SMJD*'], - 'homestead' => ['homestead'] - ] + ['local' => ['SMJD*'], 'homestead' => ['homestead']] ); @@ -69,8 +66,7 @@ $app->bindInstallPaths(require __DIR__ . '/paths.php'); | */ -$framework = $app['path.base'] . - '/vendor/laravel/framework/src'; +$framework = $app['path.base'] . '/vendor/laravel/framework/src'; require $framework . '/Illuminate/Foundation/start.php'; From 69e7501d47a5642bb4253850105a3218aeb4e5a8 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 17 Nov 2014 08:20:05 +0100 Subject: [PATCH 055/193] Start with cleaning up the menu. --- app/views/partials/menu.blade.php | 120 +++++++++++++++--------------- 1 file changed, 58 insertions(+), 62 deletions(-) diff --git a/app/views/partials/menu.blade.php b/app/views/partials/menu.blade.php index bf070e6cdb..bc5471993a 100644 --- a/app/views/partials/menu.blade.php +++ b/app/views/partials/menu.blade.php @@ -1,77 +1,73 @@
diff --git a/app/views/transactions/create.blade.php b/app/views/transactions/create.blade.php index 456ec7a40f..eed40fd5c2 100644 --- a/app/views/transactions/create.blade.php +++ b/app/views/transactions/create.blade.php @@ -69,7 +69,7 @@ @if($what == 'transfer' && count($piggies) > 0) - {{Form::ffSelect('piggybank_id',$piggies,0)}} + {{Form::ffSelect('piggybank_id',$piggies)}} @endif
From 1b1367f4c2549a5eec75dd793ebdb79916a6e60e Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 20 Nov 2014 11:10:42 +0100 Subject: [PATCH 088/193] Make sure the progress bar has a minimal width to improve readability. --- app/views/piggybanks/index.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/piggybanks/index.blade.php b/app/views/piggybanks/index.blade.php index 9249569b32..6f0e7ed77f 100644 --- a/app/views/piggybanks/index.blade.php +++ b/app/views/piggybanks/index.blade.php @@ -20,7 +20,7 @@ @else class="progress-bar progress-bar-info" @endif - role="progressbar" aria-valuenow="{{$piggybank->percentage}}" aria-valuemin="0" aria-valuemax="100" style="width: {{$piggybank->percentage}}%;"> + role="progressbar" aria-valuenow="{{$piggybank->percentage}}" aria-valuemin="0" aria-valuemax="100" style="min-width: 40px;width: {{$piggybank->percentage}}%;"> {{$piggybank->percentage}}%
From d758f723931195c32dbc253b819268ed64f47d6b Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 20 Nov 2014 11:15:00 +0100 Subject: [PATCH 089/193] Better visualisation in the budget charts. --- app/views/budgets/index.blade.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/budgets/index.blade.php b/app/views/budgets/index.blade.php index 9dd76b21e6..b8e580300e 100644 --- a/app/views/budgets/index.blade.php +++ b/app/views/budgets/index.blade.php @@ -19,8 +19,8 @@
-
-
+
+
@@ -33,12 +33,12 @@
-
+
@if($overspent)
@else -
+
@endif
From 61eb5b341dadf78536a054abe5137d196dd03e94 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 20 Nov 2014 11:19:35 +0100 Subject: [PATCH 090/193] Update piggy banks repetitions when the piggy bank is edited. --- app/controllers/PiggybankController.php | 3 ++- app/lib/FireflyIII/Event/Piggybank.php | 20 +++++++++++++++----- bootstrap/start.php | 6 +++--- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index f94e1368d1..2e9cd7fbfb 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -283,7 +283,7 @@ class PiggybankController extends BaseController /* * Create the relevant repetition per Event. */ - Event::fire('piggybank.storePiggybank', [$piggyBank]); // new and used. + Event::fire('piggybank.store', [$piggyBank]); // new and used. Session::flash('success', 'New piggy bank stored!'); @@ -333,6 +333,7 @@ class PiggybankController extends BaseController } // store! $repos->update($piggyBank, $data); + Event::fire('piggybank.update', [$piggyBank]); // new and used. Session::flash('success', 'Piggy bank updated!'); if ($data['post_submit_action'] == 'return_to_edit') { diff --git a/app/lib/FireflyIII/Event/Piggybank.php b/app/lib/FireflyIII/Event/Piggybank.php index c856dfba05..f5e24c72f1 100644 --- a/app/lib/FireflyIII/Event/Piggybank.php +++ b/app/lib/FireflyIII/Event/Piggybank.php @@ -88,10 +88,6 @@ class Piggybank } } - /* - * - */ - public function storePiggybank(\Piggybank $piggybank) { if (intval($piggybank->repeats) == 0) { @@ -104,6 +100,10 @@ class Piggybank } } + /* + * + */ + /** * @param \TransactionJournal $journal * @param int $piggybankId @@ -182,8 +182,9 @@ class Piggybank // triggers on piggy bank events: $events->listen('piggybank.addMoney', 'FireflyIII\Event\Piggybank@addMoney'); $events->listen('piggybank.removeMoney', 'FireflyIII\Event\Piggybank@removeMoney'); + $events->listen('piggybank.store', 'FireflyIII\Event\Piggybank@storePiggybank'); + $events->listen('piggybank.update', 'FireflyIII\Event\Piggybank@updatePiggybank'); - $events->listen('piggybank.storePiggybank', 'FireflyIII\Event\Piggybank@storePiggybank'); // triggers when others are updated. $events->listen('transactionJournal.store', 'FireflyIII\Event\Piggybank@storeTransfer'); @@ -191,6 +192,15 @@ class Piggybank $events->listen('transactionJournal.destroy', 'FireflyIII\Event\Piggybank@destroyTransfer'); } + public function updatePiggybank(\Piggybank $piggybank) + { + // get the repetition: + $repetition = $piggybank->currentRelevantRep(); + $repetition->startdate = $piggybank->startdate; + $repetition->targetdate = $piggybank->targetdate; + $repetition->save(); + } + public function updateTransfer(\TransactionJournal $journal) { diff --git a/bootstrap/start.php b/bootstrap/start.php index fc0f6e7441..ac8176b74e 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -92,14 +92,14 @@ Event::subscribe('FireflyIII\Event\Piggybank'); Event::subscribe('FireflyIII\Event\Budget'); Event::subscribe('FireflyIII\Event\TransactionJournal'); -// TODO event that creates a relationship between transaction journals and recurring events when created. -// TODO event that updates the relationship between transaction journals and recurring events when edited. +// event that creates a relationship between transaction journals and recurring events when created. +// event that updates the relationship between transaction journals and recurring events when edited. // event that creates a LimitRepetition when a Limit is created. // event for when a transfer gets created and set an associated piggy bank; save as Piggy bank event. // when this transfer gets edited, retro-actively edit the event and THUS also the piggy bank. // event for when a transfer gets deleted; also delete related piggy bank event. // event to create the first repetition (for non-repeating piggy banks) when the piggy bank is created. -// TODO event for when the non-repeating piggy bank is updated because the single repetition must also be changed. +// event for when the non-repeating piggy bank is updated because the single repetition must also be changed. // (also make piggy bank events "invalid" when they start falling outside of the date-scope of the piggy bank, // although this not changes the amount in the piggy bank). // TODO check if recurring transactions are being updated when journals are updated (aka no longer fitting, thus removed). From 73743721b11cb8e1e6b777287bd1c115bf08b244 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 20 Nov 2014 11:36:53 +0100 Subject: [PATCH 091/193] Fixed a bug where a non-matching journal would keep its recurring transaction. --- app/lib/FireflyIII/Event/TransactionJournal.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/lib/FireflyIII/Event/TransactionJournal.php b/app/lib/FireflyIII/Event/TransactionJournal.php index d33a188e46..e966e13ff5 100644 --- a/app/lib/FireflyIII/Event/TransactionJournal.php +++ b/app/lib/FireflyIII/Event/TransactionJournal.php @@ -20,6 +20,7 @@ class TransactionJournal $repository = \App::make('FireflyIII\Database\Recurring'); $set = $repository->get(); + /** @var \RecurringTransaction $entry */ foreach ($set as $entry) { $repository->scan($entry, $journal); @@ -41,6 +42,8 @@ class TransactionJournal /** @var \FireflyIII\Database\Recurring $repository */ $repository = \App::make('FireflyIII\Database\Recurring'); $set = $repository->get(); + $journal->recurring_transaction_id = null; + $journal->save(); /** @var \RecurringTransaction $entry */ foreach ($set as $entry) { From ea6aba62c4cd83ce44ed416d5c41fd3d3a36a071 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 21 Nov 2014 11:11:03 +0100 Subject: [PATCH 092/193] Remove unused code. --- app/lib/FireflyIII/Shared/Json/Account.php | 13 ---- app/lib/FireflyIII/Shared/Json/Json.php | 71 ---------------------- 2 files changed, 84 deletions(-) delete mode 100644 app/lib/FireflyIII/Shared/Json/Account.php delete mode 100644 app/lib/FireflyIII/Shared/Json/Json.php diff --git a/app/lib/FireflyIII/Shared/Json/Account.php b/app/lib/FireflyIII/Shared/Json/Account.php deleted file mode 100644 index 28724e732f..0000000000 --- a/app/lib/FireflyIII/Shared/Json/Account.php +++ /dev/null @@ -1,13 +0,0 @@ - intval(\Input::get('start')), 'length' => $length, 'draw' => intval(\Input::get('draw')),]; - - - /* - * Columns: - */ - if (!is_null(\Input::get('columns')) && is_array(\Input::get('columns'))) { - foreach (\Input::get('columns') as $column) { - $parameters['columns'][] = ['data' => $column['data'], 'name' => $column['name'], - 'searchable' => $column['searchable'] == 'true' ? true : false, - 'orderable' => $column['orderable'] == 'true' ? true : false, 'search' => ['value' => $column['search']['value'], - 'regex' => - $column['search']['regex'] == 'true' - ? true : false,]]; - } - } - - - /* - * Sorting. - */ - $parameters['orderOnAccount'] = false; - if (!is_null(\Input::get('order')) && is_array(\Input::get('order'))) { - foreach (\Input::get('order') as $order) { - $columnIndex = intval($order['column']); - $columnName = $parameters['columns'][$columnIndex]['name']; - $parameters['order'][] = ['name' => $columnName, 'dir' => strtoupper($order['dir'])]; - if ($columnName == 'to' || $columnName == 'from') { - $parameters['orderOnAccount'] = true; - } - } - } - /* - * Search parameters: - */ - $parameters['search'] = ['value' => '', 'regex' => false]; - if (!is_null(\Input::get('search')) && is_array(\Input::get('search'))) { - $search = \Input::get('search'); - $parameters['search'] = ['value' => $search['value'], 'regex' => $search['regex'] == 'true' ? true : false]; - } - - return $parameters; - } -} \ No newline at end of file From 243d942a6e9afbe09e05a577a6c4847f31e0f020 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 21 Nov 2014 11:11:14 +0100 Subject: [PATCH 093/193] Remove unused library --- app/config/app.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/config/app.php b/app/config/app.php index 114350c2b5..507426a367 100644 --- a/app/config/app.php +++ b/app/config/app.php @@ -84,8 +84,7 @@ return [ 'URL' => 'Illuminate\Support\Facades\URL', 'Validator' => 'Illuminate\Support\Facades\Validator', 'View' => 'Illuminate\Support\Facades\View', - 'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade', - 'Twig' => 'TwigBridge\Facade\Twig', + 'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade' ], From ec776bb6eb721b9a25816ea148618cb0c949a543 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 21 Nov 2014 11:11:52 +0100 Subject: [PATCH 094/193] Add some hasManyThrough references --- app/models/Account.php | 6 ++++++ app/models/Budget.php | 23 ++++++++++++++--------- app/models/Component.php | 1 - app/models/LimitRepetition.php | 1 + app/models/TransactionCurrency.php | 2 +- app/models/User.php | 14 +++++++++++--- 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/app/models/Account.php b/app/models/Account.php index 46e8fdc04d..e20e8f58ce 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -145,6 +145,7 @@ class Account extends Ardent /** * TODO see if this scope is still used. + * * @param Builder $query * @param array $types */ @@ -157,6 +158,11 @@ class Account extends Ardent $query->whereIn('account_types.type', $types); } + public function transactionjournals() + { + return $this->hasManyThrough('TransactionJournal', 'Transaction'); + } + /** * User * diff --git a/app/models/Budget.php b/app/models/Budget.php index b5e516762c..7d5afae06a 100644 --- a/app/models/Budget.php +++ b/app/models/Budget.php @@ -3,16 +3,16 @@ /** * Budget * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property string $name - * @property integer $user_id - * @property string $class - * @property-read \Illuminate\Database\Eloquent\Collection|\Limit[] $limits + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property string $name + * @property integer $user_id + * @property string $class + * @property-read \Illuminate\Database\Eloquent\Collection|\Limit[] $limits * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals - * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions - * @property-read \User $user + * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions + * @property-read \User $user * @method static \Illuminate\Database\Query\Builder|\Budget whereId($value) * @method static \Illuminate\Database\Query\Builder|\Budget whereCreatedAt($value) * @method static \Illuminate\Database\Query\Builder|\Budget whereUpdatedAt($value) @@ -24,6 +24,11 @@ class Budget extends Component { protected $isSubclass = true; + public function limitrepetitions() + { + return $this->hasManyThrough('LimitRepetition', 'Limit'); + } + /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ diff --git a/app/models/Component.php b/app/models/Component.php index 5f978e08d6..36493d8f65 100644 --- a/app/models/Component.php +++ b/app/models/Component.php @@ -58,7 +58,6 @@ class Component extends SingleTableInheritanceEntity return $this->belongsToMany('TransactionJournal', 'component_transaction_journal', 'component_id'); } - /** * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ diff --git a/app/models/LimitRepetition.php b/app/models/LimitRepetition.php index e9e65bff86..651b5dd40e 100644 --- a/app/models/LimitRepetition.php +++ b/app/models/LimitRepetition.php @@ -80,6 +80,7 @@ class LimitRepetition extends Ardent return $this->belongsTo('Limit'); } + /** * TODO remove this method in favour of something in the FireflyIII libraries. * diff --git a/app/models/TransactionCurrency.php b/app/models/TransactionCurrency.php index 8a8512f87f..6c1aa0da36 100644 --- a/app/models/TransactionCurrency.php +++ b/app/models/TransactionCurrency.php @@ -21,7 +21,7 @@ class TransactionCurrency extends Eloquent /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ - public function transactionjournals() + public function transactionJournals() { return $this->hasMany('TransactionJournal'); } diff --git a/app/models/User.php b/app/models/User.php index e58e572133..e92041ac74 100644 --- a/app/models/User.php +++ b/app/models/User.php @@ -40,9 +40,13 @@ class User extends Ardent implements UserInterface, RemindableInterface public static $rules - = ['email' => 'required|email|unique:users,email', 'migrated' => 'required|boolean', 'password' => 'required|between:60,60', - 'reset' => 'between:32,32',]; - protected $fillable = ['email']; + = [ + 'email' => 'required|email|unique:users,email', + 'migrated' => 'required|boolean', + 'password' => 'required|between:60,60', + 'reset' => 'between:32,32', + ]; + protected $fillable = ['email']; /** * The attributes excluded from the model's JSON form. * @@ -92,6 +96,10 @@ class User extends Ardent implements UserInterface, RemindableInterface { return $this->hasManyThrough('Piggybank', 'Account'); } + public function transactions() + { + return $this->hasManyThrough('TransactionJournal', 'Transaction'); + } /** * @return \Illuminate\Database\Eloquent\Relations\HasMany From 3dce1949302c69009584cc5f090cd4cf4a850c8d Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 21 Nov 2014 11:12:22 +0100 Subject: [PATCH 095/193] Use facades. --- app/controllers/GoogleChartController.php | 12 ++--- app/controllers/HomeController.php | 10 +--- app/controllers/PiggybankController.php | 10 +--- app/controllers/ReminderController.php | 9 +--- app/controllers/TransactionController.php | 16 +++--- app/filters.php | 13 ++--- app/lib/FireflyIII/Database/Budget.php | 2 +- app/lib/FireflyIII/Database/Recurring.php | 4 +- .../Database/TransactionJournal.php | 2 +- app/lib/FireflyIII/Event/Budget.php | 4 +- app/lib/FireflyIII/FF3ServiceProvider.php | 49 +++++++++++++++++++ app/lib/FireflyIII/Shared/Facade/DateKit.php | 16 ++++++ app/lib/FireflyIII/Shared/Facade/FFForm.php | 16 ++++++ app/lib/FireflyIII/Shared/Facade/Filter.php | 16 ++++++ .../FireflyIII/Shared/Facade/Navigation.php | 16 ++++++ .../FireflyIII/Shared/Facade/Reminders.php | 16 ++++++ app/lib/FireflyIII/Shared/Toolkit/Date.php | 1 + .../FireflyIII/Shared/Toolkit/Reminders.php | 16 ++---- app/models/RecurringTransaction.php | 12 ++--- app/models/Reminder.php | 4 +- app/views/reminders/show.blade.php | 1 + bootstrap/start.php | 22 +++++---- 22 files changed, 177 insertions(+), 90 deletions(-) create mode 100644 app/lib/FireflyIII/Shared/Facade/DateKit.php create mode 100644 app/lib/FireflyIII/Shared/Facade/FFForm.php create mode 100644 app/lib/FireflyIII/Shared/Facade/Filter.php create mode 100644 app/lib/FireflyIII/Shared/Facade/Navigation.php create mode 100644 app/lib/FireflyIII/Shared/Facade/Reminders.php diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index a822f6deca..1aec3d005c 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -499,9 +499,6 @@ class GoogleChartController extends BaseController public function recurringOverview(RecurringTransaction $recurring) { - /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ - $dateKit = App::make('FireflyIII\Shared\Toolkit\Date'); - /** @var \Grumpydictator\Gchart\GChart $chart */ $chart = App::make('gchart'); $chart->addColumn('Date', 'date'); @@ -526,7 +523,7 @@ class GoogleChartController extends BaseController } unset($result); $chart->addRow(clone $start, $recurring->amount_max, $recurring->amount_min, $amount); - $start = $dateKit->addPeriod($start, $recurring->repeat_freq, 0); + $start = DateKit::addPeriod($start, $recurring->repeat_freq, 0); } $chart->generate(); @@ -557,9 +554,6 @@ class GoogleChartController extends BaseController /** @var \FireflyIII\Database\Recurring $rcr */ $rcr = App::make('FireflyIII\Database\Recurring'); - /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ - $dateKit = App::make('FireflyIII\Shared\Toolkit\Date'); - $recurring = $rcr->get(); /** @var \RecurringTransaction $entry */ @@ -580,7 +574,7 @@ class GoogleChartController extends BaseController * Get end of period for $current: */ $currentEnd = clone $current; - $dateKit->endOfPeriod($currentEnd, $entry->repeat_freq); + DateKit::endOfPeriod($currentEnd, $entry->repeat_freq); /* * In the current session range? @@ -605,7 +599,7 @@ class GoogleChartController extends BaseController /* * Add some time for the next loop! */ - $dateKit->addPeriod($current, $entry->repeat_freq, intval($entry->skip)); + DateKit::addPeriod($current, $entry->repeat_freq, intval($entry->skip)); } diff --git a/app/controllers/HomeController.php b/app/controllers/HomeController.php index 938812f079..9617608efc 100644 --- a/app/controllers/HomeController.php +++ b/app/controllers/HomeController.php @@ -84,12 +84,9 @@ class HomeController extends BaseController */ public function sessionNext() { - /** @var \FireflyIII\Shared\Toolkit\Navigation $navigation */ - $navigation = App::make('FireflyIII\Shared\Toolkit\Navigation'); - $navigation->next(); + Navigation::next(); return Redirect::back(); - //return Redirect::route('index'); } /** @@ -97,11 +94,8 @@ class HomeController extends BaseController */ public function sessionPrev() { - /** @var \FireflyIII\Shared\Toolkit\Navigation $navigation */ - $navigation = App::make('FireflyIII\Shared\Toolkit\Navigation'); - $navigation->prev(); + Navigation::prev(); return Redirect::back(); - //return Redirect::route('index'); } } \ No newline at end of file diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index 2e9cd7fbfb..15bc390f62 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -48,13 +48,10 @@ class PiggybankController extends BaseController /** @var \FireflyIII\Database\Account $acct */ $acct = App::make('FireflyIII\Database\Account'); - /** @var \FireflyIII\Shared\Toolkit\Form $toolkit */ - $toolkit = App::make('FireflyIII\Shared\Toolkit\Form'); - $periods = Config::get('firefly.piggybank_periods'); - $accounts = $toolkit->makeSelectList($acct->getAssetAccounts()); + $accounts = FFForm::makeSelectList($acct->getAssetAccounts()); return View::make('piggybanks.create', compact('accounts', 'periods'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc')->with( 'subTitle', 'Create new piggy bank' @@ -99,12 +96,9 @@ class PiggybankController extends BaseController /** @var \FireflyIII\Database\Account $acct */ $acct = App::make('FireflyIII\Database\Account'); - /** @var \FireflyIII\Shared\Toolkit\Form $toolkit */ - $toolkit = App::make('FireflyIII\Shared\Toolkit\Form'); - $periods = Config::get('firefly.piggybank_periods'); - $accounts = $toolkit->makeSelectList($acct->getAssetAccounts()); + $accounts = FFForm::makeSelectList($acct->getAssetAccounts()); /* * Flash some data to fill the form. diff --git a/app/controllers/ReminderController.php b/app/controllers/ReminderController.php index e7862f289a..e6bdef5ea0 100644 --- a/app/controllers/ReminderController.php +++ b/app/controllers/ReminderController.php @@ -21,20 +21,15 @@ class ReminderController extends BaseController { $amount = null; - $actionURL = '#'; if (get_class($reminder->remindersable) == 'Piggybank') { - /** @var \FireflyIII\Shared\Toolkit\Reminders $toolkit */ - $reminderKit = App::make('FireflyIII\Shared\Toolkit\Reminders'); - $amount = $reminderKit->amountForReminder($reminder); + $amount = Reminders::amountForReminder($reminder); } return View::make('reminders.show', compact('reminder', 'amount')); } public function act(Reminder $reminder) { - /** @var \FireflyIII\Shared\Toolkit\Reminders $toolkit */ - $reminderKit = App::make('FireflyIII\Shared\Toolkit\Reminders'); switch(get_class($reminder->remindersable)) { default: @@ -42,7 +37,7 @@ class ReminderController extends BaseController break; break; case 'Piggybank': - $amount = $reminderKit->amountForReminder($reminder); + $amount = Reminders::amountForReminder($reminder); $prefilled = [ 'amount' => round($amount,2), 'description' => 'Money for ' . $reminder->remindersable->name, diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 56df20531f..7a8cbdcae0 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -34,8 +34,6 @@ class TransactionController extends BaseController /* * The repositories we need: */ - /** @var \FireflyIII\Shared\Toolkit\Form $form */ - $form = App::make('FireflyIII\Shared\Toolkit\Form'); /** @var \FireflyIII\Database\Account $accountRepository */ $accountRepository = App::make('FireflyIII\Database\Account'); @@ -47,14 +45,14 @@ class TransactionController extends BaseController $piggyRepository = App::make('FireflyIII\Database\Piggybank'); // get asset accounts with names and id's . - $assetAccounts = $form->makeSelectList($accountRepository->getAssetAccounts()); + $assetAccounts = FFForm::makeSelectList($accountRepository->getAssetAccounts()); // get budgets as a select list. - $budgets = $form->makeSelectList($budgetRepository->get()); + $budgets = FFForm::makeSelectList($budgetRepository->get()); $budgets[0] = '(no budget)'; // get the piggy banks. - $piggies = $form->makeSelectList($piggyRepository->get()); + $piggies = FFForm::makeSelectList($piggyRepository->get()); $piggies[0] = '(no piggy bank)'; /* @@ -135,8 +133,6 @@ class TransactionController extends BaseController /* * All the repositories we need: */ - /** @var \FireflyIII\Shared\Toolkit\Form $form */ - $form = App::make('FireflyIII\Shared\Toolkit\Form'); /** @var \FireflyIII\Database\Account $accountRepository */ $accountRepository = App::make('FireflyIII\Database\Account'); @@ -152,10 +148,10 @@ class TransactionController extends BaseController $what = strtolower($journal->transactiontype->type); // get asset accounts with names and id's. - $accounts = $form->makeSelectList($accountRepository->getAssetAccounts()); + $accounts = FFForm::makeSelectList($accountRepository->getAssetAccounts()); // get budgets as a select list. - $budgets = $form->makeSelectList($budgetRepository->get()); + $budgets = FFForm::makeSelectList($budgetRepository->get()); $budgets[0] = '(no budget)'; /* @@ -163,7 +159,7 @@ class TransactionController extends BaseController * of the transactions in the journal has this field, it should all fill in nicely. */ // get the piggy banks. - $piggies = $form->makeSelectList($piggyRepository->get()); + $piggies = FFForm::makeSelectList($piggyRepository->get()); $piggies[0] = '(no piggy bank)'; $piggyBankId = 0; foreach ($journal->transactions as $t) { diff --git a/app/filters.php b/app/filters.php index de94e1a05e..49ca4c8666 100644 --- a/app/filters.php +++ b/app/filters.php @@ -7,16 +7,9 @@ App::before( $reminders = []; if (Auth::check()) { - /** @var \FireflyIII\Shared\Toolkit\Filter $toolkit */ - $filter = App::make('FireflyIII\Shared\Toolkit\Filter'); - $filter->setSessionDateRange(); - - /** @var \FireflyIII\Shared\Toolkit\Reminders $toolkit */ - $reminderKit = App::make('FireflyIII\Shared\Toolkit\Reminders'); - - $reminderKit->updateReminders(); - $reminders = $reminderKit->getReminders(); - + Filter::setSessionDateRange(); + Reminders::updateReminders(); + $reminders = Reminders::getReminders(); } View::share('reminders', $reminders); diff --git a/app/lib/FireflyIII/Database/Budget.php b/app/lib/FireflyIII/Database/Budget.php index 6cb68ae838..2d4a0474e5 100644 --- a/app/lib/FireflyIII/Database/Budget.php +++ b/app/lib/FireflyIII/Database/Budget.php @@ -238,7 +238,7 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface public function transactionsWithoutBudgetInDateRange(Carbon $start, Carbon $end) { // Add expenses that have no budget: - return \Auth::user()->transactionjournals()->whereNotIn( + return $this->getUser()->transactionjournals()->whereNotIn( 'transaction_journals.id', function ($query) use ($start, $end) { $query->select('transaction_journals.id')->from('transaction_journals')->leftJoin( 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' diff --git a/app/lib/FireflyIII/Database/Recurring.php b/app/lib/FireflyIII/Database/Recurring.php index 8a400ac89c..6329cde2ec 100644 --- a/app/lib/FireflyIII/Database/Recurring.php +++ b/app/lib/FireflyIII/Database/Recurring.php @@ -67,9 +67,7 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface /* * Jump to the start of the period. */ - /** @var \FireflyIII\Shared\Toolkit\Date $toolkit */ - $toolkit = \App::make('FireflyIII\Shared\Toolkit\Date'); - $date = $toolkit->startOfPeriod($date, $data['repeat_freq']); + $date = DateKit::startOfPeriod($date, $data['repeat_freq']); $recurring->date = $date; $recurring->skip = intval($data['skip']); diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 040ee14989..b7c2ce5a75 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -407,7 +407,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData // } - $validator = \Validator::make([$model], \Transaction::$rules); + $validator = \Validator::make([$model], \TransactionJournal::$rules); if ($validator->invalid()) { $errors->merge($errors); } diff --git a/app/lib/FireflyIII/Event/Budget.php b/app/lib/FireflyIII/Event/Budget.php index 063838fe27..087d23c968 100644 --- a/app/lib/FireflyIII/Event/Budget.php +++ b/app/lib/FireflyIII/Event/Budget.php @@ -13,11 +13,9 @@ class Budget */ public function storeOrUpdateLimit(\Limit $limit) { - /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ - $dateKit = \App::make('FireflyIII\Shared\Toolkit\Date'); - $end = $dateKit->addPeriod(clone $limit->startdate, $limit->repeat_freq, 0); + $end = DateKit::addPeriod(clone $limit->startdate, $limit->repeat_freq, 0); $end->subDay(); $set = $limit->limitrepetitions()->where('startdate', $limit->startdate->format('Y-m-d'))->where('enddate', $end->format('Y-m-d'))->get(); diff --git a/app/lib/FireflyIII/FF3ServiceProvider.php b/app/lib/FireflyIII/FF3ServiceProvider.php index 9aba717cfe..65231c2352 100644 --- a/app/lib/FireflyIII/FF3ServiceProvider.php +++ b/app/lib/FireflyIII/FF3ServiceProvider.php @@ -2,6 +2,7 @@ namespace FireflyIII; use FireflyIII\Shared\Validation\FireflyValidator; +use Illuminate\Foundation\AliasLoader; use Illuminate\Support\ServiceProvider; /** @@ -21,6 +22,16 @@ class FF3ServiceProvider extends ServiceProvider ); } + /** + * Return the services bla bla. + * + * @return array + */ + public function provides() + { + return ['reminders', 'filters', 'datekit', 'navigation']; + } + /** * Triggered automatically by Laravel */ @@ -29,12 +40,50 @@ class FF3ServiceProvider extends ServiceProvider // FORMAT: #$this->app->bind('Interface', 'Class'); + $this->app->bind( + 'reminders', function () { + return new \FireflyIII\Shared\Toolkit\Reminders; + } + ); + $this->app->bind( + 'filter', function () { + return new \FireflyIII\Shared\Toolkit\Filter; + } + ); + $this->app->bind( + 'datekit', function () { + return new \FireflyIII\Shared\Toolkit\Date; + } + ); + $this->app->bind( + 'navigation', function () { + return new \FireflyIII\Shared\Toolkit\Navigation; + } + ); + $this->app->bind( + 'ffform', function () { + return new \FireflyIII\Shared\Toolkit\Form; + } + ); + // preferences: $this->app->bind('FireflyIII\Shared\Preferences\PreferencesInterface', 'FireflyIII\Shared\Preferences\Preferences'); // registration and user mail: $this->app->bind('FireflyIII\Shared\Mail\RegistrationInterface', 'FireflyIII\Shared\Mail\Registration'); + // Shortcut so developers don't need to add an Alias in app/config/app.php + $this->app->booting( + function () { + $loader = AliasLoader::getInstance(); + $loader->alias('Reminders', 'FireflyIII\Shared\Facade\Reminders'); + $loader->alias('Filter', 'FireflyIII\Shared\Facade\Filter'); + $loader->alias('DateKit', 'FireflyIII\Shared\Facade\DateKit'); + $loader->alias('Navigation', 'FireflyIII\Shared\Facade\Navigation'); + $loader->alias('FFForm', 'FireflyIII\Shared\Facade\FFForm'); + } + ); + } } \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Facade/DateKit.php b/app/lib/FireflyIII/Shared/Facade/DateKit.php new file mode 100644 index 0000000000..387d3c7372 --- /dev/null +++ b/app/lib/FireflyIII/Shared/Facade/DateKit.php @@ -0,0 +1,16 @@ +remindersable)) { case 'Piggybank': @@ -34,7 +31,7 @@ class Reminders $reminders = 0; while ($start <= $end) { $reminders++; - $start = $dateKit->addPeriod($start, $reminder->remindersable->reminder, $reminder->remindersable->reminder_skip); + $start = DateKit::addPeriod($start, $reminder->remindersable->reminder, $reminder->remindersable->reminder_skip); } /* * Now find amount yet to save. @@ -49,9 +46,6 @@ class Reminders throw new FireflyException('Cannot handle class ' . get_class($reminder->remindersable) . ' in amountForReminder.'); break; } - - - return 50; } /** @@ -77,10 +71,6 @@ class Reminders /** @var \FireflyIII\Database\Piggybank $repository */ $repository = \App::make('FireflyIII\Database\Piggybank'); - /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ - $dateKit = \App::make('FireflyIII\Shared\Toolkit\Date'); - - /** @var Collection $piggybanks */ $piggybanks = $repository->get(); $set = $piggybanks->filter( @@ -100,12 +90,12 @@ class Reminders */ /** @var \PiggybankRepetition $repetition */ $repetition = $piggybank->currentRelevantRep(); - $start = $dateKit->startOfPeriod(Carbon::now(), $piggybank->reminder); + $start = DateKit::startOfPeriod(Carbon::now(), $piggybank->reminder); if ($repetition->targetdate && $repetition->targetdate <= Carbon::now()) { // break when no longer relevant: continue; } - $end = $dateKit->endOfPeriod(clone $start, $piggybank->reminder); + $end = DateKit::endOfPeriod(clone $start, $piggybank->reminder); // should have a reminder for this period: /** @var \Collection $reminders */ $reminders = $piggybank->reminders()->dateIs($start, $end)->get(); diff --git a/app/models/RecurringTransaction.php b/app/models/RecurringTransaction.php index db852bfea9..7c54f69e1c 100644 --- a/app/models/RecurringTransaction.php +++ b/app/models/RecurringTransaction.php @@ -83,6 +83,7 @@ class RecurringTransaction extends Ardent return $this->hasMany('TransactionJournal'); } + /** * TODO remove this method in favour of something in the FireflyIII libraries. * @@ -92,9 +93,6 @@ class RecurringTransaction extends Ardent public function nextExpectedMatch() { - /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */ - $dateKit = App::make('FireflyIII\Shared\Toolkit\Date'); - /* * The date Firefly tries to find. If this stays null, it's "unknown". */ @@ -104,14 +102,14 @@ class RecurringTransaction extends Ardent * $today is the start of the next period, to make sure FF3 won't miss anything * when the current period has a transaction journal. */ - $today = $dateKit->addPeriod(new Carbon, $this->repeat_freq, 0); + $today = DateKit::addPeriod(new Carbon, $this->repeat_freq, 0); /* * FF3 loops from the $start of the recurring transaction, and to make sure * $skip works, it adds one (for modulo). */ $skip = $this->skip + 1; - $start = $dateKit->startOfPeriod(new Carbon, $this->repeat_freq); + $start = DateKit::startOfPeriod(new Carbon, $this->repeat_freq); /* * go back exactly one month/week/etc because FF3 does not care about 'next' * recurring transactions if they're too far into the past. @@ -124,7 +122,7 @@ class RecurringTransaction extends Ardent while ($start <= $today) { if (($counter % $skip) == 0) { // do something. - $end = $dateKit->endOfPeriod(clone $start, $this->repeat_freq); + $end = DateKit::endOfPeriod(clone $start, $this->repeat_freq); $journalCount = $this->transactionjournals()->before($end)->after($start)->count(); if ($journalCount == 0) { $finalDate = clone $start; @@ -133,7 +131,7 @@ class RecurringTransaction extends Ardent } // add period for next round! - $start = $dateKit->addPeriod($start, $this->repeat_freq, 0); + $start = DateKit::addPeriod($start, $this->repeat_freq, 0); $counter++; } diff --git a/app/models/Reminder.php b/app/models/Reminder.php index 7742909eef..a8d02ee414 100644 --- a/app/models/Reminder.php +++ b/app/models/Reminder.php @@ -15,7 +15,7 @@ use LaravelBook\Ardent\Ardent; * @property boolean $active * @property integer $remembersable_id * @property string $remembersable_type - * @property-read \ $remindersable + * @property-read \Piggybank $remindersable * @property-read \User $user * @property mixed $data * @method static \Illuminate\Database\Query\Builder|\Reminder whereId($value) @@ -62,6 +62,8 @@ class Reminder extends Eloquent { return $this->belongsTo('User'); } + + public function scopeDateIs($query, Carbon $start, Carbon $end) { return $query->where('startdate', $start->format('Y-m-d'))->where('enddate', $end->format('Y-m-d')); diff --git a/app/views/reminders/show.blade.php b/app/views/reminders/show.blade.php index 30e8f544e7..34d02d9865 100644 --- a/app/views/reminders/show.blade.php +++ b/app/views/reminders/show.blade.php @@ -15,6 +15,7 @@ Somewhere between {{$reminder->startdate->format('j F Y')}} and {{$reminder->enddate->format('j F Y')}} you should deposit {{mf($amount)}} in piggy bank {{{$reminder->remindersable->name}}} in order to make your goal of saving {{mf($reminder->remindersable->targetamount)}} on {{$reminder->remindersable->targetdate->format('j F Y')}} + @endif

diff --git a/bootstrap/start.php b/bootstrap/start.php index ac8176b74e..df2b9bde6c 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -102,13 +102,17 @@ Event::subscribe('FireflyIII\Event\TransactionJournal'); // event for when the non-repeating piggy bank is updated because the single repetition must also be changed. // (also make piggy bank events "invalid" when they start falling outside of the date-scope of the piggy bank, // although this not changes the amount in the piggy bank). -// TODO check if recurring transactions are being updated when journals are updated (aka no longer fitting, thus removed). -// TODO think about reminders. -// TODO an event that triggers and creates a limit + limit repetition when a budget is created, or something? -// TODO has many through needs to be added wherever relevant. Account > journals, etc. -// TODO check all models for "external" methods once more. -// TODO Auth::user() should be used very sparsely. -// TODO direct calls to models are BAD -// TODO cleanup everything related to reminders because it still feels a bit sloppy. -// TODO use a Database\Reminder thing instead of self-made ORM. +// check if recurring transactions are being updated when journals are updated (aka no longer fitting, thus removed). +// think about reminders. +// an event that triggers and creates a limit + limit repetition when a budget is created, or something? +// has many through needs to be added wherever relevant. Account > journals, etc. +// check all models for "external" methods once more. +// Auth::user() should be used very sparsely. +// direct calls to models are BAD +// cleanup everything related to reminders because it still feels a bit sloppy. +// use a Database\Reminder thing instead of self-made ORM. +// TODO create static calls instead of all the App::make() things. +// TODO see if the various has-many-throughs actually get used. +// TODO set very tight rules on all models +// TODO create custom uniquely rules. return $app; From 78886e7b1f7c10be23148304010d92ad0164b19f Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 21 Nov 2014 11:18:02 +0100 Subject: [PATCH 096/193] Updated git ignore. --- app/config/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/config/.gitignore b/app/config/.gitignore index 3415788027..8205aab29b 100644 --- a/app/config/.gitignore +++ b/app/config/.gitignore @@ -1,3 +1,4 @@ local/ laptop/ -vagrant/ \ No newline at end of file +vagrant/ +production/ \ No newline at end of file From 36f6bda525ae51b495ad5fa1deb08bbe58d098bc Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 21 Nov 2014 11:21:48 +0100 Subject: [PATCH 097/193] Fixed a namespace bug. --- app/lib/FireflyIII/Shared/Toolkit/Reminders.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/lib/FireflyIII/Shared/Toolkit/Reminders.php b/app/lib/FireflyIII/Shared/Toolkit/Reminders.php index 8b539964d9..453f6e7926 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Reminders.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Reminders.php @@ -31,7 +31,7 @@ class Reminders $reminders = 0; while ($start <= $end) { $reminders++; - $start = DateKit::addPeriod($start, $reminder->remindersable->reminder, $reminder->remindersable->reminder_skip); + $start = \DateKit::addPeriod($start, $reminder->remindersable->reminder, $reminder->remindersable->reminder_skip); } /* * Now find amount yet to save. @@ -90,12 +90,12 @@ class Reminders */ /** @var \PiggybankRepetition $repetition */ $repetition = $piggybank->currentRelevantRep(); - $start = DateKit::startOfPeriod(Carbon::now(), $piggybank->reminder); + $start = \DateKit::startOfPeriod(Carbon::now(), $piggybank->reminder); if ($repetition->targetdate && $repetition->targetdate <= Carbon::now()) { // break when no longer relevant: continue; } - $end = DateKit::endOfPeriod(clone $start, $piggybank->reminder); + $end = \DateKit::endOfPeriod(clone $start, $piggybank->reminder); // should have a reminder for this period: /** @var \Collection $reminders */ $reminders = $piggybank->reminders()->dateIs($start, $end)->get(); From 13c2db53785ac1adbac1d4f0177efbe983d73506 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 21 Nov 2014 19:18:44 +0100 Subject: [PATCH 098/193] Removed some todo's --- app/controllers/TransactionController.php | 3 --- bootstrap/start.php | 8 ++++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 7a8cbdcae0..048c470ce5 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -351,9 +351,6 @@ class TransactionController extends BaseController */ public function update(TransactionJournal $journal) { - /* - * TODO if the piggybank_id is set to 0, does this undo all piggy bank event(s)? - */ /** @var \FireflyIII\Database\TransactionJournal $repos */ $repos = App::make('FireflyIII\Database\TransactionJournal'); diff --git a/bootstrap/start.php b/bootstrap/start.php index df2b9bde6c..3f375d48cf 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -111,8 +111,8 @@ Event::subscribe('FireflyIII\Event\TransactionJournal'); // direct calls to models are BAD // cleanup everything related to reminders because it still feels a bit sloppy. // use a Database\Reminder thing instead of self-made ORM. -// TODO create static calls instead of all the App::make() things. -// TODO see if the various has-many-throughs actually get used. -// TODO set very tight rules on all models -// TODO create custom uniquely rules. +// create static calls instead of all the App::make() things. +// see if the various has-many-throughs actually get used. +// set very tight rules on all models +// create custom uniquely rules. return $app; From 6d4303aa3f64ee241ab46c15ee570d536d0d99cf Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 21 Nov 2014 19:18:53 +0100 Subject: [PATCH 099/193] Clone Carbon. --- app/lib/FireflyIII/Shared/Toolkit/Date.php | 57 +++++----------------- 1 file changed, 11 insertions(+), 46 deletions(-) diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index e7cbe65c13..9467133f22 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -13,15 +13,16 @@ use FireflyIII\Exception\FireflyException; class Date { /** - * @param Carbon $date + * @param Carbon $theDate * @param $repeatFreq * @param $skip * * @return Carbon * @throws FireflyException */ - public function addPeriod(Carbon $date, $repeatFreq, $skip) + public function addPeriod(Carbon $theDate, $repeatFreq, $skip) { + $date = clone $theDate; // TODO clone the dates so referred date won't be altered. $add = ($skip + 1); switch ($repeatFreq) { @@ -56,13 +57,15 @@ class Date } /** - * @param Carbon $currentEnd + * @param Carbon $theCurrentEnd * @param $repeatFreq * + * @return mixed * @throws FireflyException */ - public function endOfPeriod(Carbon $currentEnd, $repeatFreq) + public function endOfPeriod(Carbon $theCurrentEnd, $repeatFreq) { + $currentEnd = clone $theCurrentEnd; switch ($repeatFreq) { default: throw new FireflyException('Cannot do endOfPeriod for $repeat_freq ' . $repeatFreq); @@ -93,14 +96,15 @@ class Date } /** - * @param Carbon $date + * @param Carbon $theDate * @param $repeatFreq * * @return Carbon * @throws FireflyException */ - public function startOfPeriod(Carbon $date, $repeatFreq) + public function startOfPeriod(Carbon $theDate, $repeatFreq) { + $date = clone $theDate; switch ($repeatFreq) { default: throw new FireflyException('Cannot do startOfPeriod for $repeat_freq ' . $repeatFreq); @@ -133,43 +137,4 @@ class Date return $date; } - - /** - * @param Carbon $date - * @param $repeatFreq - * @param int $substract - * - * @return Carbon - * @throws FireflyException - */ - public function substractPeriod(Carbon $date, $repeatFreq, $substract = 1) - { - switch ($repeatFreq) { - default: - throw new FireflyException('Cannot do addPeriod for $repeat_freq ' . $repeatFreq); - break; - case 'daily': - $date->subDays($substract); - break; - case 'weekly': - $date->subWeeks($substract); - break; - case 'monthly': - $date->subMonths($substract); - break; - case 'quarterly': - $months = $substract * 3; - $date->subMonths($months); - break; - case 'half-year': - $months = $substract * 6; - $date->subMonths($months); - break; - case 'yearly': - $date->subYears($substract); - break; - } - - return $date; - } -} \ No newline at end of file +} \ No newline at end of file From 43e738cb44d7e6f0362addb93ce62fcfe6ffc846 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 21 Nov 2014 19:19:06 +0100 Subject: [PATCH 100/193] Remove todo --- app/lib/FireflyIII/Shared/Toolkit/Date.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index 9467133f22..b011716bd6 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -23,7 +23,6 @@ class Date public function addPeriod(Carbon $theDate, $repeatFreq, $skip) { $date = clone $theDate; - // TODO clone the dates so referred date won't be altered. $add = ($skip + 1); switch ($repeatFreq) { default: From 6381408fba101206ac03013de512fbd44c69bdfa Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 21 Nov 2014 19:33:09 +0100 Subject: [PATCH 101/193] Remove some often used long calls with shorter ones. --- app/controllers/GoogleChartController.php | 14 +++------ app/controllers/PiggybankController.php | 2 +- app/lib/FireflyIII/Database/Piggybank.php | 2 +- app/lib/FireflyIII/FF3ServiceProvider.php | 10 ++++++ app/lib/FireflyIII/Shared/Facade/Steam.php | 16 ++++++++++ app/lib/FireflyIII/Shared/Toolkit/Steam.php | 34 +++++++++++++++++++++ app/models/Account.php | 20 ------------ app/views/list/accounts.blade.php | 2 +- 8 files changed, 67 insertions(+), 33 deletions(-) create mode 100644 app/lib/FireflyIII/Shared/Facade/Steam.php create mode 100644 app/lib/FireflyIII/Shared/Toolkit/Steam.php diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index 1aec3d005c..700b29f575 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -29,7 +29,7 @@ class GoogleChartController extends BaseController if ($current > Carbon::now()) { $row[] = null; } else { - $row[] = $account->balance($current); + $row[] = Steam::balance($account, $current); } $chart->addRowArray($row); @@ -203,12 +203,7 @@ class GoogleChartController extends BaseController $row = [clone $current]; foreach ($accounts as $account) { - //if ($current > Carbon::now()) { - // $row[] = 0; - //} else { - $row[] = $account->balance($current); - //} - + $row[] = Steam::balance($account, $current); } $chart->addRowArray($row); @@ -573,8 +568,7 @@ class GoogleChartController extends BaseController /* * Get end of period for $current: */ - $currentEnd = clone $current; - DateKit::endOfPeriod($currentEnd, $entry->repeat_freq); + $currentEnd = DateKit::endOfPeriod($current, $entry->repeat_freq); /* * In the current session range? @@ -599,7 +593,7 @@ class GoogleChartController extends BaseController /* * Add some time for the next loop! */ - DateKit::addPeriod($current, $entry->repeat_freq, intval($entry->skip)); + $current = DateKit::addPeriod($current, $entry->repeat_freq, intval($entry->skip)); } diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index 15bc390f62..08ba47d26a 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -137,7 +137,7 @@ class PiggybankController extends BaseController */ $account = $piggybank->account; if (!isset($accounts[$account->id])) { - $accounts[$account->id] = ['name' => $account->name, 'balance' => $account->balance(), + $accounts[$account->id] = ['name' => $account->name, 'balance' => Steam::balance($account), 'leftForPiggybanks' => $repos->leftOnAccount($account), 'sumOfSaved' => $piggybank->savedSoFar, 'sumOfTargets' => floatval($piggybank->targetamount), 'leftToSave' => $piggybank->leftToSave]; } else { diff --git a/app/lib/FireflyIII/Database/Piggybank.php b/app/lib/FireflyIII/Database/Piggybank.php index a05bcbe7cd..7534796a7d 100644 --- a/app/lib/FireflyIII/Database/Piggybank.php +++ b/app/lib/FireflyIII/Database/Piggybank.php @@ -264,7 +264,7 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface */ public function leftOnAccount(\Account $account) { - $balance = $account->balance(); + $balance = Steam::balance($account); /** @var \Piggybank $p */ foreach ($account->piggybanks()->get() as $p) { $balance -= $p->currentRelevantRep()->currentamount; diff --git a/app/lib/FireflyIII/FF3ServiceProvider.php b/app/lib/FireflyIII/FF3ServiceProvider.php index 65231c2352..5069de9eae 100644 --- a/app/lib/FireflyIII/FF3ServiceProvider.php +++ b/app/lib/FireflyIII/FF3ServiceProvider.php @@ -66,6 +66,15 @@ class FF3ServiceProvider extends ServiceProvider } ); + /* + * For models, various stuff: + */ + $this->app->bind( + 'steam', function() { + return new \FireflyIII\Shared\Toolkit\Steam; + } + ); + // preferences: $this->app->bind('FireflyIII\Shared\Preferences\PreferencesInterface', 'FireflyIII\Shared\Preferences\Preferences'); @@ -81,6 +90,7 @@ class FF3ServiceProvider extends ServiceProvider $loader->alias('DateKit', 'FireflyIII\Shared\Facade\DateKit'); $loader->alias('Navigation', 'FireflyIII\Shared\Facade\Navigation'); $loader->alias('FFForm', 'FireflyIII\Shared\Facade\FFForm'); + $loader->alias('Steam', 'FireflyIII\Shared\Facade\Steam'); } ); diff --git a/app/lib/FireflyIII/Shared/Facade/Steam.php b/app/lib/FireflyIII/Shared/Facade/Steam.php new file mode 100644 index 0000000000..7b21a65619 --- /dev/null +++ b/app/lib/FireflyIII/Shared/Facade/Steam.php @@ -0,0 +1,16 @@ +transactions()->leftJoin( + 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' + )->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount') + ); + } + +} \ No newline at end of file diff --git a/app/models/Account.php b/app/models/Account.php index e20e8f58ce..ad6f210b67 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -57,26 +57,6 @@ class Account extends Ardent return $this->belongsTo('AccountType'); } - /** - * Get an accounts current balance. - * - * TODO remove this method in favour of something in the FireflyIII libraries. - * - * @param \Carbon\Carbon $date - * - * @return float - */ - public function balance(\Carbon\Carbon $date = null) - { - $date = is_null($date) ? new \Carbon\Carbon : $date; - - return floatval( - $this->transactions()->leftJoin( - 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' - )->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount') - ); - } - /** * Transactions. * diff --git a/app/views/list/accounts.blade.php b/app/views/list/accounts.blade.php index 263a88aa32..a803498da6 100644 --- a/app/views/list/accounts.blade.php +++ b/app/views/list/accounts.blade.php @@ -15,7 +15,7 @@

{{{$account->name}}} - {{mf($account->balance())}} + {{mf(Steam::balance($account))}} @if($account->active) From f0f965421c00029438365df03d5689f34cf547de Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 07:30:46 +0100 Subject: [PATCH 102/193] Implemented some todo's. --- app/controllers/TransactionController.php | 15 ++++++++++ app/models/Account.php | 20 ------------- app/views/reminders/show.blade.php | 1 - app/views/transactions/show.blade.php | 2 +- bootstrap/start.php | 2 ++ public/assets/javascript/firefly/gcharts.js | 31 ++++++++++----------- public/index.php | 4 +-- 7 files changed, 33 insertions(+), 42 deletions(-) diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 048c470ce5..1f5caa78f6 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -277,6 +277,21 @@ class TransactionController extends BaseController */ public function show(TransactionJournal $journal) { + $journal->transactions->each( + function(\Transaction $t) use ($journal) { + $t->before = floatval( + $t->account->transactions()->leftJoin( + 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' + )->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d'))->where( + 'transaction_journals.created_at', '<=', $journal->created_at->format('Y-m-d H:i:s') + )->where('transaction_journals.id', '!=', $journal->id)->sum('transactions.amount') + ); + $t->after = $t->before + $t->amount; + } + ); + + + return View::make('transactions.show')->with('journal', $journal)->with( 'subTitle', $journal->transactionType->type . ' "' . $journal->description . '"' ); diff --git a/app/models/Account.php b/app/models/Account.php index ad6f210b67..63f6790b48 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -66,26 +66,6 @@ class Account extends Ardent { return $this->hasMany('Transaction'); } - - /** - * - * TODO remove this method in favour of something in the FireflyIII libraries. - * - * @param TransactionJournal $journal - * - * @return float - */ - public function balanceBeforeJournal(TransactionJournal $journal) - { - return floatval( - $this->transactions()->leftJoin( - 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' - )->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d'))->where( - 'transaction_journals.created_at', '<=', $journal->created_at->format('Y-m-d H:i:s') - )->where('transaction_journals.id', '!=', $journal->id)->sum('transactions.amount') - ); - } - /** * TODO remove this method in favour of something in the FireflyIII libraries. * diff --git a/app/views/reminders/show.blade.php b/app/views/reminders/show.blade.php index 34d02d9865..0b12c927c5 100644 --- a/app/views/reminders/show.blade.php +++ b/app/views/reminders/show.blade.php @@ -19,7 +19,6 @@ @endif

- I want to do this I already did this Not this time diff --git a/app/views/transactions/show.blade.php b/app/views/transactions/show.blade.php index b4c3eb5414..3339468ef4 100644 --- a/app/views/transactions/show.blade.php +++ b/app/views/transactions/show.blade.php @@ -74,7 +74,7 @@ New balance - {{mf($t->account->balanceBeforeJournal($journal))}} → {{mf($t->account->balanceBeforeJournal($journal) + $t->amount)}} + {{mf($t->before)}} → {{mf($t->after)}} @if(!is_null($t->description)) diff --git a/bootstrap/start.php b/bootstrap/start.php index 3f375d48cf..e05212f1db 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -115,4 +115,6 @@ Event::subscribe('FireflyIII\Event\TransactionJournal'); // see if the various has-many-throughs actually get used. // set very tight rules on all models // create custom uniquely rules. +// TODO add "Create new X" button to any list there is: categories, accounts, piggies, etc. +// TODO Install PHP5 and code thing and create very small methods. return $app; diff --git a/public/assets/javascript/firefly/gcharts.js b/public/assets/javascript/firefly/gcharts.js index 3636599c68..c0bc5dd090 100644 --- a/public/assets/javascript/firefly/gcharts.js +++ b/public/assets/javascript/firefly/gcharts.js @@ -1,9 +1,6 @@ google.load('visualization', '1.1', {'packages': ['corechart', 'bar', 'sankey', 'table']}); -/* -TODO manage the combination of default options AND custom options. - */ -function googleLineChart(URL, container) { +function googleLineChart(URL, container, options) { if ($('#' + container).length == 1) { $.getJSON(URL).success(function (data) { /* @@ -31,7 +28,7 @@ function googleLineChart(URL, container) { /* Draw it: */ - chart.draw(gdata, defaultLineChartOptions); + chart.draw(gdata, options || defaultLineChartOptions); }).fail(function () { $('#' + container).addClass('google-chart-error'); @@ -41,7 +38,7 @@ function googleLineChart(URL, container) { } } -function googleBarChart(URL, container) { +function googleBarChart(URL, container, options) { if ($('#' + container).length == 1) { $.getJSON(URL).success(function (data) { /* @@ -69,7 +66,7 @@ function googleBarChart(URL, container) { /* Draw it: */ - chart.draw(gdata, defaultBarChartOptions); + chart.draw(gdata, options || defaultBarChartOptions); }).fail(function () { $('#' + container).addClass('google-chart-error'); @@ -79,7 +76,7 @@ function googleBarChart(URL, container) { } } -function googleColumnChart(URL, container) { +function googleColumnChart(URL, container, options) { if ($('#' + container).length == 1) { $.getJSON(URL).success(function (data) { /* @@ -106,7 +103,7 @@ function googleColumnChart(URL, container) { /* Draw it: */ - chart.draw(gdata, defaultColumnChartOptions); + chart.draw(gdata, options || defaultColumnChartOptions); }).fail(function () { $('#' + container).addClass('google-chart-error'); @@ -116,7 +113,7 @@ function googleColumnChart(URL, container) { } } -function googleStackedColumnChart(URL, container) { +function googleStackedColumnChart(URL, container, options) { if ($('#' + container).length == 1) { $.getJSON(URL).success(function (data) { /* @@ -143,7 +140,7 @@ function googleStackedColumnChart(URL, container) { /* Draw it: */ - chart.draw(gdata, defaultStackedColumnChartOptions); + chart.draw(gdata, options || defaultStackedColumnChartOptions); }).fail(function () { $('#' + container).addClass('google-chart-error'); @@ -153,7 +150,7 @@ function googleStackedColumnChart(URL, container) { } } -function googleComboChart(URL, container) { +function googleComboChart(URL, container, options) { if ($('#' + container).length == 1) { $.getJSON(URL).success(function (data) { /* @@ -180,7 +177,7 @@ function googleComboChart(URL, container) { /* Draw it: */ - chart.draw(gdata, defaultComboChartOptions); + chart.draw(gdata, options || defaultComboChartOptions); }).fail(function () { $('#' + container).addClass('google-chart-error'); @@ -190,7 +187,7 @@ function googleComboChart(URL, container) { } } -function googlePieChart(URL, container) { +function googlePieChart(URL, container, options) { if ($('#' + container).length == 1) { $.getJSON(URL).success(function (data) { /* @@ -218,7 +215,7 @@ function googlePieChart(URL, container) { /* Draw it: */ - chart.draw(gdata, defaultPieChartOptions); + chart.draw(gdata, options || defaultPieChartOptions); }).fail(function () { $('#' + container).addClass('google-chart-error'); @@ -228,7 +225,7 @@ function googlePieChart(URL, container) { } } -function googleSankeyChart(URL, container) { +function googleSankeyChart(URL, container, options) { if ($('#' + container).length == 1) { $.getJSON(URL).success(function (data) { /* @@ -258,7 +255,7 @@ function googleSankeyChart(URL, container) { /* Draw it: */ - chart.draw(gdata, defaultSankeyChartOptions); + chart.draw(gdata, options || defaultSankeyChartOptions); }).fail(function () { $('#' + container).addClass('google-chart-error'); diff --git a/public/index.php b/public/index.php index c4f34cbfec..50f994dcdc 100644 --- a/public/index.php +++ b/public/index.php @@ -20,9 +20,7 @@ require __DIR__.'/../bootstrap/autoload.php'; -/* - * TODO: add "Create new X" button to any list there is: categories, accounts, piggies, etc. - */ + /* |-------------------------------------------------------------------------- From 5df06343800c36809ec6d2f3b74da3bb6ca044ac Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 07:34:08 +0100 Subject: [PATCH 103/193] Cleanup. --- app/models/Account.php | 1 - app/models/Reminder.php | 24 ++++++++++++++---------- app/models/TransactionCurrency.php | 1 + app/models/TransactionJournal.php | 4 ++++ app/models/User.php | 1 + scripts/ide-helper.bat | 7 ------- scripts/local-cleanup-reload.sh | 30 ------------------------------ scripts/local-reset.sh | 2 -- scripts/vagrant-load.sh | 27 --------------------------- scripts/vagrant-migrate.sh | 2 -- scripts/vagrant-reset.sh | 2 -- 11 files changed, 20 insertions(+), 81 deletions(-) delete mode 100644 scripts/ide-helper.bat delete mode 100755 scripts/local-cleanup-reload.sh delete mode 100755 scripts/local-reset.sh delete mode 100755 scripts/vagrant-load.sh delete mode 100755 scripts/vagrant-migrate.sh delete mode 100755 scripts/vagrant-reset.sh diff --git a/app/models/Account.php b/app/models/Account.php index 63f6790b48..896ef8820a 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -5,7 +5,6 @@ use LaravelBook\Ardent\Builder; /** - * * Account * * @property integer $id diff --git a/app/models/Reminder.php b/app/models/Reminder.php index a8d02ee414..3ecb0387eb 100644 --- a/app/models/Reminder.php +++ b/app/models/Reminder.php @@ -18,16 +18,20 @@ use LaravelBook\Ardent\Ardent; * @property-read \Piggybank $remindersable * @property-read \User $user * @property mixed $data - * @method static \Illuminate\Database\Query\Builder|\Reminder whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereStartdate($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereEnddate($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereActive($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereRemembersableId($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereRemembersableType($value) - * @method static \Reminder dateIs($start, $end) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereStartdate($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereEnddate($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereActive($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereRemembersableId($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereRemembersableType($value) + * @method static \Reminder dateIs($start, $end) + * @property integer $remindersable_id + * @property string $remindersable_type + * @method static \Illuminate\Database\Query\Builder|\Reminder whereRemindersableId($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereRemindersableType($value) */ class Reminder extends Eloquent { diff --git a/app/models/TransactionCurrency.php b/app/models/TransactionCurrency.php index 6c1aa0da36..0d7dd981aa 100644 --- a/app/models/TransactionCurrency.php +++ b/app/models/TransactionCurrency.php @@ -14,6 +14,7 @@ use Illuminate\Database\Eloquent\Model as Eloquent; * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereCreatedAt($value) * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereUpdatedAt($value) * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereCode($value) + * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionJournals */ class TransactionCurrency extends Eloquent { diff --git a/app/models/TransactionJournal.php b/app/models/TransactionJournal.php index 171e7103ca..9e51ceefd2 100644 --- a/app/models/TransactionJournal.php +++ b/app/models/TransactionJournal.php @@ -52,6 +52,10 @@ use LaravelBook\Ardent\Builder; * 'Budget[] $budgets * @property-read \Illuminate\Database\Eloquent\Collection|\ * 'Category[] $categories + * @property-read \Illuminate\Database\Eloquent\Collection|\ + * 'Budget[] $budgets + * @property-read \Illuminate\Database\Eloquent\Collection|\ + * 'Category[] $categories */ class TransactionJournal extends Ardent { diff --git a/app/models/User.php b/app/models/User.php index e92041ac74..01d7372773 100644 --- a/app/models/User.php +++ b/app/models/User.php @@ -32,6 +32,7 @@ use LaravelBook\Ardent\Ardent; * @method static \Illuminate\Database\Query\Builder|\User whereReset($value) * @method static \Illuminate\Database\Query\Builder|\User whereRememberToken($value) * @method static \Illuminate\Database\Query\Builder|\User whereMigrated($value) + * @property-read \Illuminate\Database\Eloquent\Collection|\Reminder[] $reminders */ class User extends Ardent implements UserInterface, RemindableInterface { diff --git a/scripts/ide-helper.bat b/scripts/ide-helper.bat deleted file mode 100644 index 8ef2cc915c..0000000000 --- a/scripts/ide-helper.bat +++ /dev/null @@ -1,7 +0,0 @@ -REM composer self-update -composer update -php artisan clear-compiled --env=local -php artisan ide-helper:generate --env=local -php artisan ide-helper:models --env=local --write -php artisan optimize --env=local -php artisan dump-autoload --env=local \ No newline at end of file diff --git a/scripts/local-cleanup-reload.sh b/scripts/local-cleanup-reload.sh deleted file mode 100755 index 673296e4d2..0000000000 --- a/scripts/local-cleanup-reload.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -cd .. -composer self-update -composer update -rm -f ./app/storage/firefly-iii-import-*.json -rm -f ./app/storage/debugbar/*.json -rm -f ./app/storage/logs/larave*.log -rm -f ./app/storage/meta/services.json - -for i in `seq 0 9`; -do - rm -f ./app/storage/views/$i* -done - -rm -f ./app/storage/views/a* -rm -f ./app/storage/views/b* -rm -f ./app/storage/views/c* -rm -f ./app/storage/views/d* -rm -f ./app/storage/views/e* -rm -f ./app/storage/views/f* - - - -php artisan clear-compiled --env=local -php artisan ide-helper:generate --env=local -php artisan ide-helper:models --env=local --write -php artisan optimize --env=local -php artisan dump-autoload --env=local -cd scripts -./local-reset.sh diff --git a/scripts/local-reset.sh b/scripts/local-reset.sh deleted file mode 100755 index 963fbd1377..0000000000 --- a/scripts/local-reset.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -php ../artisan migrate:refresh --seed --env=local \ No newline at end of file diff --git a/scripts/vagrant-load.sh b/scripts/vagrant-load.sh deleted file mode 100755 index b7e0f3987c..0000000000 --- a/scripts/vagrant-load.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -composer self-update -composer update -rm -f ../app/storage/firefly-iii-import-*.json -rm -f ../app/storage/debugbar/*.json -rm -f ../app/storage/logs/laravel.log -rm -f ../app/storage/meta/services.json - -for i in `seq 0 9`; -do - rm -f ../app/storage/views/$i* -done - -rm -f ../app/storage/views/a* -rm -f ../app/storage/views/b* -rm -f ../app/storage/views/c* -rm -f ../app/storage/views/d* -rm -f ../app/storage/views/e* -rm -f ../app/storage/views/f* - - -php ../artisan clear-compiled --env=vagrant -php ../artisan ide-helper:generate --env=vagrant -php ../artisan ide-helper:models --env=vagrant --write -php ../artisan optimize --env=vagrant -php ../artisan dump-autoload --env=vagrant -./vagrant-reset.sh diff --git a/scripts/vagrant-migrate.sh b/scripts/vagrant-migrate.sh deleted file mode 100755 index df52192d0c..0000000000 --- a/scripts/vagrant-migrate.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -php ../artisan migrate --seed --env=vagrant \ No newline at end of file diff --git a/scripts/vagrant-reset.sh b/scripts/vagrant-reset.sh deleted file mode 100755 index cc949cb9cf..0000000000 --- a/scripts/vagrant-reset.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -php ../artisan migrate:refresh --seed --env=vagrant \ No newline at end of file From 10b969a074c9054f224da1d875b30bea4eb8e9f1 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 08:17:37 +0100 Subject: [PATCH 104/193] New cleanup command for artisan --- app/commands/Cleanup.php | 77 +++++++++++++++++++++++++++++++ app/models/Account.php | 37 ++++++++------- app/models/Reminder.php | 4 +- app/models/TransactionJournal.php | 4 ++ app/start/artisan.php | 1 + 5 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 app/commands/Cleanup.php diff --git a/app/commands/Cleanup.php b/app/commands/Cleanup.php new file mode 100644 index 0000000000..2e5c889068 --- /dev/null +++ b/app/commands/Cleanup.php @@ -0,0 +1,77 @@ +info('Start!'); + Artisan::call('clear-compiled'); + $this->info('Cleared compiled...'); + Artisan::call('ide-helper:generate'); + $this->info('IDE helper, done...'); + Artisan::call('ide-helper:models', ['write']); + $this->info('IDE models, done...'); + Artisan::call('optimize'); + $this->info('Optimized...'); + Artisan::call('dump-autoload'); + $this->info('Done!'); + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + // ['example', InputArgument::REQUIRED, 'An example argument.'], + ]; + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return [ + // ['example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null], + ]; + } + +} diff --git a/app/models/Account.php b/app/models/Account.php index 896ef8820a..03645bbb13 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -3,29 +3,28 @@ use Carbon\Carbon; use LaravelBook\Ardent\Ardent as Ardent; use LaravelBook\Ardent\Builder; - /** * Account * - * @property integer $id - * @property \Carbon\Carbon $created_at - * @property \Carbon\Carbon $updated_at - * @property integer $user_id - * @property integer $account_type_id - * @property string $name - * @property boolean $active - * @property-read \AccountType $accountType + * @property integer $id + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property integer $user_id + * @property integer $account_type_id + * @property string $name + * @property boolean $active + * @property-read \AccountType $accountType * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions - * @property-read \Illuminate\Database\Eloquent\Collection|\Piggybank[] $piggybanks - * @property-read \User $user - * @method static \Illuminate\Database\Query\Builder|\Account whereId($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereCreatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereUpdatedAt($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereUserId($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereAccountTypeId($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereName($value) - * @method static \Illuminate\Database\Query\Builder|\Account whereActive($value) - * @method static \Account accountTypeIn($types) + * @property-read \Illuminate\Database\Eloquent\Collection|\Piggybank[] $piggybanks + * @property-read \User $user + * @method static \Illuminate\Database\Query\Builder|\Account whereId($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereCreatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereUpdatedAt($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereUserId($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereAccountTypeId($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereName($value) + * @method static \Illuminate\Database\Query\Builder|\Account whereActive($value) + * @method static \Account accountTypeIn($types) */ class Account extends Ardent { diff --git a/app/models/Reminder.php b/app/models/Reminder.php index 3ecb0387eb..199c5b66e8 100644 --- a/app/models/Reminder.php +++ b/app/models/Reminder.php @@ -30,8 +30,8 @@ use LaravelBook\Ardent\Ardent; * @method static \Reminder dateIs($start, $end) * @property integer $remindersable_id * @property string $remindersable_type - * @method static \Illuminate\Database\Query\Builder|\Reminder whereRemindersableId($value) - * @method static \Illuminate\Database\Query\Builder|\Reminder whereRemindersableType($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereRemindersableId($value) + * @method static \Illuminate\Database\Query\Builder|\Reminder whereRemindersableType($value) */ class Reminder extends Eloquent { diff --git a/app/models/TransactionJournal.php b/app/models/TransactionJournal.php index 9e51ceefd2..2796563950 100644 --- a/app/models/TransactionJournal.php +++ b/app/models/TransactionJournal.php @@ -56,6 +56,10 @@ use LaravelBook\Ardent\Builder; * 'Budget[] $budgets * @property-read \Illuminate\Database\Eloquent\Collection|\ * 'Category[] $categories + * @property-read \Illuminate\Database\Eloquent\Collection|\ + * 'Budget[] $budgets + * @property-read \Illuminate\Database\Eloquent\Collection|\ + * 'Category[] $categories */ class TransactionJournal extends Ardent { diff --git a/app/start/artisan.php b/app/start/artisan.php index 1df850bc95..3b223f16ec 100644 --- a/app/start/artisan.php +++ b/app/start/artisan.php @@ -11,3 +11,4 @@ | */ +Artisan::add(new Cleanup); \ No newline at end of file From ddf9f52737517ec351ded2b2f55f878209f69ab6 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 08:21:10 +0100 Subject: [PATCH 105/193] Mar cleanup. --- app/controllers/AccountController.php | 12 ++++++++++ app/models/Account.php | 32 +++------------------------ app/views/list/accounts.blade.php | 5 ++--- 3 files changed, 17 insertions(+), 32 deletions(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 427a40e561..ed6eb51257 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -196,6 +196,18 @@ class AccountController extends BaseController break; } + $accounts->each( + function (Account $account) { + $transaction = $account->transactions()->orderBy('updated_at', 'DESC')->first(); + + if (is_null($transaction)) { + $account->lastActionDate = null; + } + + $account->lastActionDate = $transaction->updated_at; + } + ); + return View::make('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts')); } diff --git a/app/models/Account.php b/app/models/Account.php index 03645bbb13..46324baab0 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -64,20 +64,6 @@ class Account extends Ardent { return $this->hasMany('Transaction'); } - /** - * TODO remove this method in favour of something in the FireflyIII libraries. - * - * @return Carbon - */ - public function lastActionDate() - { - $transaction = $this->transactions()->orderBy('updated_at', 'DESC')->first(); - if (is_null($transaction)) { - return null; - } - - return $transaction->updated_at; - } /** * @return \Illuminate\Database\Eloquent\Relations\HasMany @@ -88,21 +74,6 @@ class Account extends Ardent } /** - * TODO remove this method in favour of something in the FireflyIII libraries. - * - * @param \Carbon\Carbon $date - * - * @return null - */ - public function predict( - /** @noinspection PhpUnusedParameterInspection */ - \Carbon\Carbon $date - ) { - return null; - } - - /** - * TODO see if this scope is still used. * * @param Builder $query * @param array $types @@ -116,6 +87,9 @@ class Account extends Ardent $query->whereIn('account_types.type', $types); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough + */ public function transactionjournals() { return $this->hasManyThrough('TransactionJournal', 'Transaction'); diff --git a/app/views/list/accounts.blade.php b/app/views/list/accounts.blade.php index a803498da6..ff48d1fabf 100644 --- a/app/views/list/accounts.blade.php +++ b/app/views/list/accounts.blade.php @@ -24,9 +24,8 @@ @endif - lastActionDate(); ?> - @if($active) - {{{$active->format('j F Y')}}} + @if($account->lastActionDate) + {{{$account->lastActionDate->format('j F Y')}}} @else Never @endif From 34454261d2d33dec9017a6de3c813291c7130425 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 17:17:28 +0100 Subject: [PATCH 106/193] First view for the return of the repeated expenses. --- app/controllers/RepeatedExpenseController.php | 15 +++++++++++++++ app/routes.php | 3 +++ app/views/layouts/default.blade.php | 2 ++ app/views/partials/menu.blade.php | 8 ++++++-- app/views/repeatedexpense/index.blade.php | 13 +++++++++++++ 5 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 app/controllers/RepeatedExpenseController.php create mode 100644 app/views/repeatedexpense/index.blade.php diff --git a/app/controllers/RepeatedExpenseController.php b/app/controllers/RepeatedExpenseController.php new file mode 100644 index 0000000000..f19167ca06 --- /dev/null +++ b/app/controllers/RepeatedExpenseController.php @@ -0,0 +1,15 @@ + 'RecurringController@delete', 'as' => 'recurring.delete']); Route::get('/recurring/show/{recurring}', ['uses' => 'RecurringController@show', 'as' => 'recurring.show']); + // repeated expenses controller: + Route::get('/repeatedexpenses', ['uses' => 'RepeatedExpenseController@index', 'as' => 'repeated.index']); + // report controller: Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']); Route::get('/reports/{year}', ['uses' => 'ReportController@year', 'as' => 'reports.year']); diff --git a/app/views/layouts/default.blade.php b/app/views/layouts/default.blade.php index 508bf49a02..47878d1e04 100644 --- a/app/views/layouts/default.blade.php +++ b/app/views/layouts/default.blade.php @@ -47,7 +47,9 @@ {{$subTitle}} @endif + +

diff --git a/app/views/partials/menu.blade.php b/app/views/partials/menu.blade.php index b571ba27b5..9eb70f8e36 100644 --- a/app/views/partials/menu.blade.php +++ b/app/views/partials/menu.blade.php @@ -137,9 +137,10 @@
  • Money management @@ -150,6 +151,9 @@
  • Recurring transactions
  • +
  • + Repeated expenses +
  • diff --git a/app/views/repeatedexpense/index.blade.php b/app/views/repeatedexpense/index.blade.php new file mode 100644 index 0000000000..f1cf41d48b --- /dev/null +++ b/app/views/repeatedexpense/index.blade.php @@ -0,0 +1,13 @@ +@extends('layouts.default') +@section('content') +
    +
    + +
    +
    + + + +@stop +@section('scripts') +@stop \ No newline at end of file From c6b6ed7fa8f3a7a908bdd27bb7f274670ab9e35d Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:30:45 +0100 Subject: [PATCH 107/193] Removed a bunch of methods and code that wasn't used. Also added a repository for repeated expenses. --- app/lib/FireflyIII/Database/Account.php | 66 +---- app/lib/FireflyIII/Database/AccountType.php | 16 +- app/lib/FireflyIII/Database/Budget.php | 14 -- app/lib/FireflyIII/Database/Category.php | 16 +- .../Database/Ifaces/AccountInterface.php | 23 +- .../Database/Ifaces/AccountTypeInterface.php | 13 - app/lib/FireflyIII/Database/Ifaces/CUD.php | 12 +- .../Database/Ifaces/CategoryInterface.php | 13 - .../Ifaces/RecurringTransactionInterface.php | 12 - .../Database/Ifaces/TransactionInterface.php | 14 -- .../Ifaces/TransactionTypeInterface.php | 14 -- app/lib/FireflyIII/Database/Piggybank.php | 18 +- app/lib/FireflyIII/Database/Recurring.php | 14 -- .../FireflyIII/Database/RepeatedExpense.php | 229 ++++++++++++++++++ app/lib/FireflyIII/Database/Transaction.php | 16 +- .../Database/TransactionCurrency.php | 118 +-------- .../Database/TransactionJournal.php | 14 -- .../FireflyIII/Database/TransactionType.php | 16 +- 18 files changed, 250 insertions(+), 388 deletions(-) delete mode 100644 app/lib/FireflyIII/Database/Ifaces/AccountTypeInterface.php delete mode 100644 app/lib/FireflyIII/Database/Ifaces/CategoryInterface.php delete mode 100644 app/lib/FireflyIII/Database/Ifaces/RecurringTransactionInterface.php delete mode 100644 app/lib/FireflyIII/Database/Ifaces/TransactionInterface.php delete mode 100644 app/lib/FireflyIII/Database/Ifaces/TransactionTypeInterface.php create mode 100644 app/lib/FireflyIII/Database/RepeatedExpense.php diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index b4960b41dd..1b598ac76f 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -81,11 +81,10 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface /** * @param array $types - * @param array $parameters * * @return Collection */ - public function getAccountsByType(array $types, array $parameters = []) + public function getAccountsByType(array $types) { /* * Basic query: @@ -103,10 +102,9 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface /* * Not used, but useful for the balance within a certain month / year. */ - $balanceOnDate = isset($parameters['date']) ? $parameters['date'] : Carbon::now(); $query->where( - function ($q) use ($balanceOnDate) { - $q->where('transaction_journals.date', '<=', $balanceOnDate->format('Y-m-d')); + function ($q) { + $q->where('transaction_journals.date', '<=', Carbon::now()->format('Y-m-d')); $q->orWhereNull('transaction_journals.date'); } ); @@ -118,23 +116,6 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface */ $query->orderBy('name', 'ASC'); - /* - * If present, process parameters for searching. - */ - if (isset($parameters['search'])) { - $query->where('name', 'LIKE', '%' . e($parameters['search']['value'] . '%')); - } - - /* - * If present, start at $start: - */ - if (isset($parameters['start'])) { - $query->skip(intval($parameters['start'])); - } - if (isset($parameters['length'])) { - $query->take(intval($parameters['length'])); - } - return $query->get(['accounts.*', \DB::Raw('SUM(`transactions`.`amount`) as `balance`')]); } @@ -145,43 +126,28 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface * * @return Collection */ - public function getAssetAccounts(array $parameters = []) + public function getAssetAccounts() { - return $this->getAccountsByType(['Default account', 'Asset account'], $parameters); + return $this->getAccountsByType(['Default account', 'Asset account']); } /** - * Get all default accounts. - * * @return Collection */ - public function getDefaultAccounts() + public function getExpenseAccounts() { - // TODO: Implement getDefaultAccounts() method. - throw new NotImplementedException; - } - - /** - * @param array $parameters - * - * @return Collection - */ - public function getExpenseAccounts(array $parameters = []) - { - return $this->getAccountsByType(['Expense account', 'Beneficiary account'], $parameters); + return $this->getAccountsByType(['Expense account', 'Beneficiary account']); } /** * Get all revenue accounts. * - * @param array $parameters - * * @return Collection */ - public function getRevenueAccounts(array $parameters = []) + public function getRevenueAccounts() { - return $this->getAccountsByType(['Revenue account'], $parameters); + return $this->getAccountsByType(['Revenue account']); } /** @@ -397,20 +363,6 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * diff --git a/app/lib/FireflyIII/Database/AccountType.php b/app/lib/FireflyIII/Database/AccountType.php index 302b8b2335..9d945faffa 100644 --- a/app/lib/FireflyIII/Database/AccountType.php +++ b/app/lib/FireflyIII/Database/AccountType.php @@ -15,7 +15,7 @@ use LaravelBook\Ardent\Ardent; * * @package FireflyIII\Database */ -class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls +class AccountType implements CUD, CommonDatabaseCalls { /** @@ -66,20 +66,6 @@ class AccountType implements AccountTypeInterface, CUD, CommonDatabaseCalls throw new NotImplementedException; } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * diff --git a/app/lib/FireflyIII/Database/Budget.php b/app/lib/FireflyIII/Database/Budget.php index 2d4a0474e5..5fc1eeb4f0 100644 --- a/app/lib/FireflyIII/Database/Budget.php +++ b/app/lib/FireflyIII/Database/Budget.php @@ -119,20 +119,6 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * diff --git a/app/lib/FireflyIII/Database/Category.php b/app/lib/FireflyIII/Database/Category.php index 5857f84326..c04d4aa6b7 100644 --- a/app/lib/FireflyIII/Database/Category.php +++ b/app/lib/FireflyIII/Database/Category.php @@ -15,7 +15,7 @@ use LaravelBook\Ardent\Ardent; * * @package FireflyIII\Database */ -class Category implements CUD, CommonDatabaseCalls, CategoryInterface +class Category implements CUD, CommonDatabaseCalls { use SwitchUser; @@ -118,20 +118,6 @@ class Category implements CUD, CommonDatabaseCalls, CategoryInterface return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * diff --git a/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php b/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php index 2871e988f7..614c476556 100644 --- a/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php +++ b/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php @@ -42,12 +42,6 @@ interface AccountInterface */ public function countRevenueAccounts(); - /** - * @param array $parameters - * - * @return Collection - */ - /** * @param \Account $account * @@ -59,38 +53,29 @@ interface AccountInterface * Get all accounts of the selected types. Is also capable of handling DataTables' parameters. * * @param array $types - * @param array $parameters * * @return Collection */ - public function getAccountsByType(array $types, array $parameters = []); + public function getAccountsByType(array $types); /** * Get all asset accounts. The parameters are optional and are provided by the DataTables plugin. * - * @param array $parameters - * * @return Collection */ - public function getAssetAccounts(array $parameters = []); + public function getAssetAccounts(); /** - * Get all default accounts. - * * @return Collection */ - public function getDefaultAccounts(); - - public function getExpenseAccounts(array $parameters = []); + public function getExpenseAccounts(); /** * Get all revenue accounts. * - * @param array $parameters - * * @return Collection */ - public function getRevenueAccounts(array $parameters = []); + public function getRevenueAccounts(); /** * @param \Account $account diff --git a/app/lib/FireflyIII/Database/Ifaces/AccountTypeInterface.php b/app/lib/FireflyIII/Database/Ifaces/AccountTypeInterface.php deleted file mode 100644 index d06621d702..0000000000 --- a/app/lib/FireflyIII/Database/Ifaces/AccountTypeInterface.php +++ /dev/null @@ -1,13 +0,0 @@ -add('date', 'Invalid date.'); + $errors->add('targetdate', 'Invalid date.'); } } if (floatval($model['targetamount']) < 0.01) { @@ -183,20 +183,6 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * @@ -264,7 +250,7 @@ class Piggybank implements CUD, CommonDatabaseCalls, PiggybankInterface */ public function leftOnAccount(\Account $account) { - $balance = Steam::balance($account); + $balance = \Steam::balance($account); /** @var \Piggybank $p */ foreach ($account->piggybanks()->get() as $p) { $balance -= $p->currentRelevantRep()->currentamount; diff --git a/app/lib/FireflyIII/Database/Recurring.php b/app/lib/FireflyIII/Database/Recurring.php index 6329cde2ec..b781b4e611 100644 --- a/app/lib/FireflyIII/Database/Recurring.php +++ b/app/lib/FireflyIII/Database/Recurring.php @@ -177,20 +177,6 @@ class Recurring implements CUD, CommonDatabaseCalls, RecurringInterface return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * diff --git a/app/lib/FireflyIII/Database/RepeatedExpense.php b/app/lib/FireflyIII/Database/RepeatedExpense.php new file mode 100644 index 0000000000..2b50bf6bf1 --- /dev/null +++ b/app/lib/FireflyIII/Database/RepeatedExpense.php @@ -0,0 +1,229 @@ +setUser(\Auth::user()); + } + + /** + * @param Ardent $model + * + * @return bool + */ + public function destroy(Ardent $model) + { + // TODO: Implement destroy() method. + throw new NotImplementedException; + } + + /** + * @param array $data + * + * @return Ardent + */ + public function store(array $data) + { + + $data['rep_every'] = isset($data['rep_every']) ? $data['rep_every'] : 0; + $data['reminder_skip'] = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0; + $data['order'] = isset($data['order']) ? $data['order'] : 0; + $data['remind_me'] = isset($data['remind_me']) ? intval($data['remind_me']) : 0; + $data['startdate'] = isset($data['startdate']) ? $data['startdate'] : Carbon::now()->format('Y-m-d'); + $data['targetdate'] = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null; + $data['account_id'] = intval($data['account_id']); + + + if ($data['remind_me'] == 0) { + $data['reminder'] = null; + } + + + $repeated = new \Piggybank($data); + if (!$repeated->validate()) { + var_dump($repeated->errors()->all()); + exit; + } + $repeated->save(); + + return $repeated; + } + + /** + * @param Ardent $model + * @param array $data + * + * @return bool + */ + public function update(Ardent $model, array $data) + { + // TODO: Implement update() method. + throw new NotImplementedException; + } + + /** + * Validates an array. Returns an array containing MessageBags + * errors/warnings/successes. + * + * @param array $model + * + * @return array + */ + public function validate(array $model) + { + $warnings = new MessageBag; + $successes = new MessageBag; + $errors = new MessageBag; + + /* + * Name validation: + */ + if (!isset($model['name'])) { + $errors->add('name', 'Name is mandatory'); + } + + if (isset($model['name']) && strlen($model['name']) == 0) { + $errors->add('name', 'Name is too short'); + } + if (isset($model['name']) && strlen($model['name']) > 100) { + $errors->add('name', 'Name is too long'); + } + + if (intval($model['account_id']) == 0) { + $errors->add('account_id', 'Account is mandatory'); + } + if ($model['targetdate'] == '' && isset($model['remind_me']) && intval($model['remind_me']) == 1) { + $errors->add('targetdate', 'Target date is mandatory when setting reminders.'); + } + if ($model['targetdate'] != '') { + try { + new Carbon($model['targetdate']); + } catch (\Exception $e) { + $errors->add('targetdate', 'Invalid date.'); + } + } else { + $errors->add('targetdate', 'Invalid target date.'); + } + if (floatval($model['targetamount']) < 0.01) { + $errors->add('targetamount', 'Amount should be above 0.01.'); + } + if (!in_array(ucfirst($model['reminder']), \Config::get('firefly.piggybank_periods'))) { + $errors->add('reminder', 'Invalid reminder period (' . $model['reminder'] . ')'); + } + + if (!in_array(ucfirst($model['rep_length']), \Config::get('firefly.piggybank_periods'))) { + $errors->add('rep_length', 'Invalid repeat period (' . $model['rep_length'] . ')'); + } + + // check period. + if (!$errors->has('reminder') && !$errors->has('targetdate') && isset($model['remind_me']) && intval($model['remind_me']) == 1) { + $today = new Carbon; + $target = new Carbon($model['targetdate']); + switch ($model['reminder']) { + case 'week': + $today->addWeek(); + break; + case 'month': + $today->addMonth(); + break; + case 'year': + $today->addYear(); + break; + } + if ($today > $target) { + $errors->add('reminder', 'Target date is too close to today to set reminders.'); + } + } + + $validator = \Validator::make($model, \Piggybank::$rules); + if ($validator->invalid()) { + $errors->merge($errors); + } + + // add ok messages. + $list = ['name', 'account_id', 'rep_every', 'rep_times', 'rep_length', 'targetamount', 'targetdate', 'remind_me', 'reminder']; + foreach ($list as $entry) { + if (!$errors->has($entry) && !$warnings->has($entry)) { + $successes->add($entry, 'OK'); + } + } + + return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; + } + + /** + * Returns an object with id $id. + * + * @param int $id + * + * @return Ardent + */ + public function find($id) + { + // TODO: Implement find() method. + throw new NotImplementedException; + } + + /** + * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. + * + * @param $what + * + * @return \AccountType|null + */ + public function findByWhat($what) + { + // TODO: Implement findByWhat() method. + throw new NotImplementedException; + } + + /** + * Returns all objects. + * + * @return Collection + */ + public function get() + { + return $this->getUser()->piggybanks()->where('repeats', 1)->get(); + } + + /** + * @param array $ids + * + * @return Collection + */ + public function getByIds(array $ids) + { + // TODO: Implement getByIds() method. + throw new NotImplementedException; + } + + /** + * @param \Account $account + * + * @return float + */ + public function leftOnAccount(\Account $account) + { + // TODO: Implement leftOnAccount() method. + throw new NotImplementedException; + } +} \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Transaction.php b/app/lib/FireflyIII/Database/Transaction.php index 26a3d252d5..3ab54aea75 100644 --- a/app/lib/FireflyIII/Database/Transaction.php +++ b/app/lib/FireflyIII/Database/Transaction.php @@ -16,7 +16,7 @@ use LaravelBook\Ardent\Ardent; * * @package FireflyIII\Database */ -class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls +class Transaction implements CUD, CommonDatabaseCalls { use SwitchUser; @@ -135,20 +135,6 @@ class Transaction implements TransactionInterface, CUD, CommonDatabaseCalls return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * diff --git a/app/lib/FireflyIII/Database/TransactionCurrency.php b/app/lib/FireflyIII/Database/TransactionCurrency.php index 82a4639345..6de3860ada 100644 --- a/app/lib/FireflyIII/Database/TransactionCurrency.php +++ b/app/lib/FireflyIII/Database/TransactionCurrency.php @@ -3,132 +3,16 @@ namespace FireflyIII\Database; -use FireflyIII\Database\Ifaces\CommonDatabaseCalls; -use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\TransactionCurrencyInterface; -use FireflyIII\Exception\NotImplementedException; -use Illuminate\Support\Collection; -use LaravelBook\Ardent\Ardent; /** * Class TransactionType * * @package FireflyIII\Database */ -class TransactionCurrency implements TransactionCurrencyInterface, CUD, CommonDatabaseCalls +class TransactionCurrency implements TransactionCurrencyInterface { - - /** - * @param Ardent $model - * - * @return bool - */ - public function destroy(Ardent $model) - { - // TODO: Implement destroy() method. - throw new NotImplementedException; - } - - /** - * @param array $data - * - * @return Ardent - */ - public function store(array $data) - { - // TODO: Implement store() method. - throw new NotImplementedException; - } - - /** - * @param Ardent $model - * @param array $data - * - * @return bool - */ - public function update(Ardent $model, array $data) - { - // TODO: Implement update() method. - throw new NotImplementedException; - } - - /** - * Validates an array. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param array $model - * - * @return array - */ - public function validate(array $model) - { - // TODO: Implement validate() method. - throw new NotImplementedException; - } - - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - - /** - * Returns an object with id $id. - * - * @param int $id - * - * @return Ardent - */ - public function find($id) - { - // TODO: Implement find() method. - throw new NotImplementedException; - } - - /** - * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc. - * - * @param $what - * - * @return \AccountType|null - */ - public function findByWhat($what) - { - // TODO: Implement findByWhat() method. - throw new NotImplementedException; - } - - /** - * Returns all objects. - * - * @return Collection - */ - public function get() - { - // TODO: Implement get() method. - throw new NotImplementedException; - } - - /** - * @param array $ids - * - * @return Collection - */ - public function getByIds(array $ids) - { - // TODO: Implement getByIds() method. - throw new NotImplementedException; - } - /** * @param string $code * diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index b7c2ce5a75..aa6c8a8044 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -428,20 +428,6 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * diff --git a/app/lib/FireflyIII/Database/TransactionType.php b/app/lib/FireflyIII/Database/TransactionType.php index 8b4aad2fef..a0c215783d 100644 --- a/app/lib/FireflyIII/Database/TransactionType.php +++ b/app/lib/FireflyIII/Database/TransactionType.php @@ -16,7 +16,7 @@ use LaravelBook\Ardent\Ardent; * * @package FireflyIII\Database */ -class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCalls +class TransactionType implements CUD, CommonDatabaseCalls { /** @@ -67,20 +67,6 @@ class TransactionType implements TransactionTypeInterface, CUD, CommonDatabaseCa throw new NotImplementedException; } - /** - * Validates a model. Returns an array containing MessageBags - * errors/warnings/successes. - * - * @param Ardent $model - * - * @return array - */ - public function validateObject(Ardent $model) - { - // TODO: Implement validateObject() method. - throw new NotImplementedException; - } - /** * Returns an object with id $id. * From 6b1d8d3aaa7096feae919da87a5e0f687809c9ea Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:30:58 +0100 Subject: [PATCH 108/193] Added the possibility to save per quarter. --- app/config/firefly.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/config/firefly.php b/app/config/firefly.php index bd7db200f6..eaf752ba7f 100644 --- a/app/config/firefly.php +++ b/app/config/firefly.php @@ -7,6 +7,7 @@ return [ 'piggybank_periods' => [ 'week' => 'Week', 'month' => 'Month', + 'quarter' => 'Quarter', 'year' => 'Year' ], 'periods_to_text' => [ From 1bb49fa4966d4d27b4f9952a4a55000efd8d1839 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:31:06 +0100 Subject: [PATCH 109/193] Expanded the repeated expenses. --- app/controllers/RepeatedExpenseController.php | 128 +++++++++++++++++- 1 file changed, 124 insertions(+), 4 deletions(-) diff --git a/app/controllers/RepeatedExpenseController.php b/app/controllers/RepeatedExpenseController.php index f19167ca06..e11896d0fc 100644 --- a/app/controllers/RepeatedExpenseController.php +++ b/app/controllers/RepeatedExpenseController.php @@ -1,15 +1,135 @@ getAssetAccounts()); + + return View::make('repeatedexpense.create', compact('accounts', 'periods'))->with('subTitle', 'Create new repeated expense')->with( + 'subTitleIcon', 'fa-plus' + ); + } + public function index() { $subTitle = 'Overview'; - return View::make('repeatedexpense.index',compact('subTitle')); + + /** @var \FireflyIII\Database\RepeatedExpense $repository */ + $repository = App::make('FireflyIII\Database\RepeatedExpense'); + + $expenses = $repository->get(); + + $expenses->each( + function (\Piggybank $piggyBank) { + // do something with "parts". + $piggyBank->currentRep = $piggyBank->currentRelevantRep(); + if (!is_null($piggyBank->reminder)) { + switch ($piggyBank->reminder) { + default: + throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses'); + break; + case 'month': + $piggyBank->parts = $piggyBank->currentRep->startdate->diffInMonths($piggyBank->currentRep->targetdate); + break; + } + } else { + $piggyBank->parts = 1; + } + + // number of bars: + $piggyBank->barCount = floor(12 / $piggyBank->parts); + $amountPerBar = $piggyBank->targetamount / $piggyBank->parts; + $currentAmount = $amountPerBar; + $bars = []; + $currentDate = clone $piggyBank->currentRep->startdate; + for ($i = 0; $i < $piggyBank->parts; $i++) { + // niet elke keer een andere dinges pakken? om target te redden? + + $bars[] = [ + 'amount' => $currentAmount, + 'date' => $currentDate + ]; + if (!is_null($piggyBank->reminder)) { + $currentDate = \DateKit::addPeriod($currentDate, $piggyBank->reminder, 0); + } + + $currentAmount += $amountPerBar; + } + $piggyBank->bars = $bars; + + } + + ); + + return View::make('repeatedexpense.index', compact('expenses', 'subTitle')); + } + + /** + * + */ + public function store() + { + $data = Input::all(); + $data['repeats'] = 1; + /** @var \FireflyIII\Database\RepeatedExpense $repository */ + $repository = App::make('FireflyIII\Database\RepeatedExpense'); + + switch ($data['post_submit_action']) { + default: + throw new FireflyException('Cannot handle post_submit_action "' . e($data['post_submit_action']) . '"'); + break; + case 'create_another': + case 'store': + $messages = $repository->validate($data); + /** @var MessageBag $messages ['errors'] */ + if ($messages['errors']->count() > 0) { + Session::flash('warnings', $messages['warnings']); + Session::flash('successes', $messages['successes']); + Session::flash('error', 'Could not save repeated expense: ' . $messages['errors']->first()); + + return Redirect::route('repeated.create')->withInput()->withErrors($messages['errors']); + } + // store! + $repeated = $repository->store($data); + + /* + * Create the relevant repetition per Event. + */ + Event::fire('piggybank.store', [$repeated]); // new and used. + + Session::flash('success', 'New repeated expense stored!'); + + if ($data['post_submit_action'] == 'create_another') { + return Redirect::route('repeated.create')->withInput(); + } else { + return Redirect::route('repeated.index'); + } + break; + case 'validate_only': + $messageBags = $repository->validate($data); + Session::flash('warnings', $messageBags['warnings']); + Session::flash('successes', $messageBags['successes']); + Session::flash('errors', $messageBags['errors']); + + return Redirect::route('repeated.create')->withInput(); + break; + } } } \ No newline at end of file From 9f920bcfe39fcbbf5fb7c1d9eecd0d12e8059843 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:31:25 +0100 Subject: [PATCH 110/193] Expanded the transaction controller to show repeated expenses --- app/controllers/TransactionController.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 1f5caa78f6..902c82bda3 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -44,6 +44,9 @@ class TransactionController extends BaseController /** @var \FireflyIII\Database\Piggybank $piggyRepository */ $piggyRepository = App::make('FireflyIII\Database\Piggybank'); + /** @var \FireflyIII\Database\RepeatedExpense $repRepository */ + $repRepository = App::make('FireflyIII\Database\RepeatedExpense'); + // get asset accounts with names and id's . $assetAccounts = FFForm::makeSelectList($accountRepository->getAssetAccounts()); @@ -52,7 +55,8 @@ class TransactionController extends BaseController $budgets[0] = '(no budget)'; // get the piggy banks. - $piggies = FFForm::makeSelectList($piggyRepository->get()); + $list = $piggyRepository->get()->merge($repRepository->get()); + $piggies = FFForm::makeSelectList($list); $piggies[0] = '(no piggy bank)'; /* From 9d889d05e4a3d2cbb42611f75a073dc1816b998a Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:31:40 +0100 Subject: [PATCH 111/193] Expanded Events to check on repeated expenses. --- app/lib/FireflyIII/Event/Piggybank.php | 63 ++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/app/lib/FireflyIII/Event/Piggybank.php b/app/lib/FireflyIII/Event/Piggybank.php index f5e24c72f1..f716a0ccab 100644 --- a/app/lib/FireflyIII/Event/Piggybank.php +++ b/app/lib/FireflyIII/Event/Piggybank.php @@ -185,6 +185,14 @@ class Piggybank $events->listen('piggybank.store', 'FireflyIII\Event\Piggybank@storePiggybank'); $events->listen('piggybank.update', 'FireflyIII\Event\Piggybank@updatePiggybank'); + \App::before( + function ($request) { + $this->validateRepeatedExpenses(); + } + ); + + //$events->listen('piggybank.boo', 'FireflyIII\Event\Piggybank@updatePiggybank'); + // triggers when others are updated. $events->listen('transactionJournal.store', 'FireflyIII\Event\Piggybank@storeTransfer'); @@ -192,12 +200,59 @@ class Piggybank $events->listen('transactionJournal.destroy', 'FireflyIII\Event\Piggybank@destroyTransfer'); } - public function updatePiggybank(\Piggybank $piggybank) + /** + * Validates the presence of repetitions for all repeated expenses! + */ + public function validateRepeatedExpenses() + { + /** @var \FireflyIII\Database\RepeatedExpense $repository */ + $repository = \App::make('FireflyIII\Database\RepeatedExpense'); + + $list = $repository->get(); + + /** @var \Piggybank $entry */ + foreach ($list as $entry) { + $start = $entry->startdate; + $target = $entry->targetdate; + // find a repetition on this date: + $count = $entry->piggybankrepetitions()->starts($start)->targets($target)->count(); + if ($count == 0) { + $repetition = new \PiggybankRepetition; + $repetition->piggybank()->associate($entry); + $repetition->startdate = $start; + $repetition->targetdate = $target; + $repetition->currentamount = 0; + $repetition->save(); + } + // then continue and do something in the current relevant timeframe. + $today = Carbon::now(); + $currentTarget = clone $target; + $currentStart = null; + while ($currentTarget < $today) { + $currentStart = \DateKit::subtractPeriod($currentTarget, $entry->rep_length, 0); + $currentTarget = \DateKit::addPeriod($currentTarget, $entry->rep_length, 0); + // create if not exists: + $count = $entry->piggybankrepetitions()->starts($currentStart)->targets($currentTarget)->count(); + if ($count == 0) { + $repetition = new \PiggybankRepetition; + $repetition->piggybank()->associate($entry); + $repetition->startdate = $currentStart; + $repetition->targetdate = $currentTarget; + $repetition->currentamount = 0; + $repetition->save(); + } + + } + + } + } + + public function updatePiggybank(\Piggybank $piggyBank) { // get the repetition: - $repetition = $piggybank->currentRelevantRep(); - $repetition->startdate = $piggybank->startdate; - $repetition->targetdate = $piggybank->targetdate; + $repetition = $piggyBank->currentRelevantRep(); + $repetition->startdate = $piggyBank->startdate; + $repetition->targetdate = $piggyBank->targetdate; $repetition->save(); } From 3d3842b9d6117aa49409506baf72cbffa7628042 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:31:55 +0100 Subject: [PATCH 112/193] Reinstated "periodshow" and some other stuff. --- app/lib/FireflyIII/Shared/Toolkit/Date.php | 69 +++++++++++++++++++- app/lib/FireflyIII/Shared/Toolkit/Filter.php | 8 +-- 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index b011716bd6..d0ddc9f6e2 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -23,7 +23,7 @@ class Date public function addPeriod(Carbon $theDate, $repeatFreq, $skip) { $date = clone $theDate; - $add = ($skip + 1); + $add = ($skip + 1); switch ($repeatFreq) { default: throw new FireflyException('Cannot do addPeriod for $repeat_freq ' . $repeatFreq); @@ -47,6 +47,7 @@ class Date $months = $add * 6; $date->addMonths($months); break; + case 'year': case 'yearly': $date->addYears($add); break; @@ -94,6 +95,28 @@ class Date return $currentEnd; } + public function periodShow(Carbon $date, $repeatFrequency) + { + switch ($repeatFrequency) { + default: + throw new FireflyException('No date formats for frequency "' . $repeatFrequency . '"!'); + break; + case 'daily': + return $date->format('j F Y'); + break; + case 'weekly': + return $date->format('\W\e\e\k W, Y'); + break; + case 'monthly': + case 'month': + return $date->format('F Y'); + break; + case 'yearly': + return $date->format('Y'); + break; + } + } + /** * @param Carbon $theDate * @param $repeatFreq @@ -136,4 +159,46 @@ class Date return $date; } -} \ No newline at end of file + + /** + * @param Carbon $date + * @param $repeatFreq + * @param int $subtract + * + * @return Carbon + * @throws FireflyException + */ + public function subtractPeriod(Carbon $theDate, $repeatFreq, $subtract = 1) + { + $date = clone $theDate; + switch ($repeatFreq) { + default: + throw new FireflyException('Cannot do subtractPeriod for $repeat_freq ' . $repeatFreq); + break; + case 'daily': + $date->subDays($subtract); + break; + case 'weekly': + $date->subWeeks($subtract); + break; + case 'monthly': + $date->subMonths($subtract); + break; + case 'quarterly': + $months = $subtract * 3; + $date->subMonths($months); + break; + case 'half-year': + $months = $subtract * 6; + $date->subMonths($months); + break; + case 'year': + case 'yearly': + $date->subYears($subtract); + break; + } + + return $date; + } +} + diff --git a/app/lib/FireflyIII/Shared/Toolkit/Filter.php b/app/lib/FireflyIII/Shared/Toolkit/Filter.php index f6c923f15a..f9051252d2 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Filter.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Filter.php @@ -1,15 +1,9 @@ Date: Sat, 22 Nov 2014 23:32:10 +0100 Subject: [PATCH 113/193] Cleanup and expansion to accomodate repeated expenses. --- app/models/LimitRepetition.php | 34 ------------------------------ app/models/Piggybank.php | 2 +- app/models/PiggybankRepetition.php | 12 +++++++++-- 3 files changed, 11 insertions(+), 37 deletions(-) diff --git a/app/models/LimitRepetition.php b/app/models/LimitRepetition.php index 651b5dd40e..750191030a 100644 --- a/app/models/LimitRepetition.php +++ b/app/models/LimitRepetition.php @@ -119,38 +119,4 @@ class LimitRepetition extends Ardent } } - /** - * TODO remove this method in favour of something in the FireflyIII libraries. - * - * Same as above, just with a more natural view. So "March 2012". - */ - public function periodShow() - { - if (is_null($this->repeat_freq)) { - $this->repeat_freq = $this->limit->repeat_freq; - } - switch ($this->repeat_freq) { - default: - throw new FireflyException('No date formats for frequency "' . $this->repeat_freq . '"!'); - break; - case 'daily': - return $this->startdate->format('j F Y'); - break; - case 'weekly': - return $this->startdate->format('\W\e\e\k W, Y'); - break; - case 'monthly': - return $this->startdate->format('F Y'); - break; - case 'half-year': - case 'quarterly': - return $this->startdate->format('M Y') . ' - ' . $this->enddate->format('M Y'); - break; - case 'yearly': - return $this->startdate->format('Y'); - break; - } - } - - } \ No newline at end of file diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php index a0580c14c9..e69a85d689 100644 --- a/app/models/Piggybank.php +++ b/app/models/Piggybank.php @@ -53,7 +53,7 @@ class Piggybank extends Ardent 'startdate' => 'date', // when you started 'targetdate' => 'date', // when its due 'repeats' => 'required|boolean', // does it repeat? - 'rep_length' => 'in:day,week,month,year', // how long is the period? + 'rep_length' => 'in:day,week,month,quarter,year', // how long is the period? 'rep_every' => 'required|min:1|max:100', // how often does it repeat? every 3 years. 'rep_times' => 'min:1|max:100', // how many times do you want to save this amount? eg. 3 times 'reminder' => 'in:day,week,month,year', // want a reminder to put money in this? diff --git a/app/models/PiggybankRepetition.php b/app/models/PiggybankRepetition.php index 8d20be1873..ef9557bfa1 100644 --- a/app/models/PiggybankRepetition.php +++ b/app/models/PiggybankRepetition.php @@ -1,6 +1,7 @@ belongsTo('Piggybank'); } + public function scopeStarts(Builder $query, Carbon $date) { + $query->where('startdate',$date->format('Y-m-d')); + } + public function scopeTargets(Builder $query, Carbon $date) { + $query->where('targetdate',$date->format('Y-m-d')); + } + } \ No newline at end of file From cca27581385a5eac43bb45e996a661d60ad02905 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:32:24 +0100 Subject: [PATCH 114/193] New views for the repeated expenses. --- app/views/repeatedexpense/create.blade.php | 96 ++++++++++++++++++++++ app/views/repeatedexpense/index.blade.php | 42 ++++++++++ 2 files changed, 138 insertions(+) create mode 100644 app/views/repeatedexpense/create.blade.php diff --git a/app/views/repeatedexpense/create.blade.php b/app/views/repeatedexpense/create.blade.php new file mode 100644 index 0000000000..8474ab4aa7 --- /dev/null +++ b/app/views/repeatedexpense/create.blade.php @@ -0,0 +1,96 @@ +@extends('layouts.default') +@section('content') +{{Form::open(['class' => 'form-horizontal','url' => route('repeated.store')])}} + +
    +
    +
    +
    + Mandatory fields +
    +
    + {{Form::ffText('name')}} + {{Form::ffSelect('account_id',$accounts,null,['label' => 'Save on account'])}} + {{Form::ffAmount('targetamount')}} + {{Form::ffDate('targetdate',null,['label' => 'First target date'])}} + {{Form::ffSelect('rep_length',$periods,'month',['label' => 'Repeats every'])}} + {{Form::ffInteger('rep_every',0,['label' => 'Skip period'])}} + {{Form::ffInteger('rep_times',0,['label' => 'Repeat times'])}} +
    +
    +

    + +

    +
    +
    + +
    +
    + Optional fields +
    +
    + + {{Form::ffCheckbox('remind_me','1',false,['label' => 'Remind me'])}} + {{Form::ffSelect('reminder',$periods,'month',['label' => 'Remind every'])}} +
    +
    + + +
    +
    + Options +
    +
    + {{Form::ffOptionsList('create','repeated expense')}} +
    +
    + +
    +
    +{{-- + +

    Mandatory fields

    + +

    Optional fields

    + + +
    + {{ Form::label('reminder', 'Remind you every', ['class' => 'col-sm-4 control-label'])}} +
    + + + + @if($errors->has('reminder')) +

    {{$errors->first('reminder')}}

    + @else + Enter a number and a period and Firefly will remind you to add money + to this piggy bank every now and then. + @endif +
    +
    + + +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +--}} + +{{Form::close()}} +@stop diff --git a/app/views/repeatedexpense/index.blade.php b/app/views/repeatedexpense/index.blade.php index f1cf41d48b..15a7acd870 100644 --- a/app/views/repeatedexpense/index.blade.php +++ b/app/views/repeatedexpense/index.blade.php @@ -1,10 +1,52 @@ @extends('layouts.default') @section('content') +
    +@foreach($expenses as $entry) +
    +
    +
    +
    + {{{$entry->name}}} +
    +
    +
    + @for($i=0;$i<$entry->parts;$i++) +
    +
    + @if($entry->currentRep->currentamount <= $entry->bars[$i]['amount']) +
    {{mf($entry->bars[$i]['amount'],false)}}
    + @else +
    {{mf($entry->bars[$i]['amount'],false)}}
    + @endif +
    + +
    + @endfor +
    +
    + @for($i=0;$i<$entry->parts;$i++) +
    + {{DateKit::periodShow($entry->bars[$i]['date'],$entry->reminder)}} +
    + @endfor +
    +
    +
    +
    +
    +@endforeach From 6691b238f738a9b1420d12f36745e74dccf13724 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:32:34 +0100 Subject: [PATCH 115/193] New routes for repeated expenses. --- app/routes.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/routes.php b/app/routes.php index f39c1086fc..9994ae52fc 100644 --- a/app/routes.php +++ b/app/routes.php @@ -199,6 +199,7 @@ Route::group( // repeated expenses controller: Route::get('/repeatedexpenses', ['uses' => 'RepeatedExpenseController@index', 'as' => 'repeated.index']); + Route::get('/repeatedexpenses/create', ['uses' => 'RepeatedExpenseController@create', 'as' => 'repeated.create']); // report controller: Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']); @@ -258,6 +259,8 @@ Route::group( Route::post('/piggybanks/add/{piggybank}', ['uses' => 'PiggybankController@postAdd', 'as' => 'piggybanks.add']); # add money Route::post('/piggybanks/remove/{piggybank}', ['uses' => 'PiggybankController@postRemove', 'as' => 'piggybanks.remove']); # remove money. + // repeated expense controller + Route::post('/repeatedexpense/store', ['uses' => 'RepeatedExpenseController@store', 'as' => 'repeated.store']); // preferences controller Route::post('/preferences', ['uses' => 'PreferencesController@postIndex']); From 8aa847c7186fe6dc9752a48ed9e57f39e773dbf3 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:34:38 +0100 Subject: [PATCH 116/193] Expanded the view. --- app/views/repeatedexpense/index.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/repeatedexpense/index.blade.php b/app/views/repeatedexpense/index.blade.php index 15a7acd870..ac0e5c890f 100644 --- a/app/views/repeatedexpense/index.blade.php +++ b/app/views/repeatedexpense/index.blade.php @@ -18,7 +18,7 @@
    - {{{$entry->name}}} + {{{$entry->name}}} ({{mf($entry->currentRep->currentamount)}})
    From d8976379b1b11bc32fb105e4b3c91111c13bd245 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:35:39 +0100 Subject: [PATCH 117/193] Some debug information. --- app/views/repeatedexpense/index.blade.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/repeatedexpense/index.blade.php b/app/views/repeatedexpense/index.blade.php index ac0e5c890f..f734bf1b82 100644 --- a/app/views/repeatedexpense/index.blade.php +++ b/app/views/repeatedexpense/index.blade.php @@ -23,8 +23,10 @@
    @for($i=0;$i<$entry->parts;$i++) +
    + @if($entry->currentRep->currentamount <= $entry->bars[$i]['amount'])
    {{mf($entry->bars[$i]['amount'],false)}}
    @else From cd44f51072b120c7de362030f6537cc0ccda55f4 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:37:03 +0100 Subject: [PATCH 118/193] Add some floatvals() just in case. --- app/controllers/RepeatedExpenseController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/RepeatedExpenseController.php b/app/controllers/RepeatedExpenseController.php index e11896d0fc..9ced97b583 100644 --- a/app/controllers/RepeatedExpenseController.php +++ b/app/controllers/RepeatedExpenseController.php @@ -55,8 +55,8 @@ class RepeatedExpenseController extends BaseController // number of bars: $piggyBank->barCount = floor(12 / $piggyBank->parts); - $amountPerBar = $piggyBank->targetamount / $piggyBank->parts; - $currentAmount = $amountPerBar; + $amountPerBar = floatval($piggyBank->targetamount) / $piggyBank->parts; + $currentAmount = floatval($amountPerBar); $bars = []; $currentDate = clone $piggyBank->currentRep->startdate; for ($i = 0; $i < $piggyBank->parts; $i++) { From 9cb6c7697e70044e369f292092de191bc07cedc8 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:38:08 +0100 Subject: [PATCH 119/193] Some debug information. --- app/views/repeatedexpense/index.blade.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/repeatedexpense/index.blade.php b/app/views/repeatedexpense/index.blade.php index f734bf1b82..8e462a065c 100644 --- a/app/views/repeatedexpense/index.blade.php +++ b/app/views/repeatedexpense/index.blade.php @@ -26,10 +26,11 @@
    - @if($entry->currentRep->currentamount <= $entry->bars[$i]['amount']) +
    {{mf($entry->bars[$i]['amount'],false)}}
    @else +
    {{mf($entry->bars[$i]['amount'],false)}}
    @endif
    From 7336367eff9a2afe9a96b63b14db2e4c990f5f32 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 22 Nov 2014 23:38:58 +0100 Subject: [PATCH 120/193] Duh. Bug fixed. --- app/views/repeatedexpense/index.blade.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/repeatedexpense/index.blade.php b/app/views/repeatedexpense/index.blade.php index 8e462a065c..9a7413fd34 100644 --- a/app/views/repeatedexpense/index.blade.php +++ b/app/views/repeatedexpense/index.blade.php @@ -23,11 +23,11 @@
    @for($i=0;$i<$entry->parts;$i++) - +
    - @if($entry->currentRep->currentamount <= $entry->bars[$i]['amount']) - + @if($entry->currentRep->currentamount < $entry->bars[$i]['amount']) +
    {{mf($entry->bars[$i]['amount'],false)}}
    @else From 4456ef2326628da12ff5ecfd66c4e77a0a387ece Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 23 Nov 2014 06:29:29 +0100 Subject: [PATCH 121/193] Some expansion on the index of repeated expenses, and the first reference to the show page. --- app/controllers/RepeatedExpenseController.php | 18 ++++++++++++------ app/lib/FireflyIII/Event/Piggybank.php | 9 ++++++--- app/lib/FireflyIII/Shared/Toolkit/Date.php | 3 +++ app/routes.php | 1 + app/views/repeatedexpense/index.blade.php | 2 +- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/app/controllers/RepeatedExpenseController.php b/app/controllers/RepeatedExpenseController.php index 9ced97b583..6d26891344 100644 --- a/app/controllers/RepeatedExpenseController.php +++ b/app/controllers/RepeatedExpenseController.php @@ -46,29 +46,35 @@ class RepeatedExpenseController extends BaseController throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses'); break; case 'month': - $piggyBank->parts = $piggyBank->currentRep->startdate->diffInMonths($piggyBank->currentRep->targetdate); + $start = clone $piggyBank->currentRep->startdate; + $start->startOfMonth(); + $end = clone $piggyBank->currentRep->targetdate; + $end->endOfMonth(); + $piggyBank->parts = $start->diffInMonths($end); + unset($start, $end); break; } + } else { $piggyBank->parts = 1; } // number of bars: - $piggyBank->barCount = floor(12 / $piggyBank->parts); + $piggyBank->barCount = floor(12 / $piggyBank->parts) == 0 ? 1 : floor(12 / $piggyBank->parts); $amountPerBar = floatval($piggyBank->targetamount) / $piggyBank->parts; $currentAmount = floatval($amountPerBar); $bars = []; $currentDate = clone $piggyBank->currentRep->startdate; for ($i = 0; $i < $piggyBank->parts; $i++) { // niet elke keer een andere dinges pakken? om target te redden? - + if (!is_null($piggyBank->reminder)) { + $currentDate = \DateKit::addPeriod($currentDate, $piggyBank->reminder, 0); + } $bars[] = [ 'amount' => $currentAmount, 'date' => $currentDate ]; - if (!is_null($piggyBank->reminder)) { - $currentDate = \DateKit::addPeriod($currentDate, $piggyBank->reminder, 0); - } + $currentAmount += $amountPerBar; } diff --git a/app/lib/FireflyIII/Event/Piggybank.php b/app/lib/FireflyIII/Event/Piggybank.php index f716a0ccab..aa1aab289f 100644 --- a/app/lib/FireflyIII/Event/Piggybank.php +++ b/app/lib/FireflyIII/Event/Piggybank.php @@ -205,10 +205,14 @@ class Piggybank */ public function validateRepeatedExpenses() { + if(!\Auth::check()) { + return; + } /** @var \FireflyIII\Database\RepeatedExpense $repository */ $repository = \App::make('FireflyIII\Database\RepeatedExpense'); - $list = $repository->get(); + $list = $repository->get(); + $today = Carbon::now(); /** @var \Piggybank $entry */ foreach ($list as $entry) { @@ -225,7 +229,7 @@ class Piggybank $repetition->save(); } // then continue and do something in the current relevant timeframe. - $today = Carbon::now(); + $currentTarget = clone $target; $currentStart = null; while ($currentTarget < $today) { @@ -243,7 +247,6 @@ class Piggybank } } - } } diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index d0ddc9f6e2..f9857a8547 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -39,6 +39,7 @@ class Date case 'monthly': $date->addMonths($add); break; + case 'quarter': case 'quarterly': $months = $add * 3; $date->addMonths($months); @@ -142,6 +143,7 @@ class Date case 'monthly': $date->startOfMonth(); break; + case 'quarter': case 'quarterly': $date->firstOfQuarter(); break; @@ -184,6 +186,7 @@ class Date case 'monthly': $date->subMonths($subtract); break; + case 'quarter': case 'quarterly': $months = $subtract * 3; $date->subMonths($months); diff --git a/app/routes.php b/app/routes.php index 9994ae52fc..93e667e22b 100644 --- a/app/routes.php +++ b/app/routes.php @@ -200,6 +200,7 @@ Route::group( // repeated expenses controller: Route::get('/repeatedexpenses', ['uses' => 'RepeatedExpenseController@index', 'as' => 'repeated.index']); Route::get('/repeatedexpenses/create', ['uses' => 'RepeatedExpenseController@create', 'as' => 'repeated.create']); + Route::get('/repeatedexpenses/show/{repeated}', ['uses' => 'RepeatedExpenseController@show', 'as' => 'repeated.show']); // report controller: Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']); diff --git a/app/views/repeatedexpense/index.blade.php b/app/views/repeatedexpense/index.blade.php index 9a7413fd34..1b285352f2 100644 --- a/app/views/repeatedexpense/index.blade.php +++ b/app/views/repeatedexpense/index.blade.php @@ -18,7 +18,7 @@
    - {{{$entry->name}}} ({{mf($entry->currentRep->currentamount)}}) + {{{$entry->name}}} ({{mf($entry->currentRep->currentamount)}})
    From bfda4bc199a18b22b9f0d7b9e7b89637b9a74b7a Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 24 Nov 2014 10:12:34 +0100 Subject: [PATCH 122/193] Lots of new stuff. --- app/controllers/RepeatedExpenseController.php | 57 +---- .../FireflyIII/Collection/PiggybankPart.php | 135 +++++++++++ .../FireflyIII/Database/RepeatedExpense.php | 212 ++++++++++++++++++ app/lib/FireflyIII/Shared/Toolkit/Date.php | 3 + .../FireflyIII/Shared/Toolkit/Reminders.php | 7 +- app/models/Piggybank.php | 58 ++--- app/routes.php | 18 +- app/views/accounts/index.blade.php | 2 - app/views/list/accounts.blade.php | 2 +- app/views/repeatedexpense/index.blade.php | 27 ++- app/views/repeatedexpense/show.blade.php | 23 ++ app/views/transactions/index.blade.php | 2 - 12 files changed, 467 insertions(+), 79 deletions(-) create mode 100644 app/lib/FireflyIII/Collection/PiggybankPart.php create mode 100644 app/views/repeatedexpense/show.blade.php diff --git a/app/controllers/RepeatedExpenseController.php b/app/controllers/RepeatedExpenseController.php index 6d26891344..58e7242997 100644 --- a/app/controllers/RepeatedExpenseController.php +++ b/app/controllers/RepeatedExpenseController.php @@ -1,5 +1,6 @@ get(); - $expenses->each( - function (\Piggybank $piggyBank) { - // do something with "parts". - $piggyBank->currentRep = $piggyBank->currentRelevantRep(); - if (!is_null($piggyBank->reminder)) { - switch ($piggyBank->reminder) { - default: - throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses'); - break; - case 'month': - $start = clone $piggyBank->currentRep->startdate; - $start->startOfMonth(); - $end = clone $piggyBank->currentRep->targetdate; - $end->endOfMonth(); - $piggyBank->parts = $start->diffInMonths($end); - unset($start, $end); - break; - } - - } else { - $piggyBank->parts = 1; - } - - // number of bars: - $piggyBank->barCount = floor(12 / $piggyBank->parts) == 0 ? 1 : floor(12 / $piggyBank->parts); - $amountPerBar = floatval($piggyBank->targetamount) / $piggyBank->parts; - $currentAmount = floatval($amountPerBar); - $bars = []; - $currentDate = clone $piggyBank->currentRep->startdate; - for ($i = 0; $i < $piggyBank->parts; $i++) { - // niet elke keer een andere dinges pakken? om target te redden? - if (!is_null($piggyBank->reminder)) { - $currentDate = \DateKit::addPeriod($currentDate, $piggyBank->reminder, 0); - } - $bars[] = [ - 'amount' => $currentAmount, - 'date' => $currentDate - ]; - - - $currentAmount += $amountPerBar; - } - $piggyBank->bars = $bars; - + function (Piggybank $piggyBank) use ($repository) { + $piggyBank->currentRelevantRep(); + $piggyBank->currentRep = $repository->calculateParts($piggyBank->currentRep); } - ); return View::make('repeatedexpense.index', compact('expenses', 'subTitle')); } + public function show(Piggybank $piggyBank) + { + $subTitle = $piggyBank->name; + $today = Carbon::now(); + + return View::make('repeatedexpense.show', compact('piggyBank', 'today', 'subTitle')); + } + /** * */ diff --git a/app/lib/FireflyIII/Collection/PiggybankPart.php b/app/lib/FireflyIII/Collection/PiggybankPart.php new file mode 100644 index 0000000000..3b198df5db --- /dev/null +++ b/app/lib/FireflyIII/Collection/PiggybankPart.php @@ -0,0 +1,135 @@ +repetition; + } + + /** + * @param \PiggybankRepetition $repetition + */ + public function setRepetition($repetition) + { + $this->repetition = $repetition; + } + + /** + * @return Carbon + */ + public function getStartdate() + { + return $this->startdate; + } + + /** + * @param Carbon $startdate + */ + public function setStartdate($startdate) + { + $this->startdate = $startdate; + } + + /** + * @return Carbon + */ + public function getTargetdate() + { + return $this->targetdate; + } + + /** + * @param Carbon $targetdate + */ + public function setTargetdate($targetdate) + { + $this->targetdate = $targetdate; + } + + public function percentage() + { + if ($this->getCurrentamount() < $this->getAmount()) { + $pct = 0; + // calculate halway point? + if ($this->getAmount() - $this->getCurrentamount() < $this->getAmountPerBar()) { + $left = $this->getCurrentamount() % $this->getAmountPerBar(); + $pct = round($left / $this->getAmountPerBar() * 100); + } + + return $pct; + } else { + return 100; + } + } + + /** + * @return int + */ + public function getCurrentamount() + { + return $this->currentamount; + } + + /** + * @param int $currentamount + */ + public function setCurrentamount($currentamount) + { + $this->currentamount = $currentamount; + } + + /** + * @return int + */ + public function getAmount() + { + return $this->amount; + } + + /** + * @param int $amount + */ + public function setAmount($amount) + { + $this->amount = $amount; + } + + /** + * @return mixed + */ + public function getAmountPerBar() + { + return $this->amountPerBar; + } + + /** + * @param mixed $amountPerBar + */ + public function setAmountPerBar($amountPerBar) + { + $this->amountPerBar = $amountPerBar; + } + + +} \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/RepeatedExpense.php b/app/lib/FireflyIII/Database/RepeatedExpense.php index 2b50bf6bf1..2295c70012 100644 --- a/app/lib/FireflyIII/Database/RepeatedExpense.php +++ b/app/lib/FireflyIII/Database/RepeatedExpense.php @@ -4,9 +4,11 @@ namespace FireflyIII\Database; use Carbon\Carbon; +use FireflyIII\Collection\PiggybankPart; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\PiggybankInterface; +use FireflyIII\Exception\FireflyException; use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; use Illuminate\Support\MessageBag; @@ -24,6 +26,212 @@ class RepeatedExpense implements CUD, CommonDatabaseCalls, PiggybankInterface $this->setUser(\Auth::user()); } + /** + * Based on the piggy bank, the reminder-setting and + * other variables this method tries to divide the piggy bank into equal parts. Each is + * accommodated by a reminder (if everything goes to plan). + * + * @return \PiggybankRepetition + */ + public function calculateParts(\PiggybankRepetition $repetition) + { + \Log::debug('NOW in calculateParts()'); + \Log::debug('Repetition id is ' . $repetition->id); + /** @var \Piggybank $piggyBank */ + $piggyBank = $repetition->piggybank()->first(); + \Log::debug('connected piggy bank is: ' . $piggyBank->name . ' (#' . $piggyBank->id . ')'); + + /* + * If no reminders are set, the repetition is split in exactly one part: + */ + if (is_null($piggyBank->reminder)) { + $parts = 1; + } else { + /* + * Number of parts is the number of [reminder period]s between + * the start date and the target date + */ + /** @var Carbon $start */ + $start = clone $repetition->startdate; + /** @var Carbon $target */ + $target = clone $repetition->targetdate; + + switch ($piggyBank->reminder) { + default: + throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses (calculateParts)'); + break; + case 'week': + $parts = $start->diffInWeeks($target); + break; + case 'month': + $parts = $start->diffInMonths($target); + break; + case 'quarter': + $parts = ceil($start->diffInMonths($target) / 3); + break; + case 'year': + $parts = $start->diffInYears($target); + break; + } + $parts = $parts < 1 ? 1 : $parts; + unset($start, $target); + + + // /* + // * Otherwise, FF3 splits by the difference in time and the amount + // * of reminders the user wants. + // */ + // switch ($piggyBank->reminder) { + // default: + // throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses (calculateParts)'); + // break; + // case 'week': + // $start = clone $repetition->startdate; + // $start->startOfWeek(); + // $end = clone $repetition->targetdate; + // $end->endOfWeek(); + // $parts = $start->diffInWeeks($end); + // unset($start, $end); + // break; + // case 'month': + // $start = clone $repetition->startdate; + // $start->startOfMonth(); + // $end = clone $repetition->targetdate; + // $end->endOfMonth(); + // $parts = $start->diffInMonths($end); + // unset($start, $end); + // break; + // } + } + $amountPerBar = floatval($piggyBank->targetamount) / $parts; + $currentAmount = floatval($amountPerBar); + $currentStart = clone $repetition->startdate; + $currentTarget = clone $repetition->targetdate; + $bars = new Collection; + + // if($parts > 12) { + // $parts = 12; + // $currentStart = \DateKit::startOfPeriod(Carbon::now(), $piggyBank->reminder); + // $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder); + // } + + for ($i = 0; $i < $parts; $i++) { + /* + * Jump one month ahead after the first instance: + */ + // if ($i > 0) { + // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); + // /* + // * Jump to the start of the period too: + // */ + // $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder); + // + // } + + + /* + * Move the current start to the actual start of + * the [period] once the first iteration has passed. + */ + // if ($i != 0) { + // $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder); + // } + // if($i == 0 && !is_null($piggyBank->reminder)) { + // $currentEnd = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder); + // $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder); + // } + + $part = new PiggybankPart; + $part->setRepetition($repetition); + $part->setAmount($currentAmount); + $part->setAmountPerBar($amountPerBar); + $part->setCurrentamount($repetition->currentamount); + $part->setStartdate($currentStart); + $part->setTargetdate($currentTarget); + + // if (!is_null($piggyBank->reminder)) { + // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); + // $currentEnd = \DateKit::endOfPeriod($currentStart, $piggyBank->reminder); + // } + + + $bars->push($part); + $currentAmount += $amountPerBar; + } + $repetition->bars = $bars; + + return $repetition; + exit; + + + $repetition->hello = 'World!'; + + return $repetition; + + $return = new Collection; + $repetitions = $piggyBank->piggybankrepetitions()->get(); + /** @var \PiggybankRepetition $repetition */ + foreach ($repetitions as $repetition) { + + + if (is_null($piggyBank->reminder)) { + // simple, one part "repetition". + $part = new PiggybankPart; + $part->setRepetition($repetition); + } else { + $part = new PiggybankPart; + } + + + // end! + $return->push($part); + } + + exit; + + return $return; + $piggyBank->currentRelevantRep(); // get the current relevant repetition. + if (!is_null($piggyBank->reminder)) { + switch ($piggyBank->reminder) { + default: + throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses'); + break; + case 'month': + $start = clone $piggyBank->currentRep->startdate; + $start->startOfMonth(); + $end = clone $piggyBank->currentRep->targetdate; + $end->endOfMonth(); + $piggyBank->parts = $start->diffInMonths($end); + unset($start, $end); + break; + } + + } else { + $piggyBank->parts = 1; + } + + // number of bars: + $piggyBank->barCount = floor(12 / $piggyBank->parts) == 0 ? 1 : floor(12 / $piggyBank->parts); + $amountPerBar = floatval($piggyBank->targetamount) / $piggyBank->parts; + $currentAmount = floatval($amountPerBar); + $bars = []; + $currentStart = clone $piggyBank->currentRep->startdate; + for ($i = 0; $i < $piggyBank->parts; $i++) { + // niet elke keer een andere dinges pakken? om target te redden? + if (!is_null($piggyBank->reminder)) { + $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); + } + $bars[] = [ + 'amount' => $currentAmount, + 'date' => $currentStart + ]; + + + $currentAmount += $amountPerBar; + } + $piggyBank->bars = $bars; + } + /** * @param Ardent $model * @@ -119,6 +327,10 @@ class RepeatedExpense implements CUD, CommonDatabaseCalls, PiggybankInterface } catch (\Exception $e) { $errors->add('targetdate', 'Invalid date.'); } + $diff = Carbon::now()->diff(new Carbon($model['targetdate'])); + if ($diff->days > 365) { + $errors->add('targetdate', 'First target date should a a year or less from now.'); + } } else { $errors->add('targetdate', 'Invalid target date.'); } diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index f9857a8547..5725db90ad 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -82,12 +82,14 @@ class Date case 'monthly': $currentEnd->addMonth()->subDay(); break; + case 'quarter': case 'quarterly': $currentEnd->addMonths(3)->subDay(); break; case 'half-year': $currentEnd->addMonths(6)->subDay(); break; + case 'year': case 'yearly': $currentEnd->addYear()->subDay(); break; @@ -154,6 +156,7 @@ class Date $date->addMonths(6); } break; + case 'year': case 'yearly': $date->startOfYear(); break; diff --git a/app/lib/FireflyIII/Shared/Toolkit/Reminders.php b/app/lib/FireflyIII/Shared/Toolkit/Reminders.php index 453f6e7926..040c9cccd6 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Reminders.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Reminders.php @@ -71,8 +71,13 @@ class Reminders /** @var \FireflyIII\Database\Piggybank $repository */ $repository = \App::make('FireflyIII\Database\Piggybank'); + /** @var \FireflyIII\Database\Piggybank $repeatedRepository */ + $repeatedRepository = \App::make('FireflyIII\Database\RepeatedExpense'); + /** @var Collection $piggybanks */ - $piggybanks = $repository->get(); + $piggybanks = $repository->get()->merge($repeatedRepository->get()); + + $set = $piggybanks->filter( function (\Piggybank $piggybank) { if (!is_null($piggybank->reminder)) { diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php index e69a85d689..291e96577f 100644 --- a/app/models/Piggybank.php +++ b/app/models/Piggybank.php @@ -42,7 +42,7 @@ use LaravelBook\Ardent\Ardent as Ardent; * @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminderSkip($value) * @method static \Illuminate\Database\Query\Builder|\Piggybank whereOrder($value) * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRemindMe($value) - * @property-read \Illuminate\Database\Eloquent\Collection|\Reminder[] $reminders + * @property-read \Illuminate\Database\Eloquent\Collection|\Reminder[] $reminders */ class Piggybank extends Ardent { @@ -56,7 +56,7 @@ class Piggybank extends Ardent 'rep_length' => 'in:day,week,month,quarter,year', // how long is the period? 'rep_every' => 'required|min:1|max:100', // how often does it repeat? every 3 years. 'rep_times' => 'min:1|max:100', // how many times do you want to save this amount? eg. 3 times - 'reminder' => 'in:day,week,month,year', // want a reminder to put money in this? + 'reminder' => 'in:day,week,quarter,month,year', // want a reminder to put money in this? 'reminder_skip' => 'required|min:0|max:100', // every week? every 2 months? 'remind_me' => 'required|boolean', 'order' => 'required:min:1', // not yet used. ]; @@ -77,16 +77,12 @@ class Piggybank extends Ardent * * @return int */ - public function amountPerReminder() { + public function amountPerReminder() + { return 0; } - public function reminders() - { - return $this->morphMany('Reminder', 'remindersable'); - } - /** * TODO remove this method in favour of something in the FireflyIII libraries. * @@ -130,37 +126,44 @@ class Piggybank extends Ardent return $this->currentRep; } if ($this->repeats == 0) { - $rep = $this->piggybankrepetitions()->first(); + $rep = $this->piggybankrepetitions()->first(['piggybank_repetitions.*']); $this->currentRep = $rep; - return $rep; } else { - $query = $this->piggybankrepetitions()->where( + $query = $this->piggybankrepetitions()->where( function ($q) { $q->where( function ($q) { - $today = new Carbon; - $q->whereNull('startdate'); - $q->orWhere('startdate', '<=', $today->format('Y-m-d')); + + $q->where( + function ($q) { + $today = new Carbon; + $q->whereNull('startdate'); + $q->orWhere('startdate', '<=', $today->format('Y-m-d')); + } + )->where( + function ($q) { + $today = new Carbon; + $q->whereNull('targetdate'); + $q->orWhere('targetdate', '>=', $today->format('Y-m-d')); + } + ); } - )->where( + )->orWhere( function ($q) { $today = new Carbon; - $q->whereNull('targetdate'); - $q->orWhere('targetdate', '>=', $today->format('Y-m-d')); + $q->where('startdate', '>=', $today->format('Y-m-d')); + $q->where('targetdate', '>=', $today->format('Y-m-d')); } ); + } - )->orWhere( - function ($q) { - $today = new Carbon; - $q->where('startdate', '>=', $today->format('Y-m-d')); - $q->where('targetdate', '>=', $today->format('Y-m-d')); - } - )->orderBy('startdate', 'ASC'); - $result = $query->first(); + ) + ->orderBy('startdate', 'ASC'); + $result = $query->first(['piggybank_repetitions.*']); $this->currentRep = $result; + \Log::debug('Found relevant rep in currentRelevantRep(): ' . $result->id); return $result; } @@ -192,6 +195,11 @@ class Piggybank extends Ardent return $this->hasMany('PiggybankEvent'); } + public function reminders() + { + return $this->morphMany('Reminder', 'remindersable'); + } + /** * TODO remove this method in favour of something in the FireflyIII libraries. * diff --git a/app/routes.php b/app/routes.php index 93e667e22b..d11b2b3e4a 100644 --- a/app/routes.php +++ b/app/routes.php @@ -103,13 +103,27 @@ Route::bind( 'piggybank', function ($value, $route) { if (Auth::check()) { return Piggybank:: - where('piggybanks.id', $value)->leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where('accounts.user_id', Auth::user()->id) - ->first(['piggybanks.*']); + where('piggybanks.id', $value) + ->leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id') + ->where('accounts.user_id', Auth::user()->id) + ->where('repeats',0)->first(['piggybanks.*']); } return null; } ); +Route::bind( + 'repeated', function ($value, $route) { + if (Auth::check()) { + return Piggybank:: + where('piggybanks.id', $value) + ->leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id') + ->where('accounts.user_id', Auth::user()->id) + ->where('repeats',1)->first(['piggybanks.*']); + } + return null; + } +); // protected routes: Route::group( diff --git a/app/views/accounts/index.blade.php b/app/views/accounts/index.blade.php index ba78cd68d8..54a5734050 100644 --- a/app/views/accounts/index.blade.php +++ b/app/views/accounts/index.blade.php @@ -21,9 +21,7 @@
    -
    @include('list.accounts') -
    diff --git a/app/views/list/accounts.blade.php b/app/views/list/accounts.blade.php index ff48d1fabf..3b86218129 100644 --- a/app/views/list/accounts.blade.php +++ b/app/views/list/accounts.blade.php @@ -1,4 +1,4 @@ - +
    diff --git a/app/views/repeatedexpense/index.blade.php b/app/views/repeatedexpense/index.blade.php index 1b285352f2..eb8765a4ee 100644 --- a/app/views/repeatedexpense/index.blade.php +++ b/app/views/repeatedexpense/index.blade.php @@ -14,14 +14,36 @@ @foreach($expenses as $entry) +currentRep->bars->count()) == 0 ? 1 : floor(12 / $entry->currentRep->bars->count()); +?>
    - {{{$entry->name}}} ({{mf($entry->currentRep->currentamount)}}) + {{{$entry->name}}}
    +
    +

    + Target amount: {{mf($entry->targetamount)}}. Currently saved: {{mf($entry->currentRep->currentamount)}}. Left to save: {{mf($entry->targetamount-$entry->currentRep->currentamount)}}
    + Runs from {{$entry->currentRep->startdate->format('j F Y')}} to {{$entry->currentRep->targetdate->format('j F Y')}} +

    +
    +
    +
    + @foreach($entry->currentRep->bars as $bar) +
    +
    + +
    +
    +
    + +
    + @endforeach + {{-- @for($i=0;$i<$entry->parts;$i++)
    @@ -37,13 +59,16 @@
    @endfor + --}}
    + {{-- @for($i=0;$i<$entry->parts;$i++)
    {{DateKit::periodShow($entry->bars[$i]['date'],$entry->reminder)}}
    @endfor + --}}
    diff --git a/app/views/repeatedexpense/show.blade.php b/app/views/repeatedexpense/show.blade.php new file mode 100644 index 0000000000..3849e5e0f0 --- /dev/null +++ b/app/views/repeatedexpense/show.blade.php @@ -0,0 +1,23 @@ +@extends('layouts.default') +@section('content') +
    +
    + @foreach($piggyBank->piggybankrepetitions as $rep) +
    +
    + Repetition from {{$rep->startdate->format('j F Y')}} to {{$rep->targetdate->format('j F Y')}} +
    +
    + {{$piggyBank->reminder}} +
    +
    + @endforeach +
    +
    +@stop \ No newline at end of file diff --git a/app/views/transactions/index.blade.php b/app/views/transactions/index.blade.php index 46f76530df..4149c3b226 100644 --- a/app/views/transactions/index.blade.php +++ b/app/views/transactions/index.blade.php @@ -6,9 +6,7 @@
    {{{$subTitle}}}
    -
    @include('list.journals-full') -
    From b051278d2e4c79c7ae413ccd7aed932c240f960e Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 24 Nov 2014 17:01:37 +0100 Subject: [PATCH 123/193] Expand repeated expenses. --- app/controllers/RepeatedExpenseController.php | 12 ++++- .../FireflyIII/Collection/PiggybankPart.php | 25 +++++++++- .../FireflyIII/Database/RepeatedExpense.php | 31 ++++++++++++ app/lib/FireflyIII/Shared/Toolkit/Date.php | 50 +++++++++++++++++++ .../FireflyIII/Shared/Toolkit/Reminders.php | 6 ++- app/views/repeatedexpense/show.blade.php | 44 +++++++++++++++- 6 files changed, 161 insertions(+), 7 deletions(-) diff --git a/app/controllers/RepeatedExpenseController.php b/app/controllers/RepeatedExpenseController.php index 58e7242997..a72da7bba0 100644 --- a/app/controllers/RepeatedExpenseController.php +++ b/app/controllers/RepeatedExpenseController.php @@ -51,7 +51,17 @@ class RepeatedExpenseController extends BaseController $subTitle = $piggyBank->name; $today = Carbon::now(); - return View::make('repeatedexpense.show', compact('piggyBank', 'today', 'subTitle')); + /** @var \FireflyIII\Database\RepeatedExpense $repository */ + $repository = App::make('FireflyIII\Database\RepeatedExpense'); + + $repetitions = $piggyBank->piggybankrepetitions()->get(); + $repetitions->each( + function (PiggybankRepetition $repetition) use ($repository) { + $repetition = $repository->calculateParts($repetition); + } + ); + + return View::make('repeatedexpense.show', compact('repetitions','piggyBank', 'today', 'subTitle')); } /** diff --git a/app/lib/FireflyIII/Collection/PiggybankPart.php b/app/lib/FireflyIII/Collection/PiggybankPart.php index 3b198df5db..bf5fb94d86 100644 --- a/app/lib/FireflyIII/Collection/PiggybankPart.php +++ b/app/lib/FireflyIII/Collection/PiggybankPart.php @@ -12,6 +12,8 @@ class PiggybankPart public $amountPerBar; /** @var int */ public $currentamount; + /** @var \Reminder */ + public $reminder; /** @var \PiggybankRepetition */ public $repetition; /** @var Carbon */ @@ -19,6 +21,22 @@ class PiggybankPart /** @var Carbon */ public $targetdate; + /** + * @return \Reminder + */ + public function getReminder() + { + return $this->reminder; + } + + /** + * @param \Reminder $reminder + */ + public function setReminder($reminder) + { + $this->reminder = $reminder; + } + /** * @return \PiggybankRepetition */ @@ -67,6 +85,11 @@ class PiggybankPart $this->targetdate = $targetdate; } + public function hasReminder() + { + return !is_null($this->reminder); + } + public function percentage() { if ($this->getCurrentamount() < $this->getAmount()) { @@ -130,6 +153,4 @@ class PiggybankPart { $this->amountPerBar = $amountPerBar; } - - } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/RepeatedExpense.php b/app/lib/FireflyIII/Database/RepeatedExpense.php index 2295c70012..9eda8edb9a 100644 --- a/app/lib/FireflyIII/Database/RepeatedExpense.php +++ b/app/lib/FireflyIII/Database/RepeatedExpense.php @@ -116,6 +116,26 @@ class RepeatedExpense implements CUD, CommonDatabaseCalls, PiggybankInterface // } for ($i = 0; $i < $parts; $i++) { + /* + * If it's not the first repetition, jump the start date a [period] + * and jump the target date a [period] + */ + if($i > 0) { + $currentStart = clone $currentTarget; + $currentStart->addDay(); + $currentTarget = \DateKit::addPeriod($currentStart, $piggyBank->reminder,0); + } + /* + * If it's the first one, and has reminders, jump to the end of the [period] + */ + if($i == 0 && !is_null($piggyBank->reminder)) { + $currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder); + } + if($currentStart > $repetition->targetdate) { + break; + } + + /* * Jump one month ahead after the first instance: */ @@ -148,6 +168,17 @@ class RepeatedExpense implements CUD, CommonDatabaseCalls, PiggybankInterface $part->setCurrentamount($repetition->currentamount); $part->setStartdate($currentStart); $part->setTargetdate($currentTarget); + if (!is_null($piggyBank->reminder)) { + // might be a reminder for this range? + $reminder = $piggyBank->reminders() + ->where('startdate',$currentStart->format('Y-m-d')) + ->where('enddate',$currentTarget->format('Y-m-d')) + ->first(); + if($reminder) { + $part->setReminder($reminder); + } + + } // if (!is_null($piggyBank->reminder)) { // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); diff --git a/app/lib/FireflyIII/Shared/Toolkit/Date.php b/app/lib/FireflyIII/Shared/Toolkit/Date.php index 5725db90ad..90152551ae 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Date.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Date.php @@ -98,6 +98,51 @@ class Date return $currentEnd; } + /** + * @param Carbon $theCurrentEnd + * @param $repeatFreq + * + * @return mixed + * @throws FireflyException + */ + public function endOfX(Carbon $theCurrentEnd, $repeatFreq) + { + $currentEnd = clone $theCurrentEnd; + switch ($repeatFreq) { + default: + throw new FireflyException('Cannot do endOfPeriod for $repeat_freq ' . $repeatFreq); + break; + case 'daily': + $currentEnd->endOfDay(); + break; + case 'week': + case 'weekly': + $currentEnd->endOfWeek(); + break; + case 'month': + case 'monthly': + $currentEnd->endOfMonth(); + break; + case 'quarter': + case 'quarterly': + $currentEnd->lastOfQuarter(); + break; + case 'half-year': + $month = intval($theCurrentEnd->format('m')); + $currentEnd->endOfYear(); + if($month <= 6) { + $currentEnd->subMonths(6); + } + break; + case 'year': + case 'yearly': + $currentEnd->endOfYear(); + break; + } + + return $currentEnd; + } + public function periodShow(Carbon $date, $repeatFrequency) { switch ($repeatFrequency) { @@ -107,13 +152,18 @@ class Date case 'daily': return $date->format('j F Y'); break; + case 'week': case 'weekly': return $date->format('\W\e\e\k W, Y'); break; + case 'quarter': + return $date->format('F Y'); + break; case 'monthly': case 'month': return $date->format('F Y'); break; + case 'year': case 'yearly': return $date->format('Y'); break; diff --git a/app/lib/FireflyIII/Shared/Toolkit/Reminders.php b/app/lib/FireflyIII/Shared/Toolkit/Reminders.php index 040c9cccd6..10197cf05b 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Reminders.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Reminders.php @@ -85,6 +85,8 @@ class Reminders } } ); + $today = Carbon::now(); + //$today = new Carbon('15-12-2014'); /** @var \Piggybank $piggybank */ foreach ($set as $piggybank) { @@ -95,8 +97,8 @@ class Reminders */ /** @var \PiggybankRepetition $repetition */ $repetition = $piggybank->currentRelevantRep(); - $start = \DateKit::startOfPeriod(Carbon::now(), $piggybank->reminder); - if ($repetition->targetdate && $repetition->targetdate <= Carbon::now()) { + $start = \DateKit::startOfPeriod($today, $piggybank->reminder); + if ($repetition->targetdate && $repetition->targetdate <= $today) { // break when no longer relevant: continue; } diff --git a/app/views/repeatedexpense/show.blade.php b/app/views/repeatedexpense/show.blade.php index 3849e5e0f0..ed22a28dd4 100644 --- a/app/views/repeatedexpense/show.blade.php +++ b/app/views/repeatedexpense/show.blade.php @@ -2,7 +2,12 @@ @section('content')
    - @foreach($piggyBank->piggybankrepetitions as $rep) + @foreach($repetitions as $rep) + bars->count()) == 0 ? 1 : floor(12 / $rep->bars->count()); + ?> + +
    - {{$piggyBank->reminder}} +

    + Target amount: {{mf($piggyBank->targetamount)}}. Currently saved: {{mf($rep->currentamount)}}. +

    +
    + @foreach($rep->bars as $bar) +
    +
    + +
    +
    +
    + +

    + + {{-- + @if($bar->hasReminder()) + + {{DateKit::periodShow($bar->getStartDate(),$piggyBank->reminder)}} + + @else + @if(!is_null($piggyBank->reminder)) + {{DateKit::periodShow($bar->getStartDate(),$piggyBank->reminder)}} + @endif + @endif + --}} + {{$bar->getStartDate()->format('d/m/y')}} → {{$bar->getTargetDate()->format('d/m/y')}} + @if($bar->hasReminder()) + ! + @endif +

    +
    + @endforeach +
    @endforeach + @foreach($piggyBank->reminders()->get() as $reminder) + Reminder: #{{$reminder->id}} [from: {{$reminder->startdate->format('d/m/y')}}, to: {{$reminder->enddate->format('d/m/y')}}]
    + @endforeach
    @stop \ No newline at end of file From 743deb42272be470e5c4e07e890778eb00a9cbf8 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 24 Nov 2014 18:06:21 +0100 Subject: [PATCH 124/193] More stuff for repeated expenses. --- app/controllers/ReminderController.php | 7 + ...4_11_17_194734_event_table_additions_1.php | 1 + .../FireflyIII/Collection/PiggybankPart.php | 61 +-- .../FireflyIII/Database/RepeatedExpense.php | 415 +++++++++--------- .../FireflyIII/Shared/Toolkit/Reminders.php | 2 +- app/models/Reminder.php | 1 + app/routes.php | 1 + app/views/reminders/show.blade.php | 2 +- app/views/repeatedexpense/index.blade.php | 2 +- app/views/repeatedexpense/show.blade.php | 43 +- 10 files changed, 278 insertions(+), 257 deletions(-) diff --git a/app/controllers/ReminderController.php b/app/controllers/ReminderController.php index e6bdef5ea0..15f226954d 100644 --- a/app/controllers/ReminderController.php +++ b/app/controllers/ReminderController.php @@ -57,5 +57,12 @@ class ReminderController extends BaseController Session::flash('success','Reminder dismissed'); return Redirect::route('index'); } + public function notnow(Reminder $reminder) { + $reminder->active = 0; + $reminder->notnow = 1; + $reminder->save(); + Session::flash('success','Reminder dismissed'); + return Redirect::route('index'); + } } \ No newline at end of file diff --git a/app/database/migrations/2014_11_17_194734_event_table_additions_1.php b/app/database/migrations/2014_11_17_194734_event_table_additions_1.php index a164da50ad..e5e419bb7f 100644 --- a/app/database/migrations/2014_11_17_194734_event_table_additions_1.php +++ b/app/database/migrations/2014_11_17_194734_event_table_additions_1.php @@ -26,6 +26,7 @@ class EventTableAdditions1 extends Migration // remove some fields: Schema::table( 'reminders', function (Blueprint $table) { + $table->boolean('notnow'); $table->integer('remindersable_id')->unsigned()->nullable(); $table->string('remindersable_type')->nullable(); } diff --git a/app/lib/FireflyIII/Collection/PiggybankPart.php b/app/lib/FireflyIII/Collection/PiggybankPart.php index bf5fb94d86..faf28173b2 100644 --- a/app/lib/FireflyIII/Collection/PiggybankPart.php +++ b/app/lib/FireflyIII/Collection/PiggybankPart.php @@ -7,17 +7,24 @@ use Carbon\Carbon; class PiggybankPart { - /** @var int */ - public $amount; + /** @var float */ public $amountPerBar; - /** @var int */ + + /** @var float */ public $currentamount; + + /** @var float */ + public $cumulativeAmount; + /** @var \Reminder */ public $reminder; + /** @var \PiggybankRepetition */ public $repetition; + /** @var Carbon */ public $startdate; + /** @var Carbon */ public $targetdate; @@ -92,10 +99,10 @@ class PiggybankPart public function percentage() { - if ($this->getCurrentamount() < $this->getAmount()) { + if ($this->getCurrentamount() < $this->getCumulativeAmount()) { $pct = 0; // calculate halway point? - if ($this->getAmount() - $this->getCurrentamount() < $this->getAmountPerBar()) { + if ($this->getCumulativeAmount() - $this->getCurrentamount() < $this->getAmountPerBar()) { $left = $this->getCurrentamount() % $this->getAmountPerBar(); $pct = round($left / $this->getAmountPerBar() * 100); } @@ -107,7 +114,7 @@ class PiggybankPart } /** - * @return int + * @return float */ public function getCurrentamount() { @@ -115,7 +122,7 @@ class PiggybankPart } /** - * @param int $currentamount + * @param float $currentamount */ public function setCurrentamount($currentamount) { @@ -123,23 +130,7 @@ class PiggybankPart } /** - * @return int - */ - public function getAmount() - { - return $this->amount; - } - - /** - * @param int $amount - */ - public function setAmount($amount) - { - $this->amount = $amount; - } - - /** - * @return mixed + * @return float */ public function getAmountPerBar() { @@ -147,10 +138,30 @@ class PiggybankPart } /** - * @param mixed $amountPerBar + * @param float $amountPerBar */ public function setAmountPerBar($amountPerBar) { $this->amountPerBar = $amountPerBar; } + + /** + * @return float + */ + public function getCumulativeAmount() + { + return $this->cumulativeAmount; + } + + /** + * @param float $cumulativeAmount + */ + public function setCumulativeAmount($cumulativeAmount) + { + $this->cumulativeAmount = $cumulativeAmount; + } + + + + } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/RepeatedExpense.php b/app/lib/FireflyIII/Database/RepeatedExpense.php index 9eda8edb9a..89c019bacd 100644 --- a/app/lib/FireflyIII/Database/RepeatedExpense.php +++ b/app/lib/FireflyIII/Database/RepeatedExpense.php @@ -8,7 +8,6 @@ use FireflyIII\Collection\PiggybankPart; use FireflyIII\Database\Ifaces\CommonDatabaseCalls; use FireflyIII\Database\Ifaces\CUD; use FireflyIII\Database\Ifaces\PiggybankInterface; -use FireflyIII\Exception\FireflyException; use FireflyIII\Exception\NotImplementedException; use Illuminate\Support\Collection; use Illuminate\Support\MessageBag; @@ -39,228 +38,234 @@ class RepeatedExpense implements CUD, CommonDatabaseCalls, PiggybankInterface \Log::debug('Repetition id is ' . $repetition->id); /** @var \Piggybank $piggyBank */ $piggyBank = $repetition->piggybank()->first(); + $bars = new Collection; \Log::debug('connected piggy bank is: ' . $piggyBank->name . ' (#' . $piggyBank->id . ')'); /* * If no reminders are set, the repetition is split in exactly one part: */ if (is_null($piggyBank->reminder)) { - $parts = 1; - } else { - /* - * Number of parts is the number of [reminder period]s between - * the start date and the target date - */ - /** @var Carbon $start */ - $start = clone $repetition->startdate; - /** @var Carbon $target */ - $target = clone $repetition->targetdate; - - switch ($piggyBank->reminder) { - default: - throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses (calculateParts)'); - break; - case 'week': - $parts = $start->diffInWeeks($target); - break; - case 'month': - $parts = $start->diffInMonths($target); - break; - case 'quarter': - $parts = ceil($start->diffInMonths($target) / 3); - break; - case 'year': - $parts = $start->diffInYears($target); - break; - } - $parts = $parts < 1 ? 1 : $parts; - unset($start, $target); - - - // /* - // * Otherwise, FF3 splits by the difference in time and the amount - // * of reminders the user wants. - // */ - // switch ($piggyBank->reminder) { - // default: - // throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses (calculateParts)'); - // break; - // case 'week': - // $start = clone $repetition->startdate; - // $start->startOfWeek(); - // $end = clone $repetition->targetdate; - // $end->endOfWeek(); - // $parts = $start->diffInWeeks($end); - // unset($start, $end); - // break; - // case 'month': - // $start = clone $repetition->startdate; - // $start->startOfMonth(); - // $end = clone $repetition->targetdate; - // $end->endOfMonth(); - // $parts = $start->diffInMonths($end); - // unset($start, $end); - // break; - // } - } - $amountPerBar = floatval($piggyBank->targetamount) / $parts; - $currentAmount = floatval($amountPerBar); - $currentStart = clone $repetition->startdate; - $currentTarget = clone $repetition->targetdate; - $bars = new Collection; - - // if($parts > 12) { - // $parts = 12; - // $currentStart = \DateKit::startOfPeriod(Carbon::now(), $piggyBank->reminder); - // $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder); - // } - - for ($i = 0; $i < $parts; $i++) { - /* - * If it's not the first repetition, jump the start date a [period] - * and jump the target date a [period] - */ - if($i > 0) { - $currentStart = clone $currentTarget; - $currentStart->addDay(); - $currentTarget = \DateKit::addPeriod($currentStart, $piggyBank->reminder,0); - } - /* - * If it's the first one, and has reminders, jump to the end of the [period] - */ - if($i == 0 && !is_null($piggyBank->reminder)) { - $currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder); - } - if($currentStart > $repetition->targetdate) { - break; - } - - - /* - * Jump one month ahead after the first instance: - */ - // if ($i > 0) { - // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); - // /* - // * Jump to the start of the period too: - // */ - // $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder); - // - // } - - - /* - * Move the current start to the actual start of - * the [period] once the first iteration has passed. - */ - // if ($i != 0) { - // $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder); - // } - // if($i == 0 && !is_null($piggyBank->reminder)) { - // $currentEnd = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder); - // $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder); - // } - $part = new PiggybankPart; $part->setRepetition($repetition); - $part->setAmount($currentAmount); - $part->setAmountPerBar($amountPerBar); + $part->setAmountPerBar(floatval($piggyBank->targetamount)); + $part->setCurrentamount($repetition->currentamount); + $part->setCumulativeAmount($piggyBank->targetamount); + $part->setStartdate(clone $repetition->startdate); + $part->setTargetdate(clone $repetition->targetdate); + $bars->push($part); + $repetition->bars = $bars; + + return $repetition; + } + $currentStart = clone $repetition->startdate; + /* + * Loop between start and target instead of counting manually. + */ + $index = 0; + //echo 'Looping!
    '; + //echo $repetition->startdate . ' until ' . $repetition->targetdate . '
    '; + while ($currentStart < $repetition->targetdate) { + $currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder); + if ($currentTarget > $repetition->targetdate) { + $currentTarget = clone $repetition->targetdate; + } + + // create a part: + $part = new PiggybankPart; + $part->setRepetition($repetition); $part->setCurrentamount($repetition->currentamount); $part->setStartdate($currentStart); $part->setTargetdate($currentTarget); - if (!is_null($piggyBank->reminder)) { - // might be a reminder for this range? - $reminder = $piggyBank->reminders() - ->where('startdate',$currentStart->format('Y-m-d')) - ->where('enddate',$currentTarget->format('Y-m-d')) - ->first(); - if($reminder) { - $part->setReminder($reminder); - } + $bars->push($part); + //echo 'Loop #' . $index . ', from ' . $currentStart . ' until ' . $currentTarget . '
    '; + + /* + * Jump to the next period by adding a day. + */ + $currentStart = clone $currentTarget; + $currentStart->addDay();//\DateKit::addPeriod($currentTarget, $piggyBank->reminder, 0); + $index++; + + } + /* + * Loop parts again to add some + */ + $parts = $bars->count(); + $amountPerBar = floatval($piggyBank->targetamount) / $parts; + $cumulative = $amountPerBar; + /** @var PiggybankPart $bar */ + foreach ($bars as $bar) { + $bar->setAmountPerBar($amountPerBar); + $bar->setCumulativeAmount($cumulative); + + $reminder = $piggyBank->reminders() + ->where('startdate', $bar->getStartdate()->format('Y-m-d')) + ->where('enddate', $bar->getTargetdate()->format('Y-m-d')) + ->first(); + if ($reminder) { + $bar->setReminder($reminder); } - // if (!is_null($piggyBank->reminder)) { - // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); - // $currentEnd = \DateKit::endOfPeriod($currentStart, $piggyBank->reminder); - // } - - - $bars->push($part); - $currentAmount += $amountPerBar; + $cumulative += $amountPerBar; } + $repetition->bars = $bars; return $repetition; - exit; - - - $repetition->hello = 'World!'; - - return $repetition; - - $return = new Collection; - $repetitions = $piggyBank->piggybankrepetitions()->get(); - /** @var \PiggybankRepetition $repetition */ - foreach ($repetitions as $repetition) { - - - if (is_null($piggyBank->reminder)) { - // simple, one part "repetition". - $part = new PiggybankPart; - $part->setRepetition($repetition); - } else { - $part = new PiggybankPart; - } - - - // end! - $return->push($part); - } - - exit; - - return $return; - $piggyBank->currentRelevantRep(); // get the current relevant repetition. - if (!is_null($piggyBank->reminder)) { - switch ($piggyBank->reminder) { - default: - throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses'); - break; - case 'month': - $start = clone $piggyBank->currentRep->startdate; - $start->startOfMonth(); - $end = clone $piggyBank->currentRep->targetdate; - $end->endOfMonth(); - $piggyBank->parts = $start->diffInMonths($end); - unset($start, $end); - break; - } - - } else { - $piggyBank->parts = 1; - } - - // number of bars: - $piggyBank->barCount = floor(12 / $piggyBank->parts) == 0 ? 1 : floor(12 / $piggyBank->parts); - $amountPerBar = floatval($piggyBank->targetamount) / $piggyBank->parts; - $currentAmount = floatval($amountPerBar); - $bars = []; - $currentStart = clone $piggyBank->currentRep->startdate; - for ($i = 0; $i < $piggyBank->parts; $i++) { - // niet elke keer een andere dinges pakken? om target te redden? - if (!is_null($piggyBank->reminder)) { - $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); - } - $bars[] = [ - 'amount' => $currentAmount, - 'date' => $currentStart - ]; - - - $currentAmount += $amountPerBar; - } - $piggyBank->bars = $bars; + // + // // if($parts > 12) { + // // $parts = 12; + // // $currentStart = \DateKit::startOfPeriod(Carbon::now(), $piggyBank->reminder); + // // $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder); + // // } + // + // for ($i = 0; $i < $parts; $i++) { + // /* + // * If it's not the first repetition, jump the start date a [period] + // * and jump the target date a [period] + // */ + // if ($i > 0) { + // $currentStart = clone $currentTarget; + // $currentStart->addDay(); + // $currentTarget = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); + // } + // /* + // * If it's the first one, and has reminders, jump to the end of the [period] + // */ + // if ($i == 0 && !is_null($piggyBank->reminder)) { + // $currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder); + // } + // if ($currentStart > $repetition->targetdate) { + // break; + // } + // + // + // /* + // * Jump one month ahead after the first instance: + // */ + // // if ($i > 0) { + // // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); + // // /* + // // * Jump to the start of the period too: + // // */ + // // $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder); + // // + // // } + // + // + // /* + // * Move the current start to the actual start of + // * the [period] once the first iteration has passed. + // */ + // // if ($i != 0) { + // // $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder); + // // } + // // if($i == 0 && !is_null($piggyBank->reminder)) { + // // $currentEnd = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder); + // // $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder); + // // } + // + // $part = new PiggybankPart; + // $part->setRepetition($repetition); + // $part->setAmount($currentAmount); + // $part->setAmountPerBar($amountPerBar); + // $part->setCurrentamount($repetition->currentamount); + // $part->setStartdate($currentStart); + // $part->setTargetdate($currentTarget); + // if (!is_null($piggyBank->reminder)) { + // // might be a reminder for this range? + // $reminder = $piggyBank->reminders() + // ->where('startdate', $currentStart->format('Y-m-d')) + // ->where('enddate', $currentTarget->format('Y-m-d')) + // ->first(); + // if ($reminder) { + // $part->setReminder($reminder); + // } + // + // } + // + // // if (!is_null($piggyBank->reminder)) { + // // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); + // // $currentEnd = \DateKit::endOfPeriod($currentStart, $piggyBank->reminder); + // // } + // + // + // $bars->push($part); + // $currentAmount += $amountPerBar; + // } + // $repetition->bars = $bars; + // + // return $repetition; + // exit; + // + // + // $repetition->hello = 'World!'; + // + // return $repetition; + // + // $return = new Collection; + // $repetitions = $piggyBank->piggybankrepetitions()->get(); + // /** @var \PiggybankRepetition $repetition */ + // foreach ($repetitions as $repetition) { + // + // + // if (is_null($piggyBank->reminder)) { + // // simple, one part "repetition". + // $part = new PiggybankPart; + // $part->setRepetition($repetition); + // } else { + // $part = new PiggybankPart; + // } + // + // + // // end! + // $return->push($part); + // } + // + // exit; + // + // return $return; + // $piggyBank->currentRelevantRep(); // get the current relevant repetition. + // if (!is_null($piggyBank->reminder)) { + // switch ($piggyBank->reminder) { + // default: + // throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses'); + // break; + // case 'month': + // $start = clone $piggyBank->currentRep->startdate; + // $start->startOfMonth(); + // $end = clone $piggyBank->currentRep->targetdate; + // $end->endOfMonth(); + // $piggyBank->parts = $start->diffInMonths($end); + // unset($start, $end); + // break; + // } + // + // } else { + // $piggyBank->parts = 1; + // } + // + // // number of bars: + // $piggyBank->barCount = floor(12 / $piggyBank->parts) == 0 ? 1 : floor(12 / $piggyBank->parts); + // $amountPerBar = floatval($piggyBank->targetamount) / $piggyBank->parts; + // $currentAmount = floatval($amountPerBar); + // $bars = []; + // $currentStart = clone $piggyBank->currentRep->startdate; + // for ($i = 0; $i < $piggyBank->parts; $i++) { + // // niet elke keer een andere dinges pakken? om target te redden? + // if (!is_null($piggyBank->reminder)) { + // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0); + // } + // $bars[] = [ + // 'amount' => $currentAmount, + // 'date' => $currentStart + // ]; + // + // + // $currentAmount += $amountPerBar; + // } + // $piggyBank->bars = $bars; } /** diff --git a/app/lib/FireflyIII/Shared/Toolkit/Reminders.php b/app/lib/FireflyIII/Shared/Toolkit/Reminders.php index 10197cf05b..52998712f5 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Reminders.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Reminders.php @@ -86,7 +86,7 @@ class Reminders } ); $today = Carbon::now(); - //$today = new Carbon('15-12-2014'); + //$today = new Carbon('14-12-2014'); /** @var \Piggybank $piggybank */ foreach ($set as $piggybank) { diff --git a/app/models/Reminder.php b/app/models/Reminder.php index 199c5b66e8..0a28b43165 100644 --- a/app/models/Reminder.php +++ b/app/models/Reminder.php @@ -13,6 +13,7 @@ use LaravelBook\Ardent\Ardent; * @property \Carbon\Carbon $startdate * @property \Carbon\Carbon $enddate * @property boolean $active + * @property boolean $notnow * @property integer $remembersable_id * @property string $remembersable_type * @property-read \Piggybank $remindersable diff --git a/app/routes.php b/app/routes.php index d11b2b3e4a..7c39fb1ae1 100644 --- a/app/routes.php +++ b/app/routes.php @@ -223,6 +223,7 @@ Route::group( // reminder controller Route::get('/reminders/{reminder}',['uses' => 'ReminderController@show','as' => 'reminders.show']); Route::get('/reminders/{reminder}/dismiss',['uses' => 'ReminderController@dismiss','as' => 'reminders.dismiss']); + Route::get('/reminders/{reminder}/notnow',['uses' => 'ReminderController@notnow','as' => 'reminders.notnow']); Route::get('/reminders/{reminder}/act',['uses' => 'ReminderController@act','as' => 'reminders.act']); // search controller: diff --git a/app/views/reminders/show.blade.php b/app/views/reminders/show.blade.php index 0b12c927c5..8eb7068fb4 100644 --- a/app/views/reminders/show.blade.php +++ b/app/views/reminders/show.blade.php @@ -21,7 +21,7 @@

    I want to do this I already did this - Not this time + Not this time

    diff --git a/app/views/repeatedexpense/index.blade.php b/app/views/repeatedexpense/index.blade.php index eb8765a4ee..00b8115387 100644 --- a/app/views/repeatedexpense/index.blade.php +++ b/app/views/repeatedexpense/index.blade.php @@ -36,7 +36,7 @@ $barSize = floor(12 / $entry->currentRep->bars->count()) == 0 ? 1 : floor(12 / $ @foreach($entry->currentRep->bars as $bar)
    - +
    diff --git a/app/views/repeatedexpense/show.blade.php b/app/views/repeatedexpense/show.blade.php index ed22a28dd4..1e29b380dc 100644 --- a/app/views/repeatedexpense/show.blade.php +++ b/app/views/repeatedexpense/show.blade.php @@ -26,38 +26,33 @@ @foreach($rep->bars as $bar)
    - -
    -
    + +
    + @if($bar->percentage() > 50 && $bar->percentage() == 100) + @if($bar->hasReminder() && $bar->getReminder()->active == 1) + + @endif + @if($bar->hasReminder() && $bar->getReminder()->active == 0 && $bar->getReminder()->notnow == 0) + + @endif + @if($bar->hasReminder() && $bar->getReminder()->active == 0 && $bar->getReminder()->notnow == 1) + + @endif + @endif + @if($bar->percentage() > 50 && $bar->percentage() < 100) + {{mf($rep->currentamount,false)}} + @endif +
    +
    +
    -

    - - {{-- - @if($bar->hasReminder()) - - {{DateKit::periodShow($bar->getStartDate(),$piggyBank->reminder)}} - - @else - @if(!is_null($piggyBank->reminder)) - {{DateKit::periodShow($bar->getStartDate(),$piggyBank->reminder)}} - @endif - @endif - --}} - {{$bar->getStartDate()->format('d/m/y')}} → {{$bar->getTargetDate()->format('d/m/y')}} - @if($bar->hasReminder()) - ! - @endif -

    @endforeach
    @endforeach - @foreach($piggyBank->reminders()->get() as $reminder) - Reminder: #{{$reminder->id}} [from: {{$reminder->startdate->format('d/m/y')}}, to: {{$reminder->enddate->format('d/m/y')}}]
    - @endforeach @stop \ No newline at end of file From fd6e7fc1ab8a8dbcbbf489d591b25aead6a74663 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 24 Nov 2014 18:08:20 +0100 Subject: [PATCH 125/193] Fixed a bug where the associated total amount for a bar would be too high. --- app/lib/FireflyIII/Database/RepeatedExpense.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/lib/FireflyIII/Database/RepeatedExpense.php b/app/lib/FireflyIII/Database/RepeatedExpense.php index 89c019bacd..e09463b023 100644 --- a/app/lib/FireflyIII/Database/RepeatedExpense.php +++ b/app/lib/FireflyIII/Database/RepeatedExpense.php @@ -95,9 +95,12 @@ class RepeatedExpense implements CUD, CommonDatabaseCalls, PiggybankInterface $amountPerBar = floatval($piggyBank->targetamount) / $parts; $cumulative = $amountPerBar; /** @var PiggybankPart $bar */ - foreach ($bars as $bar) { + foreach ($bars as $index => $bar) { $bar->setAmountPerBar($amountPerBar); $bar->setCumulativeAmount($cumulative); + if($parts -1 == $index) { + $bar->setCumulativeAmount($piggyBank->targetamount); + } $reminder = $piggyBank->reminders() ->where('startdate', $bar->getStartdate()->format('Y-m-d')) From e9b7e82aea943799d0fde3760849f12c1a6a31f5 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 24 Nov 2014 23:02:08 +0100 Subject: [PATCH 126/193] Some visual updates to repeated expenses. --- app/controllers/RepeatedExpenseController.php | 1 - app/lib/FireflyIII/Shared/Toolkit/Steam.php | 17 +++++ app/views/repeatedexpense/index.blade.php | 66 +++++-------------- app/views/repeatedexpense/show.blade.php | 6 +- 4 files changed, 37 insertions(+), 53 deletions(-) diff --git a/app/controllers/RepeatedExpenseController.php b/app/controllers/RepeatedExpenseController.php index a72da7bba0..9284cc43a7 100644 --- a/app/controllers/RepeatedExpenseController.php +++ b/app/controllers/RepeatedExpenseController.php @@ -39,7 +39,6 @@ class RepeatedExpenseController extends BaseController $expenses->each( function (Piggybank $piggyBank) use ($repository) { $piggyBank->currentRelevantRep(); - $piggyBank->currentRep = $repository->calculateParts($piggyBank->currentRep); } ); diff --git a/app/lib/FireflyIII/Shared/Toolkit/Steam.php b/app/lib/FireflyIII/Shared/Toolkit/Steam.php index 50b06fce46..3b52592a6b 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Steam.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Steam.php @@ -1,6 +1,7 @@ currentamount / $piggyBank->targetamount * 100; + if ($pct > 100) { + return 100; + } else { + return floor($pct); + } + } + } \ No newline at end of file diff --git a/app/views/repeatedexpense/index.blade.php b/app/views/repeatedexpense/index.blade.php index 00b8115387..5df04f1f7f 100644 --- a/app/views/repeatedexpense/index.blade.php +++ b/app/views/repeatedexpense/index.blade.php @@ -13,68 +13,34 @@ -@foreach($expenses as $entry) -currentRep->bars->count()) == 0 ? 1 : floor(12 / $entry->currentRep->bars->count()); -?>
    -
    +@foreach($expenses as $entry) +
    {{{$entry->name}}} + ({{mf($entry->targetamount)}})
    -
    -
    -

    - Target amount: {{mf($entry->targetamount)}}. Currently saved: {{mf($entry->currentRep->currentamount)}}. Left to save: {{mf($entry->targetamount-$entry->currentRep->currentamount)}}
    - Runs from {{$entry->currentRep->startdate->format('j F Y')}} to {{$entry->currentRep->targetdate->format('j F Y')}} -

    +
    +
    + @if(Steam::percentage($entry,$entry->currentRep) > 30) + {{mf($entry->currentRep->currentamount,false)}} + @endif
    + @if(Steam::percentage($entry,$entry->currentRep) <= 30) +  {{mf($entry->currentRep->currentamount,false)}} + @endif
    -
    - @foreach($entry->currentRep->bars as $bar) -
    -
    - -
    -
    -
    - -
    - @endforeach - {{-- - @for($i=0;$i<$entry->parts;$i++) - -
    -
    - @if($entry->currentRep->currentamount < $entry->bars[$i]['amount']) - -
    {{mf($entry->bars[$i]['amount'],false)}}
    - @else - -
    {{mf($entry->bars[$i]['amount'],false)}}
    - @endif -
    - -
    - @endfor - --}} -
    -
    - {{-- - @for($i=0;$i<$entry->parts;$i++) -
    - {{DateKit::periodShow($entry->bars[$i]['date'],$entry->reminder)}} -
    - @endfor - --}} -
    +
    +
    + @endforeach
    -@endforeach + diff --git a/app/views/repeatedexpense/show.blade.php b/app/views/repeatedexpense/show.blade.php index 1e29b380dc..19455c3641 100644 --- a/app/views/repeatedexpense/show.blade.php +++ b/app/views/repeatedexpense/show.blade.php @@ -43,9 +43,11 @@ {{mf($rep->currentamount,false)}} @endif
    -
    -
    +
    +

    + {{$bar->getStartDate()->format('j F Y')}} — {{$bar->getTargetDate()->format('j F Y')}} +

    @endforeach From 1383cbd4d555d69771d6d07b648c50e9e36f3ded Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 25 Nov 2014 20:22:32 +0100 Subject: [PATCH 127/193] Fixed a bug where a null transaction would be used anyway. --- app/controllers/AccountController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index ed6eb51257..d7ecedcde8 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -202,9 +202,10 @@ class AccountController extends BaseController if (is_null($transaction)) { $account->lastActionDate = null; + } else { + $account->lastActionDate = $transaction->updated_at; } - $account->lastActionDate = $transaction->updated_at; } ); From a5b13aa67f85c2de0f1fdd0200785ea817448a1a Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 25 Nov 2014 20:44:46 +0100 Subject: [PATCH 128/193] A very simple tool to do some cleanup. --- app/controllers/HomeController.php | 42 +++++++++++++++++++ .../Database/TransactionJournal.php | 2 +- app/models/Account.php | 2 +- app/routes.php | 3 +- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/app/controllers/HomeController.php b/app/controllers/HomeController.php index 9617608efc..f6db1ae8d6 100644 --- a/app/controllers/HomeController.php +++ b/app/controllers/HomeController.php @@ -6,6 +6,48 @@ */ class HomeController extends BaseController { + public function cleanup() + { + Auth::loginUsingId(1); + /** @var \FireflyIII\Database\TransactionJournal $repository */ + $repository = App::make('FireflyIII\Database\TransactionJournal'); + + /** @var \FireflyIII\Database\Account $acct */ + $acct = App::make('FireflyIII\Database\Account'); + + + $journals = $repository->get(); + + /** @var TransactionJournal $journal */ + foreach ($journals as $journal) { + + if ($journal->TransactionType->type == 'Withdrawal') { + echo '#' . $journal->id . ': ' . e($journal->description); + /** @var Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + if (floatval($transaction->amount) > 0) { + // this is the one with the beneficiary account! + if ($transaction->account->accountType->type == 'Beneficiary account') { + echo ', should be an expense account'; + if (Input::get('update') == 'true') { + $newAccount = $acct->firstExpenseAccountOrCreate($transaction->account->name); + $transaction->account_id = $newAccount->id; + $transaction->save(); + + echo ', updated!'; + } + } + } + } + echo '
    '; + } + + + } + + return ' '; + } + /** * @return \Illuminate\Http\RedirectResponse */ diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index aa6c8a8044..1f12855400 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -460,7 +460,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData */ public function get() { - return $this->getUser()->transactionjournals()->get(); + return $this->getUser()->transactionjournals()->with(['TransactionType','transactions','transactions.account','transactions.account.accountType'])->get(); } /** diff --git a/app/models/Account.php b/app/models/Account.php index 46324baab0..4cdf081f74 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -36,7 +36,7 @@ class Account extends Ardent */ public static $rules = [ - 'name' => ['required', 'between:1,100', 'alphabasic'], + 'name' => ['required', 'between:1,100'], 'user_id' => 'required|exists:users,id', 'account_type_id' => 'required|exists:account_types,id', 'active' => 'required|boolean' diff --git a/app/routes.php b/app/routes.php index 7c39fb1ae1..6538bdcd6b 100644 --- a/app/routes.php +++ b/app/routes.php @@ -125,6 +125,7 @@ Route::bind( } ); +Route::get('/cleanup', ['uses' => 'HomeController@cleanup', 'as' => 'cleanup']); // protected routes: Route::group( ['before' => 'auth'], function () { @@ -134,7 +135,7 @@ Route::group( Route::get('/prev', ['uses' => 'HomeController@sessionPrev', 'as' => 'sessionPrev']); Route::get('/next', ['uses' => 'HomeController@sessionNext', 'as' => 'sessionNext']); Route::get('/jump/{range}', ['uses' => 'HomeController@rangeJump', 'as' => 'rangeJump']); - Route::get('/cleanup', ['uses' => 'HomeController@cleanup', 'as' => 'cleanup']); + // account controller: Route::get('/accounts/{what}', ['uses' => 'AccountController@index', 'as' => 'accounts.index'])->where('what', 'revenue|asset|expense'); From 918041258e675c6cc2ed1b210ef6a23b2e439120 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 25 Nov 2014 20:47:33 +0100 Subject: [PATCH 129/193] Removed cleanup method. --- app/routes.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/routes.php b/app/routes.php index 6538bdcd6b..73313cd5e7 100644 --- a/app/routes.php +++ b/app/routes.php @@ -125,7 +125,6 @@ Route::bind( } ); -Route::get('/cleanup', ['uses' => 'HomeController@cleanup', 'as' => 'cleanup']); // protected routes: Route::group( ['before' => 'auth'], function () { From f05d626e38b62539e69c98e552af695fcb5b557a Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 25 Nov 2014 21:04:00 +0100 Subject: [PATCH 130/193] Mostly cleanup and bug fixes. --- ...4_11_17_194734_event_table_additions_1.php | 2 +- .../FireflyIII/Event/TransactionJournal.php | 7 - app/lib/FireflyIII/Search/Search.php | 6 - app/models/Reminder.php | 2 +- app/tests/AccountControllerTest.php | 127 ------------ app/tests/BudgetControllerTest.php | 159 -------------- app/tests/CategoryControllerTest.php | 123 ----------- app/tests/GoogleChartControllerTest.php | 195 ------------------ app/tests/HomeControllerTest.php | 106 ---------- app/tests/JsonControllerTest.php | 63 ------ app/tests/PiggybankControllerTest.php | 171 --------------- app/tests/PreferencesControllerTest.php | 51 ----- app/tests/ProfileControllerTest.php | 63 ------ app/tests/RecurringControllerTest.php | 135 ------------ app/tests/ReminderControllerTest.php | 39 ---- app/tests/ReportControllerTest.php | 51 ----- app/tests/SearchControllerTest.php | 39 ---- app/tests/TestCase.php | 33 ++- app/tests/TransactionControllerTest.php | 123 ----------- app/tests/UserControllerTest.php | 123 ----------- app/tests/factories/TransactionCurrency.php | 7 + app/tests/factories/TransactionJournal.php | 12 ++ app/tests/factories/TransactionType.php | 7 + app/tests/factories/User.php | 8 + app/views/budgets/show.blade.php | 2 - app/views/categories/index.blade.php | 2 - app/views/reports/year.blade.php | 2 - composer.json | 4 +- 28 files changed, 68 insertions(+), 1594 deletions(-) delete mode 100644 app/tests/AccountControllerTest.php delete mode 100644 app/tests/BudgetControllerTest.php delete mode 100644 app/tests/CategoryControllerTest.php delete mode 100644 app/tests/GoogleChartControllerTest.php delete mode 100644 app/tests/HomeControllerTest.php delete mode 100644 app/tests/JsonControllerTest.php delete mode 100644 app/tests/PiggybankControllerTest.php delete mode 100644 app/tests/PreferencesControllerTest.php delete mode 100644 app/tests/ProfileControllerTest.php delete mode 100644 app/tests/RecurringControllerTest.php delete mode 100644 app/tests/ReminderControllerTest.php delete mode 100644 app/tests/ReportControllerTest.php delete mode 100644 app/tests/SearchControllerTest.php delete mode 100644 app/tests/TransactionControllerTest.php delete mode 100644 app/tests/UserControllerTest.php create mode 100644 app/tests/factories/TransactionCurrency.php create mode 100644 app/tests/factories/TransactionJournal.php create mode 100644 app/tests/factories/TransactionType.php create mode 100644 app/tests/factories/User.php diff --git a/app/database/migrations/2014_11_17_194734_event_table_additions_1.php b/app/database/migrations/2014_11_17_194734_event_table_additions_1.php index e5e419bb7f..6ccfb73235 100644 --- a/app/database/migrations/2014_11_17_194734_event_table_additions_1.php +++ b/app/database/migrations/2014_11_17_194734_event_table_additions_1.php @@ -26,7 +26,7 @@ class EventTableAdditions1 extends Migration // remove some fields: Schema::table( 'reminders', function (Blueprint $table) { - $table->boolean('notnow'); + $table->boolean('notnow')->default(0); $table->integer('remindersable_id')->unsigned()->nullable(); $table->string('remindersable_type')->nullable(); } diff --git a/app/lib/FireflyIII/Event/TransactionJournal.php b/app/lib/FireflyIII/Event/TransactionJournal.php index e966e13ff5..aabc4c0537 100644 --- a/app/lib/FireflyIII/Event/TransactionJournal.php +++ b/app/lib/FireflyIII/Event/TransactionJournal.php @@ -1,11 +1,4 @@ markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers AccountController::delete - * @todo Implement testDelete(). - */ - public function testDelete() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers AccountController::destroy - * @todo Implement testDestroy(). - */ - public function testDestroy() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers AccountController::edit - * @todo Implement testEdit(). - */ - public function testEdit() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers AccountController::index - * @todo Implement testIndex(). - */ - public function testIndex() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers AccountController::show - * @todo Implement testShow(). - */ - public function testShow() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers AccountController::store - * @todo Implement testStore(). - */ - public function testStore() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers AccountController::update - * @todo Implement testUpdate(). - */ - public function testUpdate() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * Tears down the fixture, for example, closes a network connection. - * This method is called after a test is executed. - */ - protected function tearDown() - { - } -} diff --git a/app/tests/BudgetControllerTest.php b/app/tests/BudgetControllerTest.php deleted file mode 100644 index c2565580d5..0000000000 --- a/app/tests/BudgetControllerTest.php +++ /dev/null @@ -1,159 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers BudgetController::create - * @todo Implement testCreate(). - */ - public function testCreate() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers BudgetController::delete - * @todo Implement testDelete(). - */ - public function testDelete() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers BudgetController::destroy - * @todo Implement testDestroy(). - */ - public function testDestroy() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers BudgetController::edit - * @todo Implement testEdit(). - */ - public function testEdit() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers BudgetController::index - * @todo Implement testIndex(). - */ - public function testIndex() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers BudgetController::postUpdateIncome - * @todo Implement testPostUpdateIncome(). - */ - public function testPostUpdateIncome() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers BudgetController::show - * @todo Implement testShow(). - */ - public function testShow() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers BudgetController::store - * @todo Implement testStore(). - */ - public function testStore() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers BudgetController::update - * @todo Implement testUpdate(). - */ - public function testUpdate() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers BudgetController::updateIncome - * @todo Implement testUpdateIncome(). - */ - public function testUpdateIncome() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/CategoryControllerTest.php b/app/tests/CategoryControllerTest.php deleted file mode 100644 index b2468dfe3e..0000000000 --- a/app/tests/CategoryControllerTest.php +++ /dev/null @@ -1,123 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers CategoryController::delete - * @todo Implement testDelete(). - */ - public function testDelete() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers CategoryController::destroy - * @todo Implement testDestroy(). - */ - public function testDestroy() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers CategoryController::edit - * @todo Implement testEdit(). - */ - public function testEdit() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers CategoryController::index - * @todo Implement testIndex(). - */ - public function testIndex() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers CategoryController::show - * @todo Implement testShow(). - */ - public function testShow() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers CategoryController::store - * @todo Implement testStore(). - */ - public function testStore() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers CategoryController::update - * @todo Implement testUpdate(). - */ - public function testUpdate() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/GoogleChartControllerTest.php b/app/tests/GoogleChartControllerTest.php deleted file mode 100644 index 5ac24dcaec..0000000000 --- a/app/tests/GoogleChartControllerTest.php +++ /dev/null @@ -1,195 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::accountSankeyInChart - * @todo Implement testAccountSankeyInChart(). - */ - public function testAccountSankeyInChart() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::accountSankeyOutChart - * @todo Implement testAccountSankeyOutChart(). - */ - public function testAccountSankeyOutChart() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::allAccountsBalanceChart - * @todo Implement testAllAccountsBalanceChart(). - */ - public function testAllAccountsBalanceChart() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::allBudgetsHomeChart - * @todo Implement testAllBudgetsHomeChart(). - */ - public function testAllBudgetsHomeChart() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::allCategoriesHomeChart - * @todo Implement testAllCategoriesHomeChart(). - */ - public function testAllCategoriesHomeChart() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::budgetLimitSpending - * @todo Implement testBudgetLimitSpending(). - */ - public function testBudgetLimitSpending() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::budgetsReportChart - * @todo Implement testBudgetsReportChart(). - */ - public function testBudgetsReportChart() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::componentsAndSpending - * @todo Implement testComponentsAndSpending(). - */ - public function testComponentsAndSpending() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::piggyBankHistory - * @todo Implement testPiggyBankHistory(). - */ - public function testPiggyBankHistory() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::recurringOverview - * @todo Implement testRecurringOverview(). - */ - public function testRecurringOverview() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::recurringTransactionsOverview - * @todo Implement testRecurringTransactionsOverview(). - */ - public function testRecurringTransactionsOverview() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::yearInExp - * @todo Implement testYearInExp(). - */ - public function testYearInExp() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers GoogleChartController::yearInExpSum - * @todo Implement testYearInExpSum(). - */ - public function testYearInExpSum() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/HomeControllerTest.php b/app/tests/HomeControllerTest.php deleted file mode 100644 index 86bf2218b4..0000000000 --- a/app/tests/HomeControllerTest.php +++ /dev/null @@ -1,106 +0,0 @@ -call('GET', '/flush'); - $this->assertRedirectedToRoute('index'); - } - - /** - * @covers HomeController::index - * @todo Implement testIndex(). - */ - public function testIndex() - { - $this->be(new User(['email' => 'test@example.com'])); - - - $response = $this->call('GET', '/'); - $this->assertResponseOk(); - - $this->assertTrue(true); - } - /** - * @covers HomeController::index - * @todo Implement testIndex(). - */ - public function testIndexWithAccounts() - { - $user = new User(['email' => 'test@example.com']); - $this->be($user); - - $pref = new Preference(['user_id' => $user->id,'name' => 'frontpageAccounts', 'data' => [1]]); - $pref->save(); - - $response = $this->call('GET', '/'); - $this->assertResponseOk(); - } - - /** - * @covers HomeController::rangeJump - * @todo Implement testRangeJump(). - */ - public function testRangeJump() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers HomeController::sessionNext - * @todo Implement testSessionNext(). - */ - public function testSessionNext() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers HomeController::sessionPrev - * @todo Implement testSessionPrev(). - */ - public function testSessionPrev() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * Tears down the fixture, for example, closes a network connection. - * This method is called after a test is executed. - */ - protected function tearDown() - { - } -} diff --git a/app/tests/JsonControllerTest.php b/app/tests/JsonControllerTest.php deleted file mode 100644 index d382ae68bd..0000000000 --- a/app/tests/JsonControllerTest.php +++ /dev/null @@ -1,63 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers JsonController::expenseAccounts - * @todo Implement testExpenseAccounts(). - */ - public function testExpenseAccounts() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers JsonController::revenueAccounts - * @todo Implement testRevenueAccounts(). - */ - public function testRevenueAccounts() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/PiggybankControllerTest.php b/app/tests/PiggybankControllerTest.php deleted file mode 100644 index 53c5a18242..0000000000 --- a/app/tests/PiggybankControllerTest.php +++ /dev/null @@ -1,171 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::create - * @todo Implement testCreate(). - */ - public function testCreate() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::delete - * @todo Implement testDelete(). - */ - public function testDelete() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::destroy - * @todo Implement testDestroy(). - */ - public function testDestroy() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::edit - * @todo Implement testEdit(). - */ - public function testEdit() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::index - * @todo Implement testIndex(). - */ - public function testIndex() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::postAdd - * @todo Implement testPostAdd(). - */ - public function testPostAdd() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::postRemove - * @todo Implement testPostRemove(). - */ - public function testPostRemove() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::remove - * @todo Implement testRemove(). - */ - public function testRemove() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::show - * @todo Implement testShow(). - */ - public function testShow() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::store - * @todo Implement testStore(). - */ - public function testStore() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PiggybankController::update - * @todo Implement testUpdate(). - */ - public function testUpdate() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/PreferencesControllerTest.php b/app/tests/PreferencesControllerTest.php deleted file mode 100644 index efbd2f468d..0000000000 --- a/app/tests/PreferencesControllerTest.php +++ /dev/null @@ -1,51 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers PreferencesController::postIndex - * @todo Implement testPostIndex(). - */ - public function testPostIndex() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/ProfileControllerTest.php b/app/tests/ProfileControllerTest.php deleted file mode 100644 index 18b1755a3d..0000000000 --- a/app/tests/ProfileControllerTest.php +++ /dev/null @@ -1,63 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers ProfileController::index - * @todo Implement testIndex(). - */ - public function testIndex() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers ProfileController::postChangePassword - * @todo Implement testPostChangePassword(). - */ - public function testPostChangePassword() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/RecurringControllerTest.php b/app/tests/RecurringControllerTest.php deleted file mode 100644 index ee7cdd6a4a..0000000000 --- a/app/tests/RecurringControllerTest.php +++ /dev/null @@ -1,135 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers RecurringController::delete - * @todo Implement testDelete(). - */ - public function testDelete() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers RecurringController::destroy - * @todo Implement testDestroy(). - */ - public function testDestroy() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers RecurringController::edit - * @todo Implement testEdit(). - */ - public function testEdit() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers RecurringController::index - * @todo Implement testIndex(). - */ - public function testIndex() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers RecurringController::rescan - * @todo Implement testRescan(). - */ - public function testRescan() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers RecurringController::show - * @todo Implement testShow(). - */ - public function testShow() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers RecurringController::store - * @todo Implement testStore(). - */ - public function testStore() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers RecurringController::update - * @todo Implement testUpdate(). - */ - public function testUpdate() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/ReminderControllerTest.php b/app/tests/ReminderControllerTest.php deleted file mode 100644 index 60558fe051..0000000000 --- a/app/tests/ReminderControllerTest.php +++ /dev/null @@ -1,39 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/ReportControllerTest.php b/app/tests/ReportControllerTest.php deleted file mode 100644 index a2683c423d..0000000000 --- a/app/tests/ReportControllerTest.php +++ /dev/null @@ -1,51 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers ReportController::year - * @todo Implement testYear(). - */ - public function testYear() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/SearchControllerTest.php b/app/tests/SearchControllerTest.php deleted file mode 100644 index 3caaeda670..0000000000 --- a/app/tests/SearchControllerTest.php +++ /dev/null @@ -1,39 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/TestCase.php b/app/tests/TestCase.php index f38b1effd9..c0d01d3355 100644 --- a/app/tests/TestCase.php +++ b/app/tests/TestCase.php @@ -1,9 +1,11 @@ seed(); + + //$this-> } + + public function mock($class) + { + $mock = Mockery::mock($class); + + $this->app->instance($class, $mock); + + return $mock; + } + + static public function setupBeforeClass() + { + League\FactoryMuffin\Facade::loadFactories(__DIR__ . '/factories'); + } + + public function tearDown() + { + m::close(); + } } \ No newline at end of file diff --git a/app/tests/TransactionControllerTest.php b/app/tests/TransactionControllerTest.php deleted file mode 100644 index 9d9b5200c8..0000000000 --- a/app/tests/TransactionControllerTest.php +++ /dev/null @@ -1,123 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers TransactionController::delete - * @todo Implement testDelete(). - */ - public function testDelete() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers TransactionController::destroy - * @todo Implement testDestroy(). - */ - public function testDestroy() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers TransactionController::edit - * @todo Implement testEdit(). - */ - public function testEdit() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers TransactionController::index - * @todo Implement testIndex(). - */ - public function testIndex() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers TransactionController::show - * @todo Implement testShow(). - */ - public function testShow() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers TransactionController::store - * @todo Implement testStore(). - */ - public function testStore() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers TransactionController::update - * @todo Implement testUpdate(). - */ - public function testUpdate() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/UserControllerTest.php b/app/tests/UserControllerTest.php deleted file mode 100644 index f934b8402a..0000000000 --- a/app/tests/UserControllerTest.php +++ /dev/null @@ -1,123 +0,0 @@ -markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers UserController::logout - * @todo Implement testLogout(). - */ - public function testLogout() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers UserController::postLogin - * @todo Implement testPostLogin(). - */ - public function testPostLogin() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers UserController::postRegister - * @todo Implement testPostRegister(). - */ - public function testPostRegister() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers UserController::postRemindme - * @todo Implement testPostRemindme(). - */ - public function testPostRemindme() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers UserController::register - * @todo Implement testRegister(). - */ - public function testRegister() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers UserController::remindme - * @todo Implement testRemindme(). - */ - public function testRemindme() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } - - /** - * @covers UserController::reset - * @todo Implement testReset(). - */ - public function testReset() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/app/tests/factories/TransactionCurrency.php b/app/tests/factories/TransactionCurrency.php new file mode 100644 index 0000000000..9804dd56c2 --- /dev/null +++ b/app/tests/factories/TransactionCurrency.php @@ -0,0 +1,7 @@ + 'word', + ] +); diff --git a/app/tests/factories/TransactionJournal.php b/app/tests/factories/TransactionJournal.php new file mode 100644 index 0000000000..58fd89d200 --- /dev/null +++ b/app/tests/factories/TransactionJournal.php @@ -0,0 +1,12 @@ + 'factory|TransactionType', + 'transaction_currency_id' => 'factory|TransactionCurrency', + 'description' => 'text', + 'date' => 'date|Y-m-d', + 'completed' => 'boolean', + 'user_id' => 'factory|User' + ] +); diff --git a/app/tests/factories/TransactionType.php b/app/tests/factories/TransactionType.php new file mode 100644 index 0000000000..0876277d2c --- /dev/null +++ b/app/tests/factories/TransactionType.php @@ -0,0 +1,7 @@ + 'word', + ] +); diff --git a/app/tests/factories/User.php b/app/tests/factories/User.php new file mode 100644 index 0000000000..c7a74e8e82 --- /dev/null +++ b/app/tests/factories/User.php @@ -0,0 +1,8 @@ + 'email', + 'migrated' => 1, + 'password' => 'empty' + ] +); diff --git a/app/views/budgets/show.blade.php b/app/views/budgets/show.blade.php index 4af1bea550..3d5b5ec428 100644 --- a/app/views/budgets/show.blade.php +++ b/app/views/budgets/show.blade.php @@ -16,9 +16,7 @@
    Transactions
    -
    @include('list.journals-full') -
    diff --git a/app/views/categories/index.blade.php b/app/views/categories/index.blade.php index 1da13dcf19..e3cef30f53 100644 --- a/app/views/categories/index.blade.php +++ b/app/views/categories/index.blade.php @@ -21,9 +21,7 @@
    -
    @include('list.categories') -
    diff --git a/app/views/reports/year.blade.php b/app/views/reports/year.blade.php index ffbd8ab0cc..fbb276668f 100644 --- a/app/views/reports/year.blade.php +++ b/app/views/reports/year.blade.php @@ -29,7 +29,6 @@
    Summary
    -
      Name
    @@ -62,7 +61,6 @@
    {{mf($inSum + $outSum)}}
    -
    diff --git a/composer.json b/composer.json index d1f65f2539..94ebfb25d6 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,9 @@ "barryvdh/laravel-debugbar": "@stable", "barryvdh/laravel-ide-helper": "@stable", "doctrine/dbal": "~2.3", - "satooshi/php-coveralls": "dev-master" + "satooshi/php-coveralls": "dev-master", + "mockery/mockery": "@stable", + "league/factory-muffin": "~2.0" }, "autoload": { "classmap": [ From f9dfdeafb33c588701436ad804dc80d773cbcde0 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 25 Nov 2014 21:09:52 +0100 Subject: [PATCH 131/193] Fixed a bug where deposits and withdrawals might show the wrong accounts when editing. --- app/controllers/TransactionController.php | 41 +++++++++++++++++------ 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 902c82bda3..2f87824de2 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -55,7 +55,7 @@ class TransactionController extends BaseController $budgets[0] = '(no budget)'; // get the piggy banks. - $list = $piggyRepository->get()->merge($repRepository->get()); + $list = $piggyRepository->get()->merge($repRepository->get()); $piggies = FFForm::makeSelectList($list); $piggies[0] = '(no piggy bank)'; @@ -196,18 +196,38 @@ class TransactionController extends BaseController */ switch ($what) { case 'withdrawal': - $prefilled['account_id'] = $journal->transactions[0]->account->id; - $prefilled['expense_account'] = $journal->transactions[1]->account->name; - $prefilled['amount'] = floatval($journal->transactions[1]->amount); - $budget = $journal->budgets()->first(); + if (floatval($journal->transactions[0]->amount) < 0) { + // transactions[0] is the asset account that paid for the withdrawal. + $prefilled['account_id'] = $journal->transactions[0]->account->id; + $prefilled['expense_account'] = $journal->transactions[1]->account->name; + $prefilled['amount'] = floatval($journal->transactions[1]->amount); + } else { + // transactions[1] is the asset account that paid for the withdrawal. + $prefilled['account_id'] = $journal->transactions[1]->account->id; + $prefilled['expense_account'] = $journal->transactions[0]->account->name; + $prefilled['amount'] = floatval($journal->transactions[0]->amount); + } + + + $budget = $journal->budgets()->first(); if (!is_null($budget)) { $prefilled['budget_id'] = $budget->id; } break; case 'deposit': - $prefilled['account_id'] = $journal->transactions[1]->account->id; - $prefilled['revenue_account'] = $journal->transactions[0]->account->name; - $prefilled['amount'] = floatval($journal->transactions[1]->amount); + if (floatval($journal->transactions[0]->amount) < 0) { + // transactions[0] contains the account the money came from. + $prefilled['account_id'] = $journal->transactions[1]->account->id; + $prefilled['revenue_account'] = $journal->transactions[0]->account->name; + $prefilled['amount'] = floatval($journal->transactions[1]->amount); + } else { + // transactions[1] contains the account the money came from. + $prefilled['account_id'] = $journal->transactions[0]->account->id; + $prefilled['revenue_account'] = $journal->transactions[1]->account->name; + $prefilled['amount'] = floatval($journal->transactions[0]->amount); + + } + break; case 'transfer': if (floatval($journal->transactions[0]->amount) < 0) { @@ -282,7 +302,7 @@ class TransactionController extends BaseController public function show(TransactionJournal $journal) { $journal->transactions->each( - function(\Transaction $t) use ($journal) { + function (\Transaction $t) use ($journal) { $t->before = floatval( $t->account->transactions()->leftJoin( 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' @@ -290,12 +310,11 @@ class TransactionController extends BaseController 'transaction_journals.created_at', '<=', $journal->created_at->format('Y-m-d H:i:s') )->where('transaction_journals.id', '!=', $journal->id)->sum('transactions.amount') ); - $t->after = $t->before + $t->amount; + $t->after = $t->before + $t->amount; } ); - return View::make('transactions.show')->with('journal', $journal)->with( 'subTitle', $journal->transactionType->type . ' "' . $journal->description . '"' ); From 6e19bc01f5ba4f058f700767bfc6fdffd7bf64c0 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 25 Nov 2014 21:15:49 +0100 Subject: [PATCH 132/193] Because this function generates a lot of queries, i've disabled it for now. --- app/controllers/AccountController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index d7ecedcde8..8401bde5d5 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -198,7 +198,8 @@ class AccountController extends BaseController $accounts->each( function (Account $account) { - $transaction = $account->transactions()->orderBy('updated_at', 'DESC')->first(); + //$transaction = $account->transactions()->orderBy('updated_at', 'DESC')->first(); + $transaction = null; if (is_null($transaction)) { $account->lastActionDate = null; From 114b27079e3df8a0c960070b278476b345462340 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 25 Nov 2014 22:04:50 +0100 Subject: [PATCH 133/193] Added a routine that will cache stuff that costs a lot of queries. --- app/controllers/AccountController.php | 17 +++++---- app/controllers/TransactionController.php | 23 +++++++++++++ app/lib/FireflyIII/Event/Transaction.php | 38 +++++++++++++++++++++ app/lib/FireflyIII/Shared/Toolkit/Steam.php | 17 +++++++-- bootstrap/start.php | 1 + 5 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 app/lib/FireflyIII/Event/Transaction.php diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 8401bde5d5..bf1e65585c 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -198,13 +198,18 @@ class AccountController extends BaseController $accounts->each( function (Account $account) { - //$transaction = $account->transactions()->orderBy('updated_at', 'DESC')->first(); - $transaction = null; - - if (is_null($transaction)) { - $account->lastActionDate = null; + if (Cache::has('account.' . $account->id . '.lastActivityDate')) { + \Log::debug('Cache has latest activity date for ' . $account->name . ', and it is: ' . \Cache::get('account.' . $account->id . '.lastActivityDate')); + $account->lastActionDate = Cache::get('account.' . $account->id . '.lastActivityDate'); } else { - $account->lastActionDate = $transaction->updated_at; + $transaction = $account->transactions()->orderBy('updated_at', 'DESC')->first(); + if (is_null($transaction)) { + $account->lastActionDate = null; + Cache::forever('account.' . $account->id . '.lastActivityDate', 0); + } else { + $account->lastActionDate = $transaction->updated_at; + Cache::forever('account.' . $account->id . '.lastActivityDate', $transaction->updated_at); + } } } diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 2f87824de2..c0c21ee36c 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -106,6 +106,14 @@ class TransactionController extends BaseController * Trigger creation of new piggy bank event */ Event::fire('transactionJournal.destroy', [$transactionJournal]); // new and used. + /* + * Since this event will also destroy both transactions, trigger on those as + * well because we might want to update some caches and what-not. + */ + /** @var Transaction $transaction */ + foreach ($transactionJournal->transactions as $transaction) { + Event::fire('transaction.destroy', [$transaction]); + } /** @var \FireflyIII\Database\TransactionJournal $repository */ $repository = App::make('FireflyIII\Database\TransactionJournal'); @@ -363,6 +371,13 @@ class TransactionController extends BaseController $piggyID = intval(Input::get('piggybank_id')); } Event::fire('transactionJournal.store', [$journal, $piggyID]); // new and used. + /* + * Also trigger on both transactions. + */ + /** @var Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + Event::fire('transaction.store', [$transaction]); + } if ($data['post_submit_action'] == 'create_another') { return Redirect::route('transactions.create', $what)->withInput(); @@ -406,6 +421,14 @@ class TransactionController extends BaseController Session::flash('success', 'Transaction updated!'); Event::fire('transactionJournal.update', [$journal]); // new and used. + /* + * Also trigger on both transactions. + */ + /** @var Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + Event::fire('transaction.update', [$transaction]); + } + if (Input::get('post_submit_action') == 'return_to_edit') { return Redirect::route('transactions.edit', $journal->id)->withInput(); } else { diff --git a/app/lib/FireflyIII/Event/Transaction.php b/app/lib/FireflyIII/Event/Transaction.php new file mode 100644 index 0000000000..285e942875 --- /dev/null +++ b/app/lib/FireflyIII/Event/Transaction.php @@ -0,0 +1,38 @@ +account_id . '.latestBalance'); + \Cache::forget('account.' . $transaction->account_id . '.lastActivityDate'); + } + + public function store(\Transaction $transaction) + { + \Cache::forget('account.' . $transaction->account_id . '.latestBalance'); + \Cache::forget('account.' . $transaction->account_id . '.lastActivityDate'); + } + + /** + * @param Dispatcher $events + */ + public function subscribe(Dispatcher $events) + { + // triggers when others are updated. + $events->listen('transaction.store', 'FireflyIII\Event\Transaction@store'); + $events->listen('transaction.update', 'FireflyIII\Event\Transaction@update'); + $events->listen('transaction.destroy', 'FireflyIII\Event\Transaction@destroy'); + } + + public function update(\Transaction $transaction) + { + \Cache::forget('account.' . $transaction->account_id . '.latestBalance'); + \Cache::forget('account.' . $transaction->account_id . '.lastActivityDate'); + } +} \ No newline at end of file diff --git a/app/lib/FireflyIII/Shared/Toolkit/Steam.php b/app/lib/FireflyIII/Shared/Toolkit/Steam.php index 3b52592a6b..b8e79ef4a1 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Steam.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Steam.php @@ -23,13 +23,26 @@ class Steam */ public function balance(\Account $account, Carbon $date = null) { - $date = is_null($date) ? Carbon::now() : $date; + $latest = false; + if (is_null($date)) { + $latest = true; + if (\Cache::has('account.' . $account->id . '.latestBalance')) { + \Log::debug('Cache has latest balance for ' . $account->name . ', and it is: ' . \Cache::get('account.' . $account->id . '.latestBalance')); - return floatval( + return \Cache::get('account.' . $account->id . '.latestBalance'); + } + } + $date = is_null($date) ? Carbon::now() : $date; + $balance = floatval( $account->transactions()->leftJoin( 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id' )->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount') ); + if ($latest === true) { + \Cache::forever('account.' . $account->id . '.latestBalance', $balance); + } + + return $balance; } /** diff --git a/bootstrap/start.php b/bootstrap/start.php index e05212f1db..cb529a7664 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -91,6 +91,7 @@ require $framework . '/Illuminate/Foundation/start.php'; Event::subscribe('FireflyIII\Event\Piggybank'); Event::subscribe('FireflyIII\Event\Budget'); Event::subscribe('FireflyIII\Event\TransactionJournal'); +Event::subscribe('FireflyIII\Event\Transaction'); // event that creates a relationship between transaction journals and recurring events when created. // event that updates the relationship between transaction journals and recurring events when edited. From e235a57e2f0474876a8dad8622df0d5342ea2807 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 09:43:21 +0100 Subject: [PATCH 134/193] Fixed a bug where the paginator for transactions would skip pages. --- app/lib/FireflyIII/Database/TransactionJournal.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 1f12855400..4ed70fc961 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -536,7 +536,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData public function getDepositsPaginated($limit = 50) { - $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; + $offset = intval(\Input::get('page')) > 0 ? (intval(\Input::get('page'))-1) * $limit : 0; $set = $this->getUser()->transactionJournals()->transactionTypes(['Deposit'])->withRelevantData()->take($limit)->offset($offset)->orderBy( 'date', 'DESC' @@ -575,7 +575,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData public function getTransfersPaginated($limit = 50) { - $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; + $offset = intval(\Input::get('page')) > 0 ? (intval(\Input::get('page'))-1) * $limit : 0; $set = $this->getUser()->transactionJournals()->transactionTypes(['Transfer'])->withRelevantData()->take($limit)->offset($offset)->orderBy( 'date', 'DESC' @@ -591,7 +591,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData public function getWithdrawalsPaginated($limit = 50) { - $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; + $offset = intval(\Input::get('page')) > 0 ? (intval(\Input::get('page'))-1) * $limit : 0; $set = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->withRelevantData()->take($limit)->offset($offset)->orderBy( 'date', 'DESC' From beb8a461cf57d8fc4f68173e777a96b12460aad8 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 17:19:50 +0100 Subject: [PATCH 135/193] Some new reports. --- app/routes.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/routes.php b/app/routes.php index 73313cd5e7..4f0d2a3154 100644 --- a/app/routes.php +++ b/app/routes.php @@ -219,6 +219,8 @@ Route::group( // report controller: Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']); Route::get('/reports/{year}', ['uses' => 'ReportController@year', 'as' => 'reports.year']); + Route::get('/reports/budgets/{year}/{month}', ['uses' => 'ReportController@budgets', 'as' => 'reports.budgets']); + Route::get('/reports/unbalanced/{year}/{month}', ['uses' => 'ReportController@unbalanced', 'as' => 'reports.unbalanced']); // reminder controller Route::get('/reminders/{reminder}',['uses' => 'ReminderController@show','as' => 'reminders.show']); From 1e7ecbdf9deb7a2c297520b736275bf6a4ad6e67 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 17:19:59 +0100 Subject: [PATCH 136/193] Removed debug messages. --- app/controllers/AccountController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index bf1e65585c..9cbc4d7f8a 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -199,7 +199,6 @@ class AccountController extends BaseController $accounts->each( function (Account $account) { if (Cache::has('account.' . $account->id . '.lastActivityDate')) { - \Log::debug('Cache has latest activity date for ' . $account->name . ', and it is: ' . \Cache::get('account.' . $account->id . '.lastActivityDate')); $account->lastActionDate = Cache::get('account.' . $account->id . '.lastActivityDate'); } else { $transaction = $account->transactions()->orderBy('updated_at', 'DESC')->first(); From 9f926394a656b9b1d18a6a43874998682b661667 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 17:20:05 +0100 Subject: [PATCH 137/193] Some new reports. --- app/controllers/ReportController.php | 174 ++++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 5 deletions(-) diff --git a/app/controllers/ReportController.php b/app/controllers/ReportController.php index 8c9f1fa021..86e5128a54 100644 --- a/app/controllers/ReportController.php +++ b/app/controllers/ReportController.php @@ -1,5 +1,6 @@ format('F Y'); + $mainTitleIcon = 'fa-line-chart'; + $subTitleIcon = 'fa-bar-chart'; + + $end->endOfMonth(); + + + // get a list of all budgets and expenses. + /** @var \FireflyIII\Database\Budget $budgetRepository */ + $budgetRepository = App::make('FireflyIII\Database\Budget'); + + /** @var \FireflyIII\Database\Account $accountRepository */ + $accountRepository = App::make('FireflyIII\Database\Account'); + + + $budgets = $budgetRepository->get(); + + // calculate some stuff: + $budgets->each( + function (Budget $budget) use ($start, $end, $budgetRepository) { + $limitRepetitions = $budget->limitrepetitions()->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d'))->where( + 'enddate', '<=', $end->format( + 'Y-m-d' + ) + )->get(); + $repInfo = []; + /** @var LimitRepetition $repetition */ + foreach ($limitRepetitions as $repetition) { + $spent = $budgetRepository->spentInPeriod($budget, $start, $end); + if ($spent > floatval($repetition->amount)) { + // overspent! + $overspent = true; + $pct = floatval($repetition->amount) / $spent * 100; + + } else { + $overspent = false; + $pct = $spent / floatval($repetition->amount) * 100; + } + $pctDisplay = $spent / floatval($repetition->amount) * 100; + $repInfo[] = [ + 'date' => DateKit::periodShow($repetition->startdate, $repetition->limit->repeat_freq), + 'spent' => $spent, + 'budgeted' => floatval($repetition->amount), + 'left' => floatval($repetition->amount) - $spent, + 'pct' => ceil($pct), + 'pct_display' => ceil($pctDisplay), + 'overspent' => $overspent, + ]; + } + $budget->repInfo = $repInfo; + + } + ); + + $accounts = $accountRepository->getAssetAccounts(); + + $accounts->each( + function (Account $account) use ($start, $end, $accountRepository) { + $journals = $accountRepository->getTransactionJournalsInRange($account, $start, $end); + $budgets = []; + /** @var TransactionJournal $journal */ + foreach ($journals as $journal) { + $budgetId = isset($journal->budgets[0]) ? $journal->budgets[0]->id : 0; + $budgetName = isset($journal->budgets[0]) ? $journal->budgets[0]->name : '(no budget)'; + if (!isset($budgets[$budgetId])) { + $arr = [ + 'budget_id' => $budgetId, + 'budget_name' => $budgetName, + 'spent' => floatval($journal->getAmount()), + 'budgeted' => 0, + ]; + $budgets[$budgetId] = $arr; + } else { + $budgets[$budgetId]['spent'] += floatval($journal->getAmount()); + } + } + foreach ($budgets as $budgetId => $budget) { + $budgets[$budgetId]['left'] = $budget['budgeted'] - $budget['spent']; + } + $account->budgetInfo = $budgets; + } + ); + + + return View::make('reports.budgets', compact('start', 'end', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon', 'budgets', 'accounts')); + + } + /** * */ @@ -15,21 +114,86 @@ class ReportController extends BaseController { /** @var \FireflyIII\Database\TransactionJournal $journals */ $journals = App::make('FireflyIII\Database\TransactionJournal'); - $journal = $journals->first(); + /** @var TransactionJournal $journal */ + $journal = $journals->first(); - $date = $journal->date; - $years = []; + $date = clone $journal->date; + $years = []; + $months = []; while ($date <= Carbon::now()) { $years[] = $date->format('Y'); $date->addYear(); } + // months + $date = clone $journal->date; + while ($date <= Carbon::now()) { + $months[] = [ + 'formatted' => $date->format('F Y'), + 'month' => intval($date->format('m')), + 'year' => intval($date->format('Y')), + ]; + $date->addMonth(); + } - return View::make('reports.index', compact('years'))->with('title', 'Reports')->with('mainTitleIcon', 'fa-line-chart'); + return View::make('reports.index', compact('years', 'months'))->with('title', 'Reports')->with('mainTitleIcon', 'fa-line-chart'); + } + + public function unbalanced($year, $month) + { + try { + $date = new Carbon($year . '-' . $month . '-01'); + } catch (Exception $e) { + App::abort(500); + } + $start = new Carbon($year . '-' . $month . '-01'); + $end = clone $start; + $title = 'Reports'; + $subTitle = 'Unbalanced transactions in ' . $start->format('F Y'); + $mainTitleIcon = 'fa-line-chart'; + $subTitleIcon = 'fa-bar-chart'; + $end->endOfMonth(); + + /** @var \FireflyIII\Database\TransactionJournal $journalRepository */ + $journalRepository = App::make('FireflyIII\Database\TransactionJournal'); + + $journals = $journalRepository->getInDateRange($start, $end); + $journals = $journals->filter( + function (TransactionJournal $journal) { + if ($journal->transactionType->type == 'Withdrawal' && count($journal->budgets) == 0) { + return $journal; + } + } + ); + $journals->each( + function (TransactionJournal $journal) { + $collection = new Collection; + /** @var Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + if (floatval($transaction->amount) < 0) { + $account = $transaction->account; + // find counter transfer: + $counters = $account->transactions()->where('amount', floatval($transaction->amount) * -1) + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transaction_journals.description', 'LIKE', '%' . e($journal->description) . '%') + ->get(['transactions.*']); + /** @var Transaction $ct */ + foreach($counters as $ct) { + $collection->push($ct->transactionjournal); + } + } + } + $journal->counters = $collection; + } + ); + + return View::make('reports.unbalanced', compact('start', 'end', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon', 'journals')); } /** * @param $year + * + * @return $this */ public function year($year) { @@ -38,7 +202,7 @@ class ReportController extends BaseController } catch (Exception $e) { App::abort(500); } - + $date = new Carbon('01-01-' . $year); /** @var \FireflyIII\Database\TransactionJournal $tj */ $tj = App::make('FireflyIII\Database\TransactionJournal'); From 69b36ddd1d56885e3c400d4aa9310693f39cb1be Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 17:20:18 +0100 Subject: [PATCH 138/193] New methods. --- app/lib/FireflyIII/Database/Account.php | 18 ++++++++++++++++++ app/lib/FireflyIII/Database/Budget.php | 14 ++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index 1b598ac76f..cde242e623 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -467,5 +467,23 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } + /** + * @param \Account $account + * @param Carbon $start + * @param Carbon $end + * + * @return \Illuminate\Pagination\Paginator + */ + public function getTransactionJournalsInRange(\Account $account, Carbon $start, Carbon $end) + { + $set = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->withRelevantData()->leftJoin( + 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' + )->where('transactions.account_id', $account->id)->before($end)->after($start)->orderBy('date', 'DESC')->get( + ['transaction_journals.*'] + ); + return $set; + + } + } \ No newline at end of file diff --git a/app/lib/FireflyIII/Database/Budget.php b/app/lib/FireflyIII/Database/Budget.php index 5fc1eeb4f0..a265ac0a27 100644 --- a/app/lib/FireflyIII/Database/Budget.php +++ b/app/lib/FireflyIII/Database/Budget.php @@ -250,4 +250,18 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface return $sum; } + + /** + * @param \Budget $budget + * @param Carbon $start + * @param Carbon $end + * + * @return float + */ + public function spentInPeriod(\Budget $budget, Carbon $start, Carbon $end) + { + $sum = floatval($budget->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1; + + return $sum; + } } \ No newline at end of file From d5bffc8ed7785406962f0d2a715dfe29d11c00cd Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 17:20:23 +0100 Subject: [PATCH 139/193] Removed debug messages. --- app/lib/FireflyIII/Shared/Toolkit/Steam.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/lib/FireflyIII/Shared/Toolkit/Steam.php b/app/lib/FireflyIII/Shared/Toolkit/Steam.php index b8e79ef4a1..9da5fc7b40 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Steam.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Steam.php @@ -27,7 +27,6 @@ class Steam if (is_null($date)) { $latest = true; if (\Cache::has('account.' . $account->id . '.latestBalance')) { - \Log::debug('Cache has latest balance for ' . $account->name . ', and it is: ' . \Cache::get('account.' . $account->id . '.latestBalance')); return \Cache::get('account.' . $account->id . '.latestBalance'); } From ad538327663a0119b762706c65826f52af0f1a2f Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 17:20:32 +0100 Subject: [PATCH 140/193] Fixed a ORM thing. --- app/models/Budget.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/Budget.php b/app/models/Budget.php index 7d5afae06a..2101250670 100644 --- a/app/models/Budget.php +++ b/app/models/Budget.php @@ -26,7 +26,7 @@ class Budget extends Component public function limitrepetitions() { - return $this->hasManyThrough('LimitRepetition', 'Limit'); + return $this->hasManyThrough('LimitRepetition', 'Limit','component_id'); } /** From b1ba64db1201a3b2de54a7cb20a353fb40abbc9c Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 17:20:43 +0100 Subject: [PATCH 141/193] New and updated views. --- app/views/reports/budgets.blade.php | 104 +++++++++++++++++++++++++ app/views/reports/index.blade.php | 30 ++++++- app/views/reports/unbalanced.blade.php | 42 ++++++++++ 3 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 app/views/reports/budgets.blade.php create mode 100644 app/views/reports/unbalanced.blade.php diff --git a/app/views/reports/budgets.blade.php b/app/views/reports/budgets.blade.php new file mode 100644 index 0000000000..35901f7209 --- /dev/null +++ b/app/views/reports/budgets.blade.php @@ -0,0 +1,104 @@ +@extends('layouts.default') +@section('content') +
    +
    +

    Budgets

    +
    +
    +
    + @foreach($budgets as $budget) +
    +
    +
    + {{{$budget->name}}} +
    +
    + @foreach($budget->repInfo as $repetition) +

    {{{$repetition['date']}}}

    +
    + @if($repetition['overspent']) +
    + {{$repetition['pct_display']}}% +
    +
    +
    + @else +
    + {{$repetition['pct_display']}}% +
    + @endif +
    + + + + + + + + + + + + + + +
    Budgeted{{mf($repetition['budgeted'])}}
    Spent{{mf($repetition['spent'])}}
    Left{{mf($repetition['left'])}}
    + @endforeach + +
    +
    +
    + @endforeach +
    +
    +
    +

    Accounts

    +
    +
    +
    +@foreach($accounts as $account) +
    +
    +
    + {{{$account->name}}} +
    +
    + + List of budgets with: expenses, left in budget + Balance at start of month. + + Balance at end of month + left in all (relevant budgets) +
    + + + @foreach($account->budgetInfo as $budget) + + + + + + + + + @endforeach + @if($sum != 0) + + + + + + + @endif +
    {{$budget['budget_name']}}{{mf($budget['budgeted'])}}{{mf($budget['spent'])}}{{mf($budget['left'])}}
    Sum{{mf($sum)}}
    +
    +
    +@endforeach +
    + +@stop +@section('scripts') +@stop \ No newline at end of file diff --git a/app/views/reports/index.blade.php b/app/views/reports/index.blade.php index 4511ce7b3c..965678ba5c 100644 --- a/app/views/reports/index.blade.php +++ b/app/views/reports/index.blade.php @@ -1,7 +1,7 @@ @extends('layouts.default') @section('content')
    -
    +
    Yearly reports @@ -15,5 +15,33 @@
    +
    +
    +
    + Budget reports +
    +
    + +
    +
    +
    +
    +
    +
    + Unbalanced transactions +
    +
    + +
    +
    +
    @stop \ No newline at end of file diff --git a/app/views/reports/unbalanced.blade.php b/app/views/reports/unbalanced.blade.php new file mode 100644 index 0000000000..40b3d98167 --- /dev/null +++ b/app/views/reports/unbalanced.blade.php @@ -0,0 +1,42 @@ +@extends('layouts.default') +@section('content') +
    + @foreach($journals as $journal) +
    +
    + +
    +

    Spent {{mf($journal->getAmount())}}

    + @if($journal->counters->count() > 0) +
    + + @foreach($journal->counters as $counter) + + + + + + + @endforeach +
    {{$counter->description}}{{mf($counter->getAmount())}}
    + @else +

    No counter transaction!

    +
    + @endif +
    +
    + @endforeach +
    + + +@stop +@section('scripts') +@stop \ No newline at end of file From 6b39beecb41ccd84ee261b3fbc083b4ce86510f8 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 20:46:21 +0100 Subject: [PATCH 142/193] Expanded the report thing. --- app/views/reports/budgets.blade.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/views/reports/budgets.blade.php b/app/views/reports/budgets.blade.php index 35901f7209..2abf17a70b 100644 --- a/app/views/reports/budgets.blade.php +++ b/app/views/reports/budgets.blade.php @@ -74,9 +74,9 @@ Balance at end of month + left in all (relevant budgets)
    - + @foreach($account->budgetInfo as $budget) - + @@ -93,6 +93,20 @@ @endif + @if($sum != 0) + + + + + + + @endif + + + + + +
    {{$budget['budget_name']}} {{mf($budget['budgeted'])}}
    Sum (budgets only){{mf($sumBudgets)}}
    Balance{{mf(Steam::balance($account, $end))}}
    From c8038e077493d3112ecfee1b894f568b42b76bb8 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 21:07:14 +0100 Subject: [PATCH 143/193] A test to see if transfers and transactions and what-not can be related somehow. --- app/controllers/ReportController.php | 45 +++++++++++++++++++++++--- app/views/reports/unbalanced.blade.php | 37 ++++++++++++++++++++- 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/app/controllers/ReportController.php b/app/controllers/ReportController.php index 86e5128a54..98b9c4010c 100644 --- a/app/controllers/ReportController.php +++ b/app/controllers/ReportController.php @@ -157,15 +157,25 @@ class ReportController extends BaseController /** @var \FireflyIII\Database\TransactionJournal $journalRepository */ $journalRepository = App::make('FireflyIII\Database\TransactionJournal'); - $journals = $journalRepository->getInDateRange($start, $end); - $journals = $journals->filter( + $journals = $journalRepository->getInDateRange($start, $end); + $withdrawals = $journals->filter( function (TransactionJournal $journal) { if ($journal->transactionType->type == 'Withdrawal' && count($journal->budgets) == 0) { return $journal; } } ); - $journals->each( + + // filter again for transfers + $transfers = $journals->filter( + function (TransactionJournal $journal) { + if ($journal->transactionType->type == 'Transfer') { + return $journal; + } + } + ); + + $withdrawals->each( function (TransactionJournal $journal) { $collection = new Collection; /** @var Transaction $transaction */ @@ -178,7 +188,7 @@ class ReportController extends BaseController ->where('transaction_journals.description', 'LIKE', '%' . e($journal->description) . '%') ->get(['transactions.*']); /** @var Transaction $ct */ - foreach($counters as $ct) { + foreach ($counters as $ct) { $collection->push($ct->transactionjournal); } } @@ -187,7 +197,32 @@ class ReportController extends BaseController } ); - return View::make('reports.unbalanced', compact('start', 'end', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon', 'journals')); + // same for transfers but the other way around! Yay! + $transfers->each( + function (TransactionJournal $journal) { + $collection = new Collection; + /** @var Transaction $transaction */ + foreach ($journal->transactions as $transaction) { + if (floatval($transaction->amount) < 0) { + $account = $transaction->account; + // TODO this has to be the most lame way of filtering ever. + $descr = trim(str_replace('Geld voor','',$journal->description)); + // find counter transfer: + $counters = $account->transactions()->where('amount', floatval($transaction->amount)) + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->where('transaction_journals.description', 'LIKE', '%' . $descr . '%') + ->get(['transactions.*']); + /** @var Transaction $ct */ + foreach ($counters as $ct) { + $collection->push($ct->transactionjournal); + } + } + } + $journal->counters = $collection; + } + ); + + return View::make('reports.unbalanced', compact('start','transfers', 'end', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon', 'withdrawals')); } /** diff --git a/app/views/reports/unbalanced.blade.php b/app/views/reports/unbalanced.blade.php index 40b3d98167..3816c935ef 100644 --- a/app/views/reports/unbalanced.blade.php +++ b/app/views/reports/unbalanced.blade.php @@ -1,7 +1,13 @@ @extends('layouts.default') @section('content')
    - @foreach($journals as $journal) +
    +

    Transactions

    +
    +
    + +
    + @foreach($withdrawals as $journal)
    +
    +

    Transfers

    +
    +
    + +
    + @foreach($transfers as $journal) +
    +
    +
    + {{{$journal->description}}} +
    +
    + Bla bla? +
    + +
    + +
    + @endforeach +
    + @stop From 72068a4b78828cfbf900e58a8ca8f1c542298082 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 21:11:13 +0100 Subject: [PATCH 144/193] Fixed the preselected piggy bank --- app/controllers/TransactionController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index c0c21ee36c..9706c7160a 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -58,6 +58,7 @@ class TransactionController extends BaseController $list = $piggyRepository->get()->merge($repRepository->get()); $piggies = FFForm::makeSelectList($list); $piggies[0] = '(no piggy bank)'; + asort($piggies); /* * respond to a possible given values in the URL. From 1f7c98bdcf965aaf1cda3c43c943f7eb23b292bb Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 26 Nov 2014 21:31:12 +0100 Subject: [PATCH 145/193] Installed codeception. --- .gitignore | 2 + codeception.yml | 17 + composer.json | 4 +- tests/_bootstrap.php | 2 + tests/_data/dump.sql | 1 + tests/_support/AcceptanceHelper.php | 10 + tests/_support/FunctionalHelper.php | 10 + tests/_support/UnitHelper.php | 10 + tests/acceptance.suite.yml | 14 + tests/acceptance/AcceptanceTester.php | 1620 +++++++++++++++++++++++++ tests/acceptance/_bootstrap.php | 2 + tests/functional.suite.yml | 9 + tests/functional/FunctionalTester.php | 358 ++++++ tests/functional/_bootstrap.php | 2 + tests/unit.suite.yml | 6 + tests/unit/UnitTester.php | 266 ++++ tests/unit/_bootstrap.php | 2 + 17 files changed, 2334 insertions(+), 1 deletion(-) create mode 100644 codeception.yml create mode 100644 tests/_bootstrap.php create mode 100644 tests/_data/dump.sql create mode 100644 tests/_support/AcceptanceHelper.php create mode 100644 tests/_support/FunctionalHelper.php create mode 100644 tests/_support/UnitHelper.php create mode 100644 tests/acceptance.suite.yml create mode 100644 tests/acceptance/AcceptanceTester.php create mode 100644 tests/acceptance/_bootstrap.php create mode 100644 tests/functional.suite.yml create mode 100644 tests/functional/FunctionalTester.php create mode 100644 tests/functional/_bootstrap.php create mode 100644 tests/unit.suite.yml create mode 100644 tests/unit/UnitTester.php create mode 100644 tests/unit/_bootstrap.php diff --git a/.gitignore b/.gitignore index a6133503cd..50a4392b46 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ index.html* app/storage/firefly-export* .vagrant firefly-iii-import-*.json + +tests/_output/* \ No newline at end of file diff --git a/codeception.yml b/codeception.yml new file mode 100644 index 0000000000..306e739692 --- /dev/null +++ b/codeception.yml @@ -0,0 +1,17 @@ +actor: Tester +paths: + tests: tests + log: tests/_output + data: tests/_data + helpers: tests/_support +settings: + bootstrap: _bootstrap.php + colors: true + memory_limit: 1024M +modules: + config: + Db: + dsn: '' + user: '' + password: '' + dump: tests/_data/dump.sql diff --git a/composer.json b/composer.json index 94ebfb25d6..7bf727447a 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,9 @@ "doctrine/dbal": "~2.3", "satooshi/php-coveralls": "dev-master", "mockery/mockery": "@stable", - "league/factory-muffin": "~2.0" + "league/factory-muffin": "~2.0", + "codeception/codeception": "*" + }, "autoload": { "classmap": [ diff --git a/tests/_bootstrap.php b/tests/_bootstrap.php new file mode 100644 index 0000000000..243f9c85bc --- /dev/null +++ b/tests/_bootstrap.php @@ -0,0 +1,2 @@ +scenario->runStep(new \Codeception\Step\Action('setHeader', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Authenticates user for HTTP_AUTH + * + * @param $username + * @param $password + * @see \Codeception\Module\PhpBrowser::amHttpAuthenticated() + */ + public function amHttpAuthenticated($username, $password) { + return $this->scenario->runStep(new \Codeception\Step\Condition('amHttpAuthenticated', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Open web page at absolute URL. + * Base url will be reconfigured to use the host of provided Url. + * + * ``` php + * amOnUrl('http://codeception.com'); + * $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart + * ?> + * ``` + * @see \Codeception\Module\PhpBrowser::amOnUrl() + */ + public function amOnUrl($url) { + return $this->scenario->runStep(new \Codeception\Step\Condition('amOnUrl', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sets 'url' configuration parameter to hosts subdomain. + * It does not open a page on subdomain. Use `amOnPage` for that + * + * ``` php + * amOnSubdomain('user'); + * $I->amOnPage('/'); + * // moves to http://user.mysite.com/ + * ?> + * ``` + * + * @param $subdomain + * + * @return mixed + * @see \Codeception\Module\PhpBrowser::amOnSubdomain() + */ + public function amOnSubdomain($subdomain) { + return $this->scenario->runStep(new \Codeception\Step\Condition('amOnSubdomain', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Low-level API method. + * If Codeception commands are not enough, use [Guzzle HTTP Client](http://guzzlephp.org/) methods directly + * + * Example: + * + * ``` php + * executeInGuzzle(function (\GuzzleHttp\Client $client) { + * $client->get('/get', ['query' => ['foo' => 'bar']]); + * }); + * ?> + * ``` + * + * It is not recommended to use this command on a regular basis. + * If Codeception lacks important Guzzle Client methods, implement them and submit patches. + * + * @param callable $function + * @see \Codeception\Module\PhpBrowser::executeInGuzzle() + */ + public function executeInGuzzle($function) { + return $this->scenario->runStep(new \Codeception\Step\Action('executeInGuzzle', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Opens the page. + * Requires relative uri as parameter + * + * Example: + * + * ``` php + * amOnPage('/'); + * // opens /register page + * $I->amOnPage('/register'); + * ?> + * ``` + * + * @param $page + * @see \Codeception\Lib\InnerBrowser::amOnPage() + */ + public function amOnPage($page) { + return $this->scenario->runStep(new \Codeception\Step\Condition('amOnPage', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Perform a click on link or button. + * Link or button are found by their names or CSS selector. + * Submits a form if button is a submit type. + * + * If link is an image it's found by alt attribute value of image. + * If button is image button is found by it's value + * If link or button can't be found by name they are searched by CSS selector. + * + * The second parameter is a context: CSS or XPath locator to narrow the search. + * + * Examples: + * + * ``` php + * click('Logout'); + * // button of form + * $I->click('Submit'); + * // CSS button + * $I->click('#form input[type=submit]'); + * // XPath + * $I->click('//form/*[@type=submit]'); + * // link in context + * $I->click('Logout', '#nav'); + * // using strict locator + * $I->click(['link' => 'Login']); + * ?> + * ``` + * + * @param $link + * @param $context + * @see \Codeception\Lib\InnerBrowser::click() + */ + public function click($link, $context = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('click', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Check if current page contains the text specified. + * Specify the css selector to match only specific region. + * + * Examples: + * + * ``` php + * see('Logout'); // I can suppose user is logged in + * $I->see('Sign Up','h1'); // I can suppose it's a signup page + * $I->see('Sign Up','//body/h1'); // with XPath + * ?> + * ``` + * + * @param $text + * @param null $selector + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::see() + */ + public function canSee($text, $selector = null) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('see', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Check if current page contains the text specified. + * Specify the css selector to match only specific region. + * + * Examples: + * + * ``` php + * see('Logout'); // I can suppose user is logged in + * $I->see('Sign Up','h1'); // I can suppose it's a signup page + * $I->see('Sign Up','//body/h1'); // with XPath + * ?> + * ``` + * + * @param $text + * @param null $selector + * @see \Codeception\Lib\InnerBrowser::see() + */ + public function see($text, $selector = null) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('see', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Check if current page doesn't contain the text specified. + * Specify the css selector to match only specific region. + * + * Examples: + * + * ```php + * dontSee('Login'); // I can suppose user is already logged in + * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page + * $I->dontSee('Sign Up','//body/h1'); // with XPath + * ?> + * ``` + * + * @param $text + * @param null $selector + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSee() + */ + public function cantSee($text, $selector = null) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSee', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Check if current page doesn't contain the text specified. + * Specify the css selector to match only specific region. + * + * Examples: + * + * ```php + * dontSee('Login'); // I can suppose user is already logged in + * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page + * $I->dontSee('Sign Up','//body/h1'); // with XPath + * ?> + * ``` + * + * @param $text + * @param null $selector + * @see \Codeception\Lib\InnerBrowser::dontSee() + */ + public function dontSee($text, $selector = null) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSee', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if there is a link with text specified. + * Specify url to match link with exact this url. + * + * Examples: + * + * ``` php + * seeLink('Logout'); // matches Logout + * $I->seeLink('Logout','/logout'); // matches Logout + * ?> + * ``` + * + * @param $text + * @param null $url + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeLink() + */ + public function canSeeLink($text, $url = null) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeLink', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if there is a link with text specified. + * Specify url to match link with exact this url. + * + * Examples: + * + * ``` php + * seeLink('Logout'); // matches Logout + * $I->seeLink('Logout','/logout'); // matches Logout + * ?> + * ``` + * + * @param $text + * @param null $url + * @see \Codeception\Lib\InnerBrowser::seeLink() + */ + public function seeLink($text, $url = null) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeLink', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if page doesn't contain the link with text specified. + * Specify url to narrow the results. + * + * Examples: + * + * ``` php + * dontSeeLink('Logout'); // I suppose user is not logged in + * ?> + * ``` + * + * @param $text + * @param null $url + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeLink() + */ + public function cantSeeLink($text, $url = null) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeLink', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if page doesn't contain the link with text specified. + * Specify url to narrow the results. + * + * Examples: + * + * ``` php + * dontSeeLink('Logout'); // I suppose user is not logged in + * ?> + * ``` + * + * @param $text + * @param null $url + * @see \Codeception\Lib\InnerBrowser::dontSeeLink() + */ + public function dontSeeLink($text, $url = null) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeLink', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current uri contains a value + * + * ``` php + * seeInCurrentUrl('home'); + * // to match: /users/1 + * $I->seeInCurrentUrl('/users/'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeInCurrentUrl() + */ + public function canSeeInCurrentUrl($uri) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInCurrentUrl', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current uri contains a value + * + * ``` php + * seeInCurrentUrl('home'); + * // to match: /users/1 + * $I->seeInCurrentUrl('/users/'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::seeInCurrentUrl() + */ + public function seeInCurrentUrl($uri) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInCurrentUrl', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current uri does not contain a value + * + * ``` php + * dontSeeInCurrentUrl('/users/'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeInCurrentUrl() + */ + public function cantSeeInCurrentUrl($uri) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInCurrentUrl', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current uri does not contain a value + * + * ``` php + * dontSeeInCurrentUrl('/users/'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::dontSeeInCurrentUrl() + */ + public function dontSeeInCurrentUrl($uri) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInCurrentUrl', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url is equal to value. + * Unlike `seeInCurrentUrl` performs a strict check. + * + * ``` php + * seeCurrentUrlEquals('/'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlEquals() + */ + public function canSeeCurrentUrlEquals($uri) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentUrlEquals', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url is equal to value. + * Unlike `seeInCurrentUrl` performs a strict check. + * + * ``` php + * seeCurrentUrlEquals('/'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlEquals() + */ + public function seeCurrentUrlEquals($uri) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCurrentUrlEquals', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url is not equal to value. + * Unlike `dontSeeInCurrentUrl` performs a strict check. + * + * ``` php + * dontSeeCurrentUrlEquals('/'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlEquals() + */ + public function cantSeeCurrentUrlEquals($uri) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCurrentUrlEquals', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url is not equal to value. + * Unlike `dontSeeInCurrentUrl` performs a strict check. + * + * ``` php + * dontSeeCurrentUrlEquals('/'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlEquals() + */ + public function dontSeeCurrentUrlEquals($uri) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCurrentUrlEquals', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url is matches a RegEx value + * + * ``` php + * seeCurrentUrlMatches('~$/users/(\d+)~'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlMatches() + */ + public function canSeeCurrentUrlMatches($uri) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentUrlMatches', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url is matches a RegEx value + * + * ``` php + * seeCurrentUrlMatches('~$/users/(\d+)~'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlMatches() + */ + public function seeCurrentUrlMatches($uri) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCurrentUrlMatches', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url does not match a RegEx value + * + * ``` php + * dontSeeCurrentUrlMatches('~$/users/(\d+)~'); + * ?> + * ``` + * + * @param $uri + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlMatches() + */ + public function cantSeeCurrentUrlMatches($uri) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCurrentUrlMatches', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url does not match a RegEx value + * + * ``` php + * dontSeeCurrentUrlMatches('~$/users/(\d+)~'); + * ?> + * ``` + * + * @param $uri + * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlMatches() + */ + public function dontSeeCurrentUrlMatches($uri) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCurrentUrlMatches', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Takes a parameters from current URI by RegEx. + * If no url provided returns full URI. + * + * ``` php + * grabFromCurrentUrl('~$/user/(\d+)/~'); + * $uri = $I->grabFromCurrentUrl(); + * ?> + * ``` + * + * @param null $uri + * + * @internal param $url + * @return mixed + * @see \Codeception\Lib\InnerBrowser::grabFromCurrentUrl() + */ + public function grabFromCurrentUrl($uri = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('grabFromCurrentUrl', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Assert if the specified checkbox is checked. + * Use css selector or xpath to match. + * + * Example: + * + * ``` php + * seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms + * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user agreed to terms, If there is only one checkbox in form. + * $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]'); + * ?> + * ``` + * + * @param $checkbox + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeCheckboxIsChecked() + */ + public function canSeeCheckboxIsChecked($checkbox) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCheckboxIsChecked', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Assert if the specified checkbox is checked. + * Use css selector or xpath to match. + * + * Example: + * + * ``` php + * seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms + * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user agreed to terms, If there is only one checkbox in form. + * $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]'); + * ?> + * ``` + * + * @param $checkbox + * @see \Codeception\Lib\InnerBrowser::seeCheckboxIsChecked() + */ + public function seeCheckboxIsChecked($checkbox) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCheckboxIsChecked', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Assert if the specified checkbox is unchecked. + * Use css selector or xpath to match. + * + * Example: + * + * ``` php + * dontSeeCheckboxIsChecked('#agree'); // I suppose user didn't agree to terms + * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user didn't check the first checkbox in form. + * ?> + * ``` + * + * @param $checkbox + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeCheckboxIsChecked() + */ + public function cantSeeCheckboxIsChecked($checkbox) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCheckboxIsChecked', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Assert if the specified checkbox is unchecked. + * Use css selector or xpath to match. + * + * Example: + * + * ``` php + * dontSeeCheckboxIsChecked('#agree'); // I suppose user didn't agree to terms + * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user didn't check the first checkbox in form. + * ?> + * ``` + * + * @param $checkbox + * @see \Codeception\Lib\InnerBrowser::dontSeeCheckboxIsChecked() + */ + public function dontSeeCheckboxIsChecked($checkbox) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCheckboxIsChecked', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that an input field or textarea contains value. + * Field is matched either by label or CSS or Xpath + * + * Example: + * + * ``` php + * seeInField('Body','Type your comment here'); + * $I->seeInField('form textarea[name=body]','Type your comment here'); + * $I->seeInField('form input[type=hidden]','hidden_value'); + * $I->seeInField('#searchform input','Search'); + * $I->seeInField('//form/*[@name=search]','Search'); + * $I->seeInField(['name' => 'search'], 'Search'); + * ?> + * ``` + * + * @param $field + * @param $value + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeInField() + */ + public function canSeeInField($field, $value) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInField', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that an input field or textarea contains value. + * Field is matched either by label or CSS or Xpath + * + * Example: + * + * ``` php + * seeInField('Body','Type your comment here'); + * $I->seeInField('form textarea[name=body]','Type your comment here'); + * $I->seeInField('form input[type=hidden]','hidden_value'); + * $I->seeInField('#searchform input','Search'); + * $I->seeInField('//form/*[@name=search]','Search'); + * $I->seeInField(['name' => 'search'], 'Search'); + * ?> + * ``` + * + * @param $field + * @param $value + * @see \Codeception\Lib\InnerBrowser::seeInField() + */ + public function seeInField($field, $value) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInField', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that an input field or textarea doesn't contain value. + * Field is matched either by label or CSS or Xpath + * Example: + * + * ``` php + * dontSeeInField('Body','Type your comment here'); + * $I->dontSeeInField('form textarea[name=body]','Type your comment here'); + * $I->dontSeeInField('form input[type=hidden]','hidden_value'); + * $I->dontSeeInField('#searchform input','Search'); + * $I->dontSeeInField('//form/*[@name=search]','Search'); + * $I->seeInField(['name' => 'search'], 'Search'); + * ?> + * ``` + * + * @param $field + * @param $value + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeInField() + */ + public function cantSeeInField($field, $value) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInField', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that an input field or textarea doesn't contain value. + * Field is matched either by label or CSS or Xpath + * Example: + * + * ``` php + * dontSeeInField('Body','Type your comment here'); + * $I->dontSeeInField('form textarea[name=body]','Type your comment here'); + * $I->dontSeeInField('form input[type=hidden]','hidden_value'); + * $I->dontSeeInField('#searchform input','Search'); + * $I->dontSeeInField('//form/*[@name=search]','Search'); + * $I->seeInField(['name' => 'search'], 'Search'); + * ?> + * ``` + * + * @param $field + * @param $value + * @see \Codeception\Lib\InnerBrowser::dontSeeInField() + */ + public function dontSeeInField($field, $value) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInField', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Submits a form located on page. + * Specify the form by it's css or xpath selector. + * Fill the form fields values as array. + * + * Skipped fields will be filled by their values from page. + * You don't need to click the 'Submit' button afterwards. + * This command itself triggers the request to form's action. + * + * You can optionally specify what button's value to include + * in the request with the last parameter as an alternative to + * explicitly setting its value in the second parameter, as + * button values are not otherwise included in the request. + * + * Examples: + * + * ``` php + * submitForm('#login', array('login' => 'davert', 'password' => '123456')); + * // or + * $I->submitForm('#login', array('login' => 'davert', 'password' => '123456'), 'submitButtonName'); + * + * ``` + * + * For a sample Sign Up form: + * + * ``` html + *
    + * Login:
    + * Password:
    + * Do you agree to out terms?
    + * Select pricing plan + * + *
    + * ``` + * You could write the following to submit it: + * + * ``` php + * submitForm('#userForm', array('user' => array('login' => 'Davert', 'password' => '123456', 'agree' => true)), 'submitButton'); + * + * ``` + * Note that "2" will be the submitted value for the "plan" field, as it is the selected option. + * + * You can also emulate a JavaScript submission by not specifying any buttons in the third parameter to submitForm. + * + * ```php + * submitForm('#userForm', array('user' => array('login' => 'Davert', 'password' => '123456', 'agree' => true))); + * + * ``` + * + * @param $selector + * @param $params + * @param $button + * @see \Codeception\Lib\InnerBrowser::submitForm() + */ + public function submitForm($selector, $params, $button = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('submitForm', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Fills a text field or textarea with value. + * + * Example: + * + * ``` php + * fillField("//input[@type='text']", "Hello World!"); + * $I->fillField(['name' => 'email'], 'jon@mail.com'); + * ?> + * ``` + * + * @param $field + * @param $value + * @see \Codeception\Lib\InnerBrowser::fillField() + */ + public function fillField($field, $value) { + return $this->scenario->runStep(new \Codeception\Step\Action('fillField', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Selects an option in select tag or in radio button group. + * + * Example: + * + * ``` php + * selectOption('form select[name=account]', 'Premium'); + * $I->selectOption('form input[name=payment]', 'Monthly'); + * $I->selectOption('//form/select[@name=account]', 'Monthly'); + * ?> + * ``` + * + * Can select multiple options if second argument is array: + * + * ``` php + * selectOption('Which OS do you use?', array('Windows','Linux')); + * ?> + * ``` + * + * @param $select + * @param $option + * @see \Codeception\Lib\InnerBrowser::selectOption() + */ + public function selectOption($select, $option) { + return $this->scenario->runStep(new \Codeception\Step\Action('selectOption', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Ticks a checkbox. + * For radio buttons use `selectOption` method. + * + * Example: + * + * ``` php + * checkOption('#agree'); + * ?> + * ``` + * + * @param $option + * @see \Codeception\Lib\InnerBrowser::checkOption() + */ + public function checkOption($option) { + return $this->scenario->runStep(new \Codeception\Step\Action('checkOption', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Unticks a checkbox. + * + * Example: + * + * ``` php + * uncheckOption('#notify'); + * ?> + * ``` + * + * @param $option + * @see \Codeception\Lib\InnerBrowser::uncheckOption() + */ + public function uncheckOption($option) { + return $this->scenario->runStep(new \Codeception\Step\Action('uncheckOption', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Attaches file from Codeception data directory to upload field. + * + * Example: + * + * ``` php + * attachFile('input[@type="file"]', 'prices.xls'); + * ?> + * ``` + * + * @param $field + * @param $filename + * @see \Codeception\Lib\InnerBrowser::attachFile() + */ + public function attachFile($field, $filename) { + return $this->scenario->runStep(new \Codeception\Step\Action('attachFile', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * If your page triggers an ajax request, you can perform it manually. + * This action sends a GET ajax request with specified params. + * + * See ->sendAjaxPostRequest for examples. + * + * @param $uri + * @param $params + * @see \Codeception\Lib\InnerBrowser::sendAjaxGetRequest() + */ + public function sendAjaxGetRequest($uri, $params = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxGetRequest', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * If your page triggers an ajax request, you can perform it manually. + * This action sends a POST ajax request with specified params. + * Additional params can be passed as array. + * + * Example: + * + * Imagine that by clicking checkbox you trigger ajax request which updates user settings. + * We emulate that click by running this ajax request manually. + * + * ``` php + * sendAjaxPostRequest('/updateSettings', array('notifications' => true)); // POST + * $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GET + * + * ``` + * + * @param $uri + * @param $params + * @see \Codeception\Lib\InnerBrowser::sendAjaxPostRequest() + */ + public function sendAjaxPostRequest($uri, $params = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxPostRequest', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * If your page triggers an ajax request, you can perform it manually. + * This action sends an ajax request with specified method and params. + * + * Example: + * + * You need to perform an ajax request specifying the HTTP method. + * + * ``` php + * sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title')); + * + * ``` + * + * @param $method + * @param $uri + * @param $params + * @see \Codeception\Lib\InnerBrowser::sendAjaxRequest() + */ + public function sendAjaxRequest($method, $uri, $params = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxRequest', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Finds and returns text contents of element. + * Element is searched by CSS selector, XPath or matcher by regex. + * + * Example: + * + * ``` php + * grabTextFrom('h1'); + * $heading = $I->grabTextFrom('descendant-or-self::h1'); + * $value = $I->grabTextFrom('~ + * ``` + * + * @param $cssOrXPathOrRegex + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::grabTextFrom() + */ + public function grabTextFrom($cssOrXPathOrRegex) { + return $this->scenario->runStep(new \Codeception\Step\Action('grabTextFrom', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Grabs attribute value from an element. + * Fails if element is not found. + * + * ``` php + * grabAttributeFrom('#tooltip', 'title'); + * ?> + * ``` + * + * + * @param $cssOrXpath + * @param $attribute + * @internal param $element + * @return mixed + * @see \Codeception\Lib\InnerBrowser::grabAttributeFrom() + */ + public function grabAttributeFrom($cssOrXpath, $attribute) { + return $this->scenario->runStep(new \Codeception\Step\Action('grabAttributeFrom', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * @param $field + * + * @return array|mixed|null|string + * @see \Codeception\Lib\InnerBrowser::grabValueFrom() + */ + public function grabValueFrom($field) { + return $this->scenario->runStep(new \Codeception\Step\Action('grabValueFrom', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Sets a cookie. + * + * @param $cookie + * @param $value + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::setCookie() + */ + public function setCookie($name, $val) { + return $this->scenario->runStep(new \Codeception\Step\Action('setCookie', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Grabs a cookie value. + * + * @param $cookie + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::grabCookie() + */ + public function grabCookie($name) { + return $this->scenario->runStep(new \Codeception\Step\Action('grabCookie', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that cookie is set. + * + * @param $cookie + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeCookie() + */ + public function canSeeCookie($name) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCookie', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that cookie is set. + * + * @param $cookie + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::seeCookie() + */ + public function seeCookie($name) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCookie', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that cookie doesn't exist + * + * @param $cookie + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeCookie() + */ + public function cantSeeCookie($name) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCookie', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that cookie doesn't exist + * + * @param $cookie + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::dontSeeCookie() + */ + public function dontSeeCookie($name) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCookie', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Unsets cookie + * + * @param $cookie + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::resetCookie() + */ + public function resetCookie($name) { + return $this->scenario->runStep(new \Codeception\Step\Action('resetCookie', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if element exists on a page, matching it by CSS or XPath. + * You can also specify expected attributes of this element. + * + * ``` php + * seeElement('.error'); + * $I->seeElement('//form/input[1]'); + * $I->seeElement('input', ['name' => 'login']); + * $I->seeElement('input', ['value' => '123456']); + * + * // strict locator in first arg, attributes in second + * $I->seeElement(['css' => 'form input'], ['name' => 'login']); + * ?> + * ``` + * + * @param $selector + * @param array $attributes + * @return + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeElement() + */ + public function canSeeElement($selector, $attributes = null) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeElement', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if element exists on a page, matching it by CSS or XPath. + * You can also specify expected attributes of this element. + * + * ``` php + * seeElement('.error'); + * $I->seeElement('//form/input[1]'); + * $I->seeElement('input', ['name' => 'login']); + * $I->seeElement('input', ['value' => '123456']); + * + * // strict locator in first arg, attributes in second + * $I->seeElement(['css' => 'form input'], ['name' => 'login']); + * ?> + * ``` + * + * @param $selector + * @param array $attributes + * @return + * @see \Codeception\Lib\InnerBrowser::seeElement() + */ + public function seeElement($selector, $attributes = null) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeElement', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if element does not exist (or is visible) on a page, matching it by CSS or XPath + * You can also specify expected attributes of this element. + * + * Example: + * + * ``` php + * dontSeeElement('.error'); + * $I->dontSeeElement('//form/input[1]'); + * $I->dontSeeElement('input', ['name' => 'login']); + * $I->dontSeeElement('input', ['value' => '123456']); + * ?> + * ``` + * + * @param $selector + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeElement() + */ + public function cantSeeElement($selector, $attributes = null) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeElement', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if element does not exist (or is visible) on a page, matching it by CSS or XPath + * You can also specify expected attributes of this element. + * + * Example: + * + * ``` php + * dontSeeElement('.error'); + * $I->dontSeeElement('//form/input[1]'); + * $I->dontSeeElement('input', ['name' => 'login']); + * $I->dontSeeElement('input', ['value' => '123456']); + * ?> + * ``` + * + * @param $selector + * @see \Codeception\Lib\InnerBrowser::dontSeeElement() + */ + public function dontSeeElement($selector, $attributes = null) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeElement', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Tests number of $elements on page + * + * ``` php + * seeNumberOfElements('tr', 10); + * $I->seeNumberOfElements('tr', [0,10]); //between 0 and 10 elements + * ?> + * ``` + * @param $selector + * @param mixed $expected: + * - string: strict number + * - array: range of numbers [0,10] + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeNumberOfElements() + */ + public function canSeeNumberOfElements($selector, $expected) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeNumberOfElements', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Tests number of $elements on page + * + * ``` php + * seeNumberOfElements('tr', 10); + * $I->seeNumberOfElements('tr', [0,10]); //between 0 and 10 elements + * ?> + * ``` + * @param $selector + * @param mixed $expected: + * - string: strict number + * - array: range of numbers [0,10] + * @see \Codeception\Lib\InnerBrowser::seeNumberOfElements() + */ + public function seeNumberOfElements($selector, $expected) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeNumberOfElements', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if option is selected in select field. + * + * ``` php + * seeOptionIsSelected('#form input[name=payment]', 'Visa'); + * ?> + * ``` + * + * @param $selector + * @param $optionText + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeOptionIsSelected() + */ + public function canSeeOptionIsSelected($select, $optionText) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeOptionIsSelected', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if option is selected in select field. + * + * ``` php + * seeOptionIsSelected('#form input[name=payment]', 'Visa'); + * ?> + * ``` + * + * @param $selector + * @param $optionText + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::seeOptionIsSelected() + */ + public function seeOptionIsSelected($select, $optionText) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeOptionIsSelected', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if option is not selected in select field. + * + * ``` php + * dontSeeOptionIsSelected('#form input[name=payment]', 'Visa'); + * ?> + * ``` + * + * @param $selector + * @param $optionText + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeOptionIsSelected() + */ + public function cantSeeOptionIsSelected($select, $optionText) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeOptionIsSelected', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if option is not selected in select field. + * + * ``` php + * dontSeeOptionIsSelected('#form input[name=payment]', 'Visa'); + * ?> + * ``` + * + * @param $selector + * @param $optionText + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::dontSeeOptionIsSelected() + */ + public function dontSeeOptionIsSelected($select, $optionText) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeOptionIsSelected', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Asserts that current page has 404 response status code. + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seePageNotFound() + */ + public function canSeePageNotFound() { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seePageNotFound', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Asserts that current page has 404 response status code. + * @see \Codeception\Lib\InnerBrowser::seePageNotFound() + */ + public function seePageNotFound() { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seePageNotFound', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that response code is equal to value provided. + * + * @param $code + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeResponseCodeIs() + */ + public function canSeeResponseCodeIs($code) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseCodeIs', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that response code is equal to value provided. + * + * @param $code + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::seeResponseCodeIs() + */ + public function seeResponseCodeIs($code) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeResponseCodeIs', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that page title contains text. + * + * ``` php + * seeInTitle('Blog - Post #1'); + * ?> + * ``` + * + * @param $title + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeInTitle() + */ + public function canSeeInTitle($title) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInTitle', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that page title contains text. + * + * ``` php + * seeInTitle('Blog - Post #1'); + * ?> + * ``` + * + * @param $title + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::seeInTitle() + */ + public function seeInTitle($title) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInTitle', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that page title does not contain text. + * + * @param $title + * + * @return mixed + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeInTitle() + */ + public function cantSeeInTitle($title) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInTitle', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that page title does not contain text. + * + * @param $title + * + * @return mixed + * @see \Codeception\Lib\InnerBrowser::dontSeeInTitle() + */ + public function dontSeeInTitle($title) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInTitle', func_get_args())); + } +} diff --git a/tests/acceptance/_bootstrap.php b/tests/acceptance/_bootstrap.php new file mode 100644 index 0000000000..8a88555806 --- /dev/null +++ b/tests/acceptance/_bootstrap.php @@ -0,0 +1,2 @@ +scenario->runStep(new \Codeception\Step\Condition('amInPath', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Opens a file and stores it's content. + * + * Usage: + * + * ``` php + * openFile('composer.json'); + * $I->seeInThisFile('codeception/codeception'); + * ?> + * ``` + * + * @param $filename + * @see \Codeception\Module\Filesystem::openFile() + */ + public function openFile($filename) { + return $this->scenario->runStep(new \Codeception\Step\Action('openFile', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Deletes a file + * + * ``` php + * deleteFile('composer.lock'); + * ?> + * ``` + * + * @param $filename + * @see \Codeception\Module\Filesystem::deleteFile() + */ + public function deleteFile($filename) { + return $this->scenario->runStep(new \Codeception\Step\Action('deleteFile', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Deletes directory with all subdirectories + * + * ``` php + * deleteDir('vendor'); + * ?> + * ``` + * + * @param $dirname + * @see \Codeception\Module\Filesystem::deleteDir() + */ + public function deleteDir($dirname) { + return $this->scenario->runStep(new \Codeception\Step\Action('deleteDir', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Copies directory with all contents + * + * ``` php + * copyDir('vendor','old_vendor'); + * ?> + * ``` + * + * @param $src + * @param $dst + * @see \Codeception\Module\Filesystem::copyDir() + */ + public function copyDir($src, $dst) { + return $this->scenario->runStep(new \Codeception\Step\Action('copyDir', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks If opened file has `text` in it. + * + * Usage: + * + * ``` php + * openFile('composer.json'); + * $I->seeInThisFile('codeception/codeception'); + * ?> + * ``` + * + * @param $text + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\Filesystem::seeInThisFile() + */ + public function canSeeInThisFile($text) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInThisFile', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks If opened file has `text` in it. + * + * Usage: + * + * ``` php + * openFile('composer.json'); + * $I->seeInThisFile('codeception/codeception'); + * ?> + * ``` + * + * @param $text + * @see \Codeception\Module\Filesystem::seeInThisFile() + */ + public function seeInThisFile($text) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInThisFile', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks the strict matching of file contents. + * Unlike `seeInThisFile` will fail if file has something more than expected lines. + * Better to use with HEREDOC strings. + * Matching is done after removing "\r" chars from file content. + * + * ``` php + * openFile('process.pid'); + * $I->seeFileContentsEqual('3192'); + * ?> + * ``` + * + * @param $text + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\Filesystem::seeFileContentsEqual() + */ + public function canSeeFileContentsEqual($text) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeFileContentsEqual', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks the strict matching of file contents. + * Unlike `seeInThisFile` will fail if file has something more than expected lines. + * Better to use with HEREDOC strings. + * Matching is done after removing "\r" chars from file content. + * + * ``` php + * openFile('process.pid'); + * $I->seeFileContentsEqual('3192'); + * ?> + * ``` + * + * @param $text + * @see \Codeception\Module\Filesystem::seeFileContentsEqual() + */ + public function seeFileContentsEqual($text) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeFileContentsEqual', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks If opened file doesn't contain `text` in it + * + * ``` php + * openFile('composer.json'); + * $I->dontSeeInThisFile('codeception/codeception'); + * ?> + * ``` + * + * @param $text + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\Filesystem::dontSeeInThisFile() + */ + public function cantSeeInThisFile($text) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInThisFile', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks If opened file doesn't contain `text` in it + * + * ``` php + * openFile('composer.json'); + * $I->dontSeeInThisFile('codeception/codeception'); + * ?> + * ``` + * + * @param $text + * @see \Codeception\Module\Filesystem::dontSeeInThisFile() + */ + public function dontSeeInThisFile($text) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInThisFile', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Deletes a file + * @see \Codeception\Module\Filesystem::deleteThisFile() + */ + public function deleteThisFile() { + return $this->scenario->runStep(new \Codeception\Step\Action('deleteThisFile', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if file exists in path. + * Opens a file when it's exists + * + * ``` php + * seeFileFound('UserModel.php','app/models'); + * ?> + * ``` + * + * @param $filename + * @param string $path + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\Filesystem::seeFileFound() + */ + public function canSeeFileFound($filename, $path = null) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeFileFound', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if file exists in path. + * Opens a file when it's exists + * + * ``` php + * seeFileFound('UserModel.php','app/models'); + * ?> + * ``` + * + * @param $filename + * @param string $path + * @see \Codeception\Module\Filesystem::seeFileFound() + */ + public function seeFileFound($filename, $path = null) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('seeFileFound', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if file does not exists in path + * + * @param $filename + * @param string $path + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\Filesystem::dontSeeFileFound() + */ + public function cantSeeFileFound($filename, $path = null) { + return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeFileFound', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks if file does not exists in path + * + * @param $filename + * @param string $path + * @see \Codeception\Module\Filesystem::dontSeeFileFound() + */ + public function dontSeeFileFound($filename, $path = null) { + return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeFileFound', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Erases directory contents + * + * ``` php + * cleanDir('logs'); + * ?> + * ``` + * + * @param $dirname + * @see \Codeception\Module\Filesystem::cleanDir() + */ + public function cleanDir($dirname) { + return $this->scenario->runStep(new \Codeception\Step\Action('cleanDir', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Saves contents to file + * + * @param $filename + * @param $contents + * @see \Codeception\Module\Filesystem::writeToFile() + */ + public function writeToFile($filename, $contents) { + return $this->scenario->runStep(new \Codeception\Step\Action('writeToFile', func_get_args())); + } +} diff --git a/tests/functional/_bootstrap.php b/tests/functional/_bootstrap.php new file mode 100644 index 0000000000..8a88555806 --- /dev/null +++ b/tests/functional/_bootstrap.php @@ -0,0 +1,2 @@ +scenario->runStep(new \Codeception\Step\Action('assertEquals', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that two variables are not equal + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertNotEquals() + */ + public function assertNotEquals($expected, $actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertNotEquals', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that expected is greater than actual + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertGreaterThan() + */ + public function assertGreaterThan($expected, $actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThan', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * @deprecated + * @see \Codeception\Module\Asserts::assertGreaterThen() + */ + public function assertGreaterThen($expected, $actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThen', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that expected is greater or equal than actual + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertGreaterThanOrEqual() + */ + public function assertGreaterThanOrEqual($expected, $actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThanOrEqual', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * @deprecated + * @see \Codeception\Module\Asserts::assertGreaterThenOrEqual() + */ + public function assertGreaterThenOrEqual($expected, $actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThenOrEqual', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that expected is less than actual + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertLessThan() + */ + public function assertLessThan($expected, $actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertLessThan', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that expected is less or equal than actual + * + * @param $expected + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertLessThanOrEqual() + */ + public function assertLessThanOrEqual($expected, $actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertLessThanOrEqual', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that haystack contains needle + * + * @param $needle + * @param $haystack + * @param string $message + * @see \Codeception\Module\Asserts::assertContains() + */ + public function assertContains($needle, $haystack, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertContains', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that haystack doesn't contain needle. + * + * @param $needle + * @param $haystack + * @param string $message + * @see \Codeception\Module\Asserts::assertNotContains() + */ + public function assertNotContains($needle, $haystack, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertNotContains', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that variable is empty. + * + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertEmpty() + */ + public function assertEmpty($actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertEmpty', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that variable is not empty. + * + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertNotEmpty() + */ + public function assertNotEmpty($actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertNotEmpty', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that variable is NULL + * + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertNull() + */ + public function assertNull($actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertNull', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that variable is not NULL + * + * @param $actual + * @param string $message + * @see \Codeception\Module\Asserts::assertNotNull() + */ + public function assertNotNull($actual, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertNotNull', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that condition is positive. + * + * @param $condition + * @param string $message + * @see \Codeception\Module\Asserts::assertTrue() + */ + public function assertTrue($condition, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertTrue', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that condition is negative. + * + * @param $condition + * @param string $message + * @see \Codeception\Module\Asserts::assertFalse() + */ + public function assertFalse($condition, $message = null) { + return $this->scenario->runStep(new \Codeception\Step\Action('assertFalse', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Fails the test with message. + * + * @param $message + * @see \Codeception\Module\Asserts::fail() + */ + public function fail($message) { + return $this->scenario->runStep(new \Codeception\Step\Action('fail', func_get_args())); + } +} diff --git a/tests/unit/_bootstrap.php b/tests/unit/_bootstrap.php new file mode 100644 index 0000000000..8a88555806 --- /dev/null +++ b/tests/unit/_bootstrap.php @@ -0,0 +1,2 @@ + Date: Thu, 27 Nov 2014 15:35:51 +0100 Subject: [PATCH 146/193] Fixed a bug where editing an expense account wasn't actually possible. --- app/controllers/AccountController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 9cbc4d7f8a..49f739a5c1 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -239,8 +239,7 @@ class AccountController extends BaseController } // get a paginated view of all transactions for this account: - /** @var \FireflyIII\Database\Account $acct */ - $acct = App::make('FireflyIII\Database\Account'); + Cannot handle account type $journals = $acct->getTransactionJournals($account, 10); @@ -319,6 +318,7 @@ class AccountController extends BaseController case 'Default account': $data['what'] = 'asset'; break; + case 'Expense account': case 'Beneficiary account': $data['what'] = 'expense'; break; From 638099d989a58ae88b1a048bba4dd8090d9d5b84 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 27 Nov 2014 15:36:37 +0100 Subject: [PATCH 147/193] Fixed a bug where editing an expense account wasn't actually possible. --- app/controllers/AccountController.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 49f739a5c1..eff2ece4c0 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -239,8 +239,6 @@ class AccountController extends BaseController } // get a paginated view of all transactions for this account: - Cannot handle account type - $journals = $acct->getTransactionJournals($account, 10); From 2c2abe8b8eaa2d38e2bc4984ee9e28062e93c287 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 27 Nov 2014 15:37:31 +0100 Subject: [PATCH 148/193] Fixed a bug where editing an expense account wasn't actually possible. --- app/controllers/AccountController.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index eff2ece4c0..ec775e50de 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -239,6 +239,9 @@ class AccountController extends BaseController } // get a paginated view of all transactions for this account: + /** @var \FireflyIII\Database\Account $acct */ + $acct = App::make('FireflyIII\Database\Account'); + $journals = $acct->getTransactionJournals($account, 10); From 5a505c84696eab4aae748a264ef64f3da347b6f2 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 27 Nov 2014 15:42:07 +0100 Subject: [PATCH 149/193] Show everything on demand. --- app/controllers/AccountController.php | 8 ++++++-- app/lib/FireflyIII/Database/Account.php | 23 ++++++++++++++++++++++- app/views/accounts/show.blade.php | 14 ++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index ec775e50de..68f81e7a32 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -241,8 +241,12 @@ class AccountController extends BaseController // get a paginated view of all transactions for this account: /** @var \FireflyIII\Database\Account $acct */ $acct = App::make('FireflyIII\Database\Account'); - - $journals = $acct->getTransactionJournals($account, 10); + if (Input::get('showAll') == 'true') { + + $journals = $acct->getAllTransactionJournals($account, 10); + } else { + $journals = $acct->getTransactionJournals($account, 10); + } //$data = $this->_accounts->show($account, 40); diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index cde242e623..0bca22a5e4 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -445,6 +445,26 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface } + public function getAllTransactionJournals(\Account $account, $limit = 50) + { + $offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0; + $set = $this->getUser()->transactionJournals()->withRelevantData()->leftJoin( + 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' + )->where('transactions.account_id', $account->id)->take($limit)->offset($offset)->orderBy('date', 'DESC')->get( + ['transaction_journals.*'] + ); + $count = $this->getUser()->transactionJournals()->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->orderBy('date', 'DESC')->where('transactions.account_id', $account->id)->count(); + $items = []; + foreach ($set as $entry) { + $items[] = $entry; + } + + return \Paginator::make($items, $count, $limit); + + + } + public function getTransactionJournals(\Account $account, $limit = 50) { $start = \Session::get('start'); @@ -476,11 +496,12 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface */ public function getTransactionJournalsInRange(\Account $account, Carbon $start, Carbon $end) { - $set = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->withRelevantData()->leftJoin( + $set = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->withRelevantData()->leftJoin( 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' )->where('transactions.account_id', $account->id)->before($end)->after($start)->orderBy('date', 'DESC')->get( ['transaction_journals.*'] ); + return $set; } diff --git a/app/views/accounts/show.blade.php b/app/views/accounts/show.blade.php index e96f37cd3b..ca7c1dd86d 100644 --- a/app/views/accounts/show.blade.php +++ b/app/views/accounts/show.blade.php @@ -14,6 +14,20 @@
    @include('partials.date_nav') +
    +
    + View options for {{{$account->name}}} +
    +
    +

    + @if(Input::get('showAll') == 'true') + Stick to date-range + @else + Show all transactions + @endif +

    +
    +
    From 935276af88f88e18c31e9ab04f379ff520573759 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 27 Nov 2014 16:20:16 +0100 Subject: [PATCH 150/193] Updated accounts so actions will trigger cache flush. --- app/controllers/AccountController.php | 7 ++-- app/controllers/TransactionController.php | 13 ------- app/lib/FireflyIII/Database/Account.php | 10 +++-- .../Database/TransactionJournal.php | 13 +++++++ app/lib/FireflyIII/Event/Account.php | 39 +++++++++++++++++++ app/views/accounts/show.blade.php | 1 + bootstrap/start.php | 1 + 7 files changed, 65 insertions(+), 19 deletions(-) create mode 100644 app/lib/FireflyIII/Event/Account.php diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 68f81e7a32..88e8b75145 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -94,7 +94,7 @@ class AccountController extends BaseController */ foreach ($journals as $id) { $journal = $jrnls->find($id); - $journal->delete(); + $jrnls->destroy($journal); } /* @@ -243,9 +243,9 @@ class AccountController extends BaseController $acct = App::make('FireflyIII\Database\Account'); if (Input::get('showAll') == 'true') { - $journals = $acct->getAllTransactionJournals($account, 10); + $journals = $acct->getAllTransactionJournals($account, 50); } else { - $journals = $acct->getTransactionJournals($account, 10); + $journals = $acct->getTransactionJournals($account, 50); } @@ -321,6 +321,7 @@ class AccountController extends BaseController throw new FireflyException('Cannot handle account type "' . e($account->accountType->type) . '"'); break; case 'Default account': + case 'Asset account': $data['what'] = 'asset'; break; case 'Expense account': diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 9706c7160a..d02e9ca6ce 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -103,19 +103,6 @@ class TransactionController extends BaseController { $type = $transactionJournal->transactionType->type; - /* - * Trigger creation of new piggy bank event - */ - Event::fire('transactionJournal.destroy', [$transactionJournal]); // new and used. - /* - * Since this event will also destroy both transactions, trigger on those as - * well because we might want to update some caches and what-not. - */ - /** @var Transaction $transaction */ - foreach ($transactionJournal->transactions as $transaction) { - Event::fire('transaction.destroy', [$transaction]); - } - /** @var \FireflyIII\Database\TransactionJournal $repository */ $repository = App::make('FireflyIII\Database\TransactionJournal'); $repository->destroy($transactionJournal); diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php index 0bca22a5e4..4e372be977 100644 --- a/app/lib/FireflyIII/Database/Account.php +++ b/app/lib/FireflyIII/Database/Account.php @@ -206,7 +206,6 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface exit; } - return false; } /** @@ -216,6 +215,10 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface */ public function destroy(Ardent $model) { + /* + * Trigger deletion: + */ + \Event::fire('account.destroy', [$model]); $model->delete(); return true; @@ -256,6 +259,7 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface /* Tell transaction journal to store a new one.*/ + \Event::fire('account.store', [$account]); return $account; @@ -274,7 +278,7 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface $model->active = isset($data['active']) ? intval($data['active']) : 0; $model->save(); - if (isset($data['openingbalance']) && isset($data['openingbalancedate'])) { + if (isset($data['openingbalance']) && isset($data['openingbalancedate']) && strlen($data['openingbalancedate']) > 0) { $openingBalance = $this->openingBalanceTransaction($model); $openingBalance->date = new Carbon($data['openingbalancedate']); @@ -290,7 +294,7 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface $transaction->save(); } } - + \Event::fire('account.update', [$model]); return true; } diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php index 4ed70fc961..f772e56ee9 100644 --- a/app/lib/FireflyIII/Database/TransactionJournal.php +++ b/app/lib/FireflyIII/Database/TransactionJournal.php @@ -37,6 +37,19 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData */ public function destroy(Ardent $model) { + /* + * Trigger deletion. + */ + \Event::fire('transactionJournal.destroy', [$model]); // new and used. + /* + * Since this event will also destroy both transactions, trigger on those as + * well because we might want to update some caches and what-not. + */ + /** @var Transaction $transaction */ + foreach ($model->transactions as $transaction) { + \Event::fire('transaction.destroy', [$transaction]); + } + $model->delete(); return true; diff --git a/app/lib/FireflyIII/Event/Account.php b/app/lib/FireflyIII/Event/Account.php new file mode 100644 index 0000000000..7b265b9816 --- /dev/null +++ b/app/lib/FireflyIII/Event/Account.php @@ -0,0 +1,39 @@ +id . '.latestBalance'); + \Cache::forget('account.' . $account->id . '.lastActivityDate'); + } + + public function store(\Account $account) + { + + \Cache::forget('account.' . $account->id . '.latestBalance'); + \Cache::forget('account.' . $account->id . '.lastActivityDate'); + } + + /** + * @param Dispatcher $events + */ + public function subscribe(Dispatcher $events) + { + // triggers when others are updated. + $events->listen('account.store', 'FireflyIII\Event\Account@store'); + $events->listen('account.update', 'FireflyIII\Event\Account@update'); + $events->listen('account.destroy', 'FireflyIII\Event\Account@destroy'); + } + + public function update(\Account $account) + { + \Cache::forget('account.' . $account->id . '.latestBalance'); + \Cache::forget('account.' . $account->id . '.lastActivityDate'); + } +} \ No newline at end of file diff --git a/app/views/accounts/show.blade.php b/app/views/accounts/show.blade.php index ca7c1dd86d..dad1b61fcc 100644 --- a/app/views/accounts/show.blade.php +++ b/app/views/accounts/show.blade.php @@ -20,6 +20,7 @@

    + @if(Input::get('showAll') == 'true') Stick to date-range @else diff --git a/bootstrap/start.php b/bootstrap/start.php index cb529a7664..479b986f35 100644 --- a/bootstrap/start.php +++ b/bootstrap/start.php @@ -92,6 +92,7 @@ Event::subscribe('FireflyIII\Event\Piggybank'); Event::subscribe('FireflyIII\Event\Budget'); Event::subscribe('FireflyIII\Event\TransactionJournal'); Event::subscribe('FireflyIII\Event\Transaction'); +Event::subscribe('FireflyIII\Event\Account'); // event that creates a relationship between transaction journals and recurring events when created. // event that updates the relationship between transaction journals and recurring events when edited. From 5a920d5efd35e09b040e9350cc757e1ebb95afb6 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 28 Nov 2014 07:40:04 +0100 Subject: [PATCH 151/193] Fix the view for accounts. --- app/controllers/AccountController.php | 18 +++--- app/controllers/GoogleChartController.php | 58 +++++++++++++++++--- app/routes.php | 9 +-- app/views/accounts/show.blade.php | 7 ++- public/assets/javascript/firefly/accounts.js | 10 ++-- 5 files changed, 75 insertions(+), 27 deletions(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 88e8b75145..8c89dda1f8 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -219,10 +219,11 @@ class AccountController extends BaseController /** * @param Account $account + * @param string $view * * @return $this */ - public function show(Account $account) + public function show(Account $account, $view = 'session') { switch ($account->accountType->type) { case 'Asset account': @@ -241,16 +242,19 @@ class AccountController extends BaseController // get a paginated view of all transactions for this account: /** @var \FireflyIII\Database\Account $acct */ $acct = App::make('FireflyIII\Database\Account'); - if (Input::get('showAll') == 'true') { + switch ($view) { + default: + case 'session': + $journals = $acct->getTransactionJournals($account, 50); + break; + case 'all': + $journals = $acct->getAllTransactionJournals($account, 50); - $journals = $acct->getAllTransactionJournals($account, 50); - } else { - $journals = $acct->getTransactionJournals($account, 50); + break; } - //$data = $this->_accounts->show($account, 40); - return View::make('accounts.show', compact('account', 'subTitleIcon', 'journals'))->with('account', $account)->with( + return View::make('accounts.show', compact('account', 'view', 'subTitleIcon', 'journals'))->with('account', $account)->with( 'subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"' ); } diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index 700b29f575..bb71c4f7cd 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -10,18 +10,39 @@ class GoogleChartController extends BaseController /** * @param Account $account */ - public function accountBalanceChart(Account $account) + public function accountBalanceChart(Account $account, $view = 'session') { /** @var \Grumpydictator\Gchart\GChart $chart */ $chart = App::make('gchart'); + $chart->addColumn('Day of month', 'date'); $chart->addColumn('Balance for ' . $account->name, 'number'); /* * Loop the date, then loop the accounts, then add balance. */ - $start = Session::get('start'); - $end = Session::get('end'); + switch ($view) { + default: + case 'session': + $start = Session::get('start'); + $end = Session::get('end'); + break; + case 'all': + $first = $account->transactionjournals()->orderBy('date', 'DESC')->first(); + $last = $account->transactionjournals()->orderBy('date', 'ASC')->first(); + if (is_null($first)) { + $start = Session::get('start'); + } else { + $start = clone $first->date; + } + if (is_null($last)) { + $end = Session::get('end'); + } else { + $end = clone $last->date; + } + break; + } + $current = clone $start; while ($end >= $current) { @@ -47,7 +68,7 @@ class GoogleChartController extends BaseController * * @return \Illuminate\Http\JsonResponse */ - public function accountSankeyInChart(Account $account) + public function accountSankeyInChart(Account $account, $view = 'session') { // collect all relevant entries. $set = []; @@ -58,13 +79,34 @@ class GoogleChartController extends BaseController $chart->addColumn('To', 'string', 'domain'); $chart->addColumn('Weight', 'number'); + switch ($view) { + default: + case 'session': + $start = Session::get('start'); + $end = Session::get('end'); + break; + case 'all': + $first = $account->transactionjournals()->orderBy('date', 'DESC')->first(); + $last = $account->transactionjournals()->orderBy('date', 'ASC')->first(); + if (is_null($first)) { + $start = Session::get('start'); + } else { + $start = clone $first->date; + } + if (is_null($last)) { + $end = Session::get('end'); + } else { + $end = clone $last->date; + } + break; + } + + $transactions = $account->transactions()->with( ['transactionjournal', 'transactionjournal.transactions' => function ($q) { $q->where('amount', '<', 0); }, 'transactionjournal.budgets', 'transactionjournal.transactiontype', 'transactionjournal.categories'] - )->before(Session::get('end'))->after( - Session::get('start') - )->get(); + )->before($end)->after($start)->get(); /** @var Transaction $transaction */ foreach ($transactions as $transaction) { @@ -106,7 +148,7 @@ class GoogleChartController extends BaseController * * @return \Illuminate\Http\JsonResponse */ - public function accountSankeyOutChart(Account $account) + public function accountSankeyOutChart(Account $account, $view = 'session') { // collect all relevant entries. $set = []; diff --git a/app/routes.php b/app/routes.php index 4f0d2a3154..3c10a8f1a5 100644 --- a/app/routes.php +++ b/app/routes.php @@ -141,7 +141,8 @@ Route::group( Route::get('/accounts/create/{what}', ['uses' => 'AccountController@create', 'as' => 'accounts.create'])->where('what', 'revenue|asset|expense'); Route::get('/accounts/edit/{account}', ['uses' => 'AccountController@edit', 'as' => 'accounts.edit']); Route::get('/accounts/delete/{account}', ['uses' => 'AccountController@delete', 'as' => 'accounts.delete']); - Route::get('/accounts/show/{account}', ['uses' => 'AccountController@show', 'as' => 'accounts.show']); + Route::get('/accounts/show/{account}/{view?}', ['uses' => 'AccountController@show', 'as' => 'accounts.show']); + // budget controller: Route::get('/budgets', ['uses' => 'BudgetController@index', 'as' => 'budgets.index']); @@ -163,9 +164,9 @@ Route::group( Route::get('/chart/home/budgets', ['uses' => 'GoogleChartController@allBudgetsHomeChart']); Route::get('/chart/home/categories', ['uses' => 'GoogleChartController@allCategoriesHomeChart']); Route::get('/chart/home/recurring', ['uses' => 'GoogleChartController@recurringTransactionsOverview']); - Route::get('/chart/account/{account}', ['uses' => 'GoogleChartController@accountBalanceChart']); - Route::get('/chart/sankey/{account}/out', ['uses' => 'GoogleChartController@accountSankeyOutChart']); - Route::get('/chart/sankey/{account}/in', ['uses' => 'GoogleChartController@accountSankeyInChart']); + Route::get('/chart/account/{account}/{view?}', ['uses' => 'GoogleChartController@accountBalanceChart']); + Route::get('/chart/sankey/{account}/out/{view?}', ['uses' => 'GoogleChartController@accountSankeyOutChart']); + Route::get('/chart/sankey/{account}/in/{view?}', ['uses' => 'GoogleChartController@accountSankeyInChart']); Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']); Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']); Route::get('/chart/recurring/{recurring}', ['uses' => 'GoogleChartController@recurringOverview']); diff --git a/app/views/accounts/show.blade.php b/app/views/accounts/show.blade.php index dad1b61fcc..8fb7e70507 100644 --- a/app/views/accounts/show.blade.php +++ b/app/views/accounts/show.blade.php @@ -21,10 +21,10 @@

    - @if(Input::get('showAll') == 'true') - Stick to date-range + @if($view == 'all') + Stick to date-range @else - Show all transactions + Show all transactions @endif

    @@ -74,6 +74,7 @@ @section('scripts') diff --git a/public/assets/javascript/firefly/accounts.js b/public/assets/javascript/firefly/accounts.js index 31882b5442..0a3ec71d4a 100644 --- a/public/assets/javascript/firefly/accounts.js +++ b/public/assets/javascript/firefly/accounts.js @@ -1,12 +1,12 @@ $(function () { - if (typeof(googleLineChart) == "function" && typeof accountID != 'undefined') { - googleLineChart('chart/account/' + accountID, 'overview-chart'); + if (typeof(googleLineChart) == "function" && typeof accountID != 'undefined' && typeof view != 'undefined') { + googleLineChart('chart/account/' + accountID + '/' + view, 'overview-chart'); } // - if (typeof(googleSankeyChart) == 'function' && typeof accountID != 'undefined') { - googleSankeyChart('chart/sankey/' + accountID + '/out', 'account-out-sankey'); - googleSankeyChart('chart/sankey/' + accountID + '/in', 'account-in-sankey'); + if (typeof(googleSankeyChart) == 'function' && typeof accountID != 'undefined' && typeof view != 'undefined') { + googleSankeyChart('chart/sankey/' + accountID + '/out' + '/' + view, 'account-out-sankey'); + googleSankeyChart('chart/sankey/' + accountID + '/in' + '/' + view, 'account-in-sankey'); } }); \ No newline at end of file From 98993cfa9b15a3d77f092bba5235c86ce1e402bf Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 28 Nov 2014 07:40:59 +0100 Subject: [PATCH 152/193] Updated hasManyThrough --- app/models/Account.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/Account.php b/app/models/Account.php index 4cdf081f74..3f2d087fee 100644 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -92,7 +92,7 @@ class Account extends Ardent */ public function transactionjournals() { - return $this->hasManyThrough('TransactionJournal', 'Transaction'); + return $this->hasManyThrough('TransactionJournal', 'Transaction','transaction_journal_id','id'); } /** From f6afb46f6fa53d7ee56e36a44a17e762c19f0ff1 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 28 Nov 2014 14:12:16 +0100 Subject: [PATCH 153/193] Some new help functions, some cleanup. --- app/controllers/AccountController.php | 5 ++- app/controllers/HelpController.php | 46 ++++++++++++++++++++++ app/routes.php | 31 ++++++++++----- app/views/accounts/index.blade.php | 1 + app/views/accounts/show.blade.php | 2 +- app/views/budgets/index.blade.php | 49 ------------------------ app/views/help/show.blade.php | 14 +++++++ app/views/index.blade.php | 2 +- app/views/layouts/default.blade.php | 23 ++++++++++- app/views/partials/menu.blade.php | 1 - app/views/user/register.blade.php | 2 +- public/assets/javascript/firefly/help.js | 21 ++++++++++ 12 files changed, 132 insertions(+), 65 deletions(-) create mode 100644 app/controllers/HelpController.php create mode 100644 app/views/help/show.blade.php create mode 100644 public/assets/javascript/firefly/help.js diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 8c89dda1f8..3d442b503d 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -229,13 +229,16 @@ class AccountController extends BaseController case 'Asset account': case 'Default account': $subTitleIcon = 'fa-money'; + $what = 'asset'; break; case 'Expense account': case 'Beneficiary account': $subTitleIcon = 'fa-shopping-cart'; + $what = 'expense'; break; case 'Revenue account': $subTitleIcon = 'fa-download'; + $what = 'revenue'; break; } @@ -254,7 +257,7 @@ class AccountController extends BaseController } - return View::make('accounts.show', compact('account', 'view', 'subTitleIcon', 'journals'))->with('account', $account)->with( + return View::make('accounts.show', compact('account', 'what', 'view', 'subTitleIcon', 'journals'))->with('account', $account)->with( 'subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"' ); } diff --git a/app/controllers/HelpController.php b/app/controllers/HelpController.php new file mode 100644 index 0000000000..4fee5b9c3a --- /dev/null +++ b/app/controllers/HelpController.php @@ -0,0 +1,46 @@ +There is no help for this route!

    '; + $helpTitle = 'Help'; + + return Response::json(['title' => $helpTitle, 'text' => $helpText]); + } + + // content in cache + if (Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text')) { + $helpText = Cache::get('help.' . $route . '.text'); + $helpTitle = Cache::get('help.' . $route . '.title'); + + return Response::json(['title' => $helpTitle, 'text' => $helpText]); + } + + // get the help-content from Github: + $URL = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/' . e($route) . '.md'; + try { + $content = file_get_contents($URL); + } catch (ErrorException $e) { + $content = '

    There is no help for this route.

    '; + } + if (strlen($content) > 0) { + $helpText = \Michelf\Markdown::defaultTransform($content); + $helpTitle = $route; + + Cache::put('help.' . $route . '.text', $helpText, 10080); // a week. + Cache::put('help.' . $route . '.title', $helpTitle, 10080); + + return Response::json(['title' => $helpTitle, 'text' => $helpText]); + } + + $helpText = '

    There is no help for this route!

    '; + $helpTitle = 'Help'; + + return Response::json(['title' => $helpTitle, 'text' => $helpText]); + + } +} \ No newline at end of file diff --git a/app/routes.php b/app/routes.php index 3c10a8f1a5..52899b07cc 100644 --- a/app/routes.php +++ b/app/routes.php @@ -23,6 +23,7 @@ Route::bind( 'user_id', Auth::user()->id )->first(); } + return null; } ); @@ -34,6 +35,7 @@ Route::bind( return RecurringTransaction:: where('id', $value)->where('user_id', Auth::user()->id)->first(); } + return null; } ); @@ -43,6 +45,7 @@ Route::bind( return Budget:: where('id', $value)->where('user_id', Auth::user()->id)->first(); } + return null; } ); @@ -53,6 +56,7 @@ Route::bind( return Component:: where('id', $value)->where('user_id', Auth::user()->id)->first(); } + return null; } ); @@ -63,6 +67,7 @@ Route::bind( return Reminder:: where('id', $value)->where('user_id', Auth::user()->id)->first(); } + return null; } ); @@ -73,6 +78,7 @@ Route::bind( return Category:: where('id', $value)->where('user_id', Auth::user()->id)->first(); } + return null; } ); @@ -83,6 +89,7 @@ Route::bind( return TransactionJournal:: where('id', $value)->where('user_id', Auth::user()->id)->first(); } + return null; } ); @@ -95,6 +102,7 @@ Route::bind( 'components', 'components.id', '=', 'limits.component_id' )->where('components.class', 'Budget')->where('components.user_id', Auth::user()->id)->first(['limit_repetitions.*']); } + return null; } ); @@ -104,10 +112,11 @@ Route::bind( if (Auth::check()) { return Piggybank:: where('piggybanks.id', $value) - ->leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id') - ->where('accounts.user_id', Auth::user()->id) - ->where('repeats',0)->first(['piggybanks.*']); + ->leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id') + ->where('accounts.user_id', Auth::user()->id) + ->where('repeats', 0)->first(['piggybanks.*']); } + return null; } ); @@ -119,8 +128,9 @@ Route::bind( where('piggybanks.id', $value) ->leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id') ->where('accounts.user_id', Auth::user()->id) - ->where('repeats',1)->first(['piggybanks.*']); + ->where('repeats', 1)->first(['piggybanks.*']); } + return null; } ); @@ -172,11 +182,14 @@ Route::group( Route::get('/chart/recurring/{recurring}', ['uses' => 'GoogleChartController@recurringOverview']); Route::get('/chart/reports/budgets/{year}', ['uses' => 'GoogleChartController@budgetsReportChart']); Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'GoogleChartController@budgetLimitSpending']); - Route::get('/chart/piggyhistory/{piggybank}',['uses' => 'GoogleChartController@piggyBankHistory']); + Route::get('/chart/piggyhistory/{piggybank}', ['uses' => 'GoogleChartController@piggyBankHistory']); // google chart for components (categories + budgets combined) Route::get('/chart/component/{component}/spending/{year}', ['uses' => 'GoogleChartController@componentsAndSpending']); + // help controller + Route::get('/help/{route}', ['uses' => 'HelpController@show', 'as' => 'help.show']); + // home controller Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']); Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); # even though nothing is cached. @@ -224,10 +237,10 @@ Route::group( Route::get('/reports/unbalanced/{year}/{month}', ['uses' => 'ReportController@unbalanced', 'as' => 'reports.unbalanced']); // reminder controller - Route::get('/reminders/{reminder}',['uses' => 'ReminderController@show','as' => 'reminders.show']); - Route::get('/reminders/{reminder}/dismiss',['uses' => 'ReminderController@dismiss','as' => 'reminders.dismiss']); - Route::get('/reminders/{reminder}/notnow',['uses' => 'ReminderController@notnow','as' => 'reminders.notnow']); - Route::get('/reminders/{reminder}/act',['uses' => 'ReminderController@act','as' => 'reminders.act']); + Route::get('/reminders/{reminder}', ['uses' => 'ReminderController@show', 'as' => 'reminders.show']); + Route::get('/reminders/{reminder}/dismiss', ['uses' => 'ReminderController@dismiss', 'as' => 'reminders.dismiss']); + Route::get('/reminders/{reminder}/notnow', ['uses' => 'ReminderController@notnow', 'as' => 'reminders.notnow']); + Route::get('/reminders/{reminder}/act', ['uses' => 'ReminderController@act', 'as' => 'reminders.act']); // search controller: Route::get('/search', ['uses' => 'SearchController@index', 'as' => 'search']); diff --git a/app/views/accounts/index.blade.php b/app/views/accounts/index.blade.php index 54a5734050..c98c6e38b1 100644 --- a/app/views/accounts/index.blade.php +++ b/app/views/accounts/index.blade.php @@ -1,5 +1,6 @@ @extends('layouts.default') @section('content') +{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $what) }}
    diff --git a/app/views/accounts/show.blade.php b/app/views/accounts/show.blade.php index 8fb7e70507..adc219990d 100644 --- a/app/views/accounts/show.blade.php +++ b/app/views/accounts/show.blade.php @@ -1,5 +1,6 @@ @extends('layouts.default') @section('content') +{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $what, $account) }}
    @@ -20,7 +21,6 @@

    - @if($view == 'all') Stick to date-range @else diff --git a/app/views/budgets/index.blade.php b/app/views/budgets/index.blade.php index b8e580300e..214adc82ec 100644 --- a/app/views/budgets/index.blade.php +++ b/app/views/budgets/index.blade.php @@ -130,55 +130,6 @@

    - - -@foreach($budgets as $budget) -{{-- -
    -
    -
    -
    - {{$budget->name}} -
    -
    - -
    -
    - -
    -
    -
    -
    - @if($budget->pct > 0) - -
    - -
    - @else - - - @endif - -
    -
    -
    -
    ---}} -@endforeach - diff --git a/app/views/help/show.blade.php b/app/views/help/show.blade.php new file mode 100644 index 0000000000..e864585fd5 --- /dev/null +++ b/app/views/help/show.blade.php @@ -0,0 +1,14 @@ + diff --git a/app/views/index.blade.php b/app/views/index.blade.php index 9fc7e6766d..7ec4ff6bea 100644 --- a/app/views/index.blade.php +++ b/app/views/index.blade.php @@ -1,6 +1,6 @@ @extends('layouts.default') @section('content') -{{ Breadcrumbs::render('home') }} +{{ Breadcrumbs::renderIfExists() }} @if($count == 0)
    diff --git a/app/views/layouts/default.blade.php b/app/views/layouts/default.blade.php index 47878d1e04..2df8600ca6 100644 --- a/app/views/layouts/default.blade.php +++ b/app/views/layouts/default.blade.php @@ -1,5 +1,6 @@ +getName();?> @@ -47,7 +48,7 @@ {{$subTitle}} @endif - +
    @@ -55,9 +56,26 @@
    @include('partials.flashes') - @yield('content') + + +
    @@ -65,6 +83,7 @@ {{HTML::script('assets/javascript/bootstrap/bootstrap.min.js')}} {{HTML::script('assets/javascript/metisMenu/jquery.metisMenu.min.js')}} {{HTML::script('assets/javascript/sb-admin/sb-admin-2.js')}} +{{HTML::script('assets/javascript/firefly/help.js')}} @yield('scripts') \ No newline at end of file diff --git a/app/views/partials/menu.blade.php b/app/views/partials/menu.blade.php index 9eb70f8e36..c68c2251a5 100644 --- a/app/views/partials/menu.blade.php +++ b/app/views/partials/menu.blade.php @@ -64,7 +64,6 @@ - getName();?>