diff --git a/app/assets/javascripts/accounts.js b/app/assets/javascripts/accounts.js
new file mode 100644
index 0000000000..a9d3956059
--- /dev/null
+++ b/app/assets/javascripts/accounts.js
@@ -0,0 +1,16 @@
+// This is a manifest file that'll be compiled into application.js, which will include all the files
+// listed below.
+//
+// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+// can be referenced here using a relative path.
+//
+// It's not advisable to add code directly here, but if you do, it'll appear in whatever order it
+// gets included (e.g. say you have require_tree . then the code will appear after all the directories
+// but before any files alphabetically greater than 'application.js'
+//
+// The available directives right now are require, require_directory, and require_tree
+//
+//= require highslide/highslide-full.min
+//= require highslide/highslide.config
+//= require_tree highcharts
+//= require firefly/accounts
diff --git a/app/assets/javascripts/firefly/accounts.js b/app/assets/javascripts/firefly/accounts.js
new file mode 100644
index 0000000000..67040dd4d5
--- /dev/null
+++ b/app/assets/javascripts/firefly/accounts.js
@@ -0,0 +1,95 @@
+$(function () {
+if($('#chart').length == 1) {
+ /**
+ * get data from controller for home charts:
+ */
+ $.getJSON('chart/home/account/' + accountID).success(function (data) {
+ var options = {
+ chart: {
+ renderTo: 'chart',
+ type: 'line'
+ },
+
+ series: data,
+ title: {
+ text: 'BETTER TITLE HERE'
+ },
+ yAxis: {
+ formatter: function () {
+ return '$' + Highcharts.numberFormat(this.y, 0);
+ }
+ },
+ subtitle: {
+ text: 'View more',
+ useHTML: true
+ },
+
+ xAxis: {
+ floor: 0,
+ type: 'datetime',
+ dateTimeLabelFormats: {
+ day: '%e %b',
+ year: '%b'
+ },
+ title: {
+ text: 'Date'
+ }
+ },
+ 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 + ': € ' + Highcharts.numberFormat(point.y, 2) + '
';
+ }
+ //console.log();
+ return str;
+ return '' + this.series.name + ' on ' + Highcharts.dateFormat("%e %B", this.x) + ':
€ ' + 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/app/assets/stylesheets/accounts.css b/app/assets/stylesheets/accounts.css
new file mode 100644
index 0000000000..87f24089da
--- /dev/null
+++ b/app/assets/stylesheets/accounts.css
@@ -0,0 +1,13 @@
+/**
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
+ * listed below.
+ *
+ * Any Css/Less files within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+ * can be referenced here using a relative path.
+ *
+ * It's not advisable to add code directly here, but if you do, it'll appear in whatever order it
+ * gets included (e.g. say you have require_tree . then the code will appear after all the directories
+ * but before any files alphabetically greater than 'application.css'
+ *
+ *= require highslide/highslide
+ */
\ No newline at end of file
diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php
index 89703b3015..e4c3714734 100644
--- a/app/controllers/AccountController.php
+++ b/app/controllers/AccountController.php
@@ -51,13 +51,11 @@ class AccountController extends \BaseController
$result = $this->_repository->destroy(Input::get('id'));
if ($result === true) {
Session::flash('success', 'The account was deleted.');
-
- return Redirect::route('accounts.index');
} else {
- Session::flash('danger', 'Could not delete the account. Check the logs to be sure.');
-
- return Redirect::route('accounts.index');
+ Session::flash('error', 'Could not delete the account. Check the logs to be sure.');
}
+ return Redirect::route('accounts.index');
+
}
@@ -93,7 +91,9 @@ class AccountController extends \BaseController
*/
public function show(Account $account)
{
- return View::make('accounts.show')->with('account', $account);
+ $show = $this->_accounts->show($account, 40);
+
+ return View::make('accounts.show')->with('account', $account)->with('show',$show);
}
/**
diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php
index c95daffa2f..2c81e339a0 100644
--- a/app/controllers/BudgetController.php
+++ b/app/controllers/BudgetController.php
@@ -1,7 +1,8 @@
_budgets = $budgets;
+ $this->_repository = $repository;
View::share('menu', 'budgets');
}
+ /**
+ * @return $this|\Illuminate\View\View
+ */
+ public function create()
+ {
+ $periods = \Config::get('firefly.periods_to_text');
+
+ return View::make('budgets.create')->with('periods', $periods);
+ }
+
+ /**
+ * @return $this|\Illuminate\View\View
+ */
+ public function indexByBudget()
+ {
+ $budgets = $this->_repository->get();
+ $today = new Carbon;
+
+ return View::make('budgets.indexByBudget')->with('budgets', $budgets)->with('today', $today);
+
+ }
+
/**
* @return $this|\Illuminate\View\View
* @throws Firefly\Exception\FireflyException
@@ -26,76 +51,12 @@ class BudgetController extends BaseController
public function indexByDate()
{
// get a list of dates by getting all repetitions:
- $budgets = $this->_budgets->get();
- $reps = [];
- foreach ($budgets as $budget) {
- foreach ($budget->limits as $limit) {
- $dateFormats = \Config::get('firefly.date_formats_by_period.' . $limit->repeat_freq);
- if (is_null($dateFormats)) {
- throw new \Firefly\Exception\FireflyException('No date formats for ' . $limit->repeat_freq);
- }
+ $set = $this->_repository->get();
+ $budgets = $this->_budgets->organizeByDate($set);
- foreach ($limit->limitrepetitions as $rep) {
- $periodOrder = $rep->startdate->format($dateFormats['group_date']);
- $period = $rep->startdate->format($dateFormats['display_date']);
- $reps[$periodOrder] = isset($reps[$periodOrder]) ? $reps[$periodOrder] : ['date' => $period];
+ return View::make('budgets.indexByDate')->with('budgets', $budgets);
- }
- }
- }
- // put all the budgets under their respective date:
- foreach ($budgets as $budget) {
- foreach ($budget->limits as $limit) {
- $dateFormats = \Config::get('firefly.date_formats_by_period.' . $limit->repeat_freq);
- foreach ($limit->limitrepetitions as $rep) {
- $month = $rep->startdate->format($dateFormats['group_date']);
- $reps[$month]['limitrepetitions'][] = $rep;
- }
- }
- }
- krsort($reps);
-
- return View::make('budgets.indexByDate')->with('reps', $reps);
-
- }
-
- /**
- * @return $this|\Illuminate\View\View
- */
- public function indexByBudget()
- {
- $budgets = $this->_budgets->get();
- $today = new \Carbon\Carbon;
- return View::make('budgets.indexByBudget')->with('budgets', $budgets)->with('today', $today);
-
- }
-
- /**
- * @return $this|\Illuminate\View\View
- */
- public function create()
- {
- $periods = \Config::get('firefly.periods_to_text');
- return View::make('budgets.create')->with('periods', $periods);
- }
-
- /**
- * @return \Illuminate\Http\RedirectResponse
- */
- public function store()
- {
-
- $data = [
- 'name' => Input::get('name'),
- 'amount' => floatval(Input::get('amount')),
- 'repeat_freq' => Input::get('period'),
- 'repeats' => intval(Input::get('repeats'))
- ];
-
- $this->_budgets->store($data);
- Session::flash('success', 'Budget created!');
- return Redirect::route('budgets.index');
}
/**
@@ -146,5 +107,24 @@ class BudgetController extends BaseController
}
+ /**
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function store()
+ {
+
+ $data = [
+ 'name' => Input::get('name'),
+ 'amount' => floatval(Input::get('amount')),
+ 'repeat_freq' => Input::get('period'),
+ 'repeats' => intval(Input::get('repeats'))
+ ];
+
+ $this->_budgets->store($data);
+ Session::flash('success', 'Budget created!');
+
+ return Redirect::route('budgets.index');
+ }
+
}
\ No newline at end of file
diff --git a/app/lib/Firefly/Helper/Controllers/Account.php b/app/lib/Firefly/Helper/Controllers/Account.php
index cc1bb527ed..bdc18aff7a 100644
--- a/app/lib/Firefly/Helper/Controllers/Account.php
+++ b/app/lib/Firefly/Helper/Controllers/Account.php
@@ -41,6 +41,7 @@ class Account implements AccountInterface
}
}
+
return $list;
}
@@ -53,6 +54,7 @@ class Account implements AccountInterface
public function openingBalanceTransaction(\Account $account)
{
$transactionType = \TransactionType::where('type', 'Opening balance')->first();
+
return \TransactionJournal::
with(
['transactions' => function ($q) {
@@ -63,4 +65,118 @@ class Account implements AccountInterface
->where('transactions.account_id', $account->id)->first(['transaction_journals.*']);
}
+
+ /**
+ * @param \Account $account
+ * @param $perPage
+ *
+ * @return mixed|void
+ */
+ public function show(\Account $account, $perPage)
+ {
+ $start = \Session::get('start');
+ $end = \Session::get('end');
+ $stats = [
+ 'budgets' => [],
+ 'categories' => [],
+ 'accounts' => []
+ ];
+ $items = [];
+
+
+ // build a query:
+ $query = \TransactionJournal::with(
+ ['transactions' => function ($q) {
+ $q->orderBy('amount', 'ASC');
+ }, 'transactiontype', 'components' => function ($q) {
+ $q->orderBy('class');
+ }, 'transactions.account.accounttype']
+ )->orderBy('date', 'DESC')->leftJoin(
+ 'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id'
+ )->where('transactions.account_id', $account->id)->where('date', '>=', $start->format('Y-m-d'))->where(
+ 'date', '<=', $end->format('Y-m-d')
+ )->orderBy('transaction_journals.id', 'DESC');
+
+
+ // build paginator:
+ $totalItems = $query->count();
+ $page = intval(\Input::get('page')) > 1 ? intval(\Input::get('page')) : 1;
+ $skip = ($page - 1) * $perPage;
+ $result = $query->skip($skip)->take($perPage)->get(['transaction_journals.*']);
+ // in the mean time, build list of categories, budgets and other accounts:
+
+ /** @var $item \TransactionJournal */
+ foreach ($result as $item) {
+ $items[] = $item;
+ foreach ($item->components as $component) {
+ if ($component->class == 'Budget') {
+ $stats['budgets'][$component->id] = $component;
+ }
+ if ($component->class == 'Category') {
+ $stats['categories'][$component->id] = $component;
+ }
+ }
+ $fromAccount = $item->transactions[0]->account;
+ $toAccount = $item->transactions[1]->account;
+ $stats['accounts'][$fromAccount->id] = $fromAccount;
+ $stats['accounts'][$toAccount->id] = $toAccount;
+ }
+ unset($result, $page);
+ $paginator = \Paginator::make($items, $totalItems, $perPage);
+
+ // statistics
+ $stats['period']['in'] = floatval(
+ \Transaction::where('account_id', $account->id)->where('amount', '>', 0)->leftJoin(
+ 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
+ )->leftJoin(
+ 'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id'
+ )->whereIn('transaction_types.type', ['Deposit', 'Withdrawal'])->where(
+ 'transaction_journals.date', '>=', $start->format('Y-m-d')
+ )->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('amount')
+ );
+
+
+ $stats['period']['out'] = floatval(
+ \Transaction::where('account_id', $account->id)->where('amount', '<', 0)->leftJoin(
+ 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
+ )->leftJoin(
+ 'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id'
+ )->whereIn('transaction_types.type', ['Deposit', 'Withdrawal'])->where(
+ 'transaction_journals.date', '>=', $start->format('Y-m-d')
+ )->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('amount')
+ );
+ $stats['period']['diff'] = $stats['period']['in'] + $stats['period']['out'];
+
+ $stats['period']['t_in'] = floatval(
+ \Transaction::where('account_id', $account->id)->where('amount', '>', 0)->leftJoin(
+ 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
+ )->leftJoin(
+ 'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id'
+ )->where('transaction_types.type', 'Transfer')->where(
+ 'transaction_journals.date', '>=', $start->format('Y-m-d')
+ )->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('amount')
+ );
+
+ $stats['period']['t_out'] = floatval(
+ \Transaction::where('account_id', $account->id)->where('amount', '<', 0)->leftJoin(
+ 'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
+ )->leftJoin(
+ 'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id'
+ )->where('transaction_types.type', 'Transfer')->where(
+ 'transaction_journals.date', '>=', $start->format('Y-m-d')
+ )->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('amount')
+ );
+
+ $stats['period']['t_diff'] = $stats['period']['t_in'] + $stats['period']['t_out'];
+
+
+ $return = [
+ 'journals' => $paginator,
+ 'statistics' => $stats
+ ];
+
+ return $return;
+
+
+ }
}
\ No newline at end of file
diff --git a/app/lib/Firefly/Helper/Controllers/AccountInterface.php b/app/lib/Firefly/Helper/Controllers/AccountInterface.php
index 02efe5baf7..793035c043 100644
--- a/app/lib/Firefly/Helper/Controllers/AccountInterface.php
+++ b/app/lib/Firefly/Helper/Controllers/AccountInterface.php
@@ -28,4 +28,12 @@ interface AccountInterface
*/
public function openingBalanceTransaction(\Account $account);
+ /**
+ * @param \Account $account
+ * @param $perPage
+ *
+ * @return mixed
+ */
+ public function show(\Account $account, $perPage);
+
}
\ No newline at end of file
diff --git a/app/lib/Firefly/Helper/Controllers/Budget.php b/app/lib/Firefly/Helper/Controllers/Budget.php
new file mode 100644
index 0000000000..9aad56d9cb
--- /dev/null
+++ b/app/lib/Firefly/Helper/Controllers/Budget.php
@@ -0,0 +1,61 @@
+limits as $limit) {
+ $dateFormats = \Config::get('firefly.date_formats_by_period.' . $limit->repeat_freq);
+ if (is_null($dateFormats)) {
+ throw new \Firefly\Exception\FireflyException('No date formats for ' . $limit->repeat_freq);
+ }
+
+ foreach ($limit->limitrepetitions as $rep) {
+ $periodOrder = $rep->startdate->format($dateFormats['group_date']);
+ $period = $rep->startdate->format($dateFormats['display_date']);
+ $return[$periodOrder] = isset($return[$periodOrder]) ? $return[$periodOrder] : ['date' => $period];
+
+ }
+ }
+ }
+ // put all the budgets under their respective date:
+ foreach ($budgets as $budget) {
+ foreach ($budget->limits as $limit) {
+ $dateFormats = \Config::get('firefly.date_formats_by_period.' . $limit->repeat_freq);
+ foreach ($limit->limitrepetitions as $rep) {
+ $rep->left = $rep->left();
+
+ $month = $rep->startdate->format($dateFormats['group_date']);
+ $return[$month]['limitrepetitions'][] = $rep;
+ }
+ }
+ }
+ krsort($return);
+ return $return;
+ }
+
+}
\ No newline at end of file
diff --git a/app/lib/Firefly/Helper/Controllers/BudgetInterface.php b/app/lib/Firefly/Helper/Controllers/BudgetInterface.php
new file mode 100644
index 0000000000..a727cf4f9b
--- /dev/null
+++ b/app/lib/Firefly/Helper/Controllers/BudgetInterface.php
@@ -0,0 +1,18 @@
+app->bind(
+ 'Firefly\Helper\Controllers\BudgetInterface',
+ 'Firefly\Helper\Controllers\Budget'
+ );
+
// mail:
$this->app->bind(
'Firefly\Helper\Email\EmailHelperInterface',
diff --git a/app/lib/Firefly/Storage/Budget/EloquentBudgetRepository.php b/app/lib/Firefly/Storage/Budget/EloquentBudgetRepository.php
index c3945e10cb..113e2adc5b 100644
--- a/app/lib/Firefly/Storage/Budget/EloquentBudgetRepository.php
+++ b/app/lib/Firefly/Storage/Budget/EloquentBudgetRepository.php
@@ -12,6 +12,40 @@ use Carbon\Carbon;
class EloquentBudgetRepository implements BudgetRepositoryInterface
{
+ /**
+ * @param $budgetId
+ *
+ * @return mixed
+ */
+ public function find($budgetId)
+ {
+
+ return \Auth::user()->budgets()->find($budgetId);
+ }
+
+ /**
+ * @return mixed
+ */
+ public function get()
+ {
+ $set = \Auth::user()->budgets()->with(
+ ['limits' => function ($q) {
+ $q->orderBy('limits.startdate', 'ASC');
+ }, 'limits.limitrepetitions' => function ($q) {
+ $q->orderBy('limit_repetitions.startdate', 'ASC');
+ }]
+ )->orderBy('name', 'ASC')->get();
+ foreach ($set as $budget) {
+ foreach ($budget->limits as $limit) {
+ foreach ($limit->limitrepetitions as $rep) {
+ $rep->left = $rep->left();
+ }
+ }
+ }
+
+ return $set;
+ }
+
/**
* @return array|mixed
*/
@@ -24,6 +58,7 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
foreach ($list as $entry) {
$return[intval($entry->id)] = $entry->name;
}
+
return $return;
}
@@ -69,6 +104,7 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
$budget->count += count($limit->limitrepetitions);
}
}
+
return $set;
}
@@ -123,30 +159,4 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
return $budget;
}
-
- /**
- * @return mixed
- */
- public function get()
- {
- return \Auth::user()->budgets()->with(
- ['limits' => function ($q) {
- $q->orderBy('limits.startdate', 'ASC');
- }, 'limits.limitrepetitions' => function ($q) {
- $q->orderBy('limit_repetitions.startdate', 'ASC');
- }]
- )->orderBy('name', 'ASC')->get();
- }
-
- /**
- * @param $budgetId
- *
- * @return mixed
- */
- public function find($budgetId)
- {
-
- return \Auth::user()->budgets()->find($budgetId);
- }
-
}
\ No newline at end of file
diff --git a/app/lib/Firefly/Storage/Limit/EloquentLimitRepository.php b/app/lib/Firefly/Storage/Limit/EloquentLimitRepository.php
index b241aef92d..96bcc3d607 100644
--- a/app/lib/Firefly/Storage/Limit/EloquentLimitRepository.php
+++ b/app/lib/Firefly/Storage/Limit/EloquentLimitRepository.php
@@ -100,7 +100,7 @@ class EloquentLimitRepository implements LimitRepositoryInterface
*/
public function getTJByBudgetAndDateRange(\Budget $budget, Carbon $start, Carbon $end)
{
- $result = $budget->transactionjournals()->after($start)->before($end)->get();
+ $result = $budget->transactionjournals()->with('transactions')->after($start)->before($end)->get();
return $result;
diff --git a/app/models/LimitRepetition.php b/app/models/LimitRepetition.php
index df8c26e6f5..010d01d5f8 100644
--- a/app/models/LimitRepetition.php
+++ b/app/models/LimitRepetition.php
@@ -37,6 +37,7 @@ class LimitRepetition extends Ardent
$start->startOfMonth();
$end = clone $start;
$end->endOfMonth();
+
return [
'limit_id' => 'factory|Limit',
'startdate' => $start,
@@ -45,11 +46,6 @@ class LimitRepetition extends Ardent
];
}
- public function limit()
- {
- return $this->belongsTo('Limit');
- }
-
public function getDates()
{
return ['created_at', 'updated_at', 'startdate', 'enddate'];
@@ -60,10 +56,6 @@ class LimitRepetition extends Ardent
*/
public function left()
{
- $key = 'limit-rep-left-' . $this->id;
- if (Cache::has($key)) {
- return Cache::get($key);
- }
$left = floatval($this->amount);
// budget:
@@ -80,11 +72,14 @@ class LimitRepetition extends Ardent
}
}
}
- Cache::forever($key, $left);
-
return $left;
}
+ public function limit()
+ {
+ return $this->belongsTo('Limit');
+ }
+
}
\ No newline at end of file
diff --git a/app/routes.php b/app/routes.php
index 6d379add58..15c5f10d2d 100644
--- a/app/routes.php
+++ b/app/routes.php
@@ -3,8 +3,23 @@
// models:
Route::bind('account', function($value, $route)
{
- return Account::where('id', $value)->where('user_id',Auth::user()->id)->first();
+ if(Auth::check()) {
+ return Account::
+ where('id', $value)->
+ where('user_id',Auth::user()->id)->first();
+ }
+ return null;
});
+Route::bind('budget', function($value, $route)
+ {
+ if(Auth::check()) {
+ return Budget::
+ where('id', $value)->
+ where('user_id',Auth::user()->id)->first();
+ }
+ return null;
+ });
+
// protected routes:
@@ -15,7 +30,7 @@ Route::group(['before' => 'auth'], function () {
Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']);
// chart controller
- Route::get('/chart/home/account/{account?}', ['uses' => 'ChartController@homeAccount', 'as' => 'chart.home']);
+ Route::get('/chart/home/account/{accountname?}', ['uses' => 'ChartController@homeAccount', 'as' => 'chart.home']);
Route::get('/chart/home/categories', ['uses' => 'ChartController@homeCategories', 'as' => 'chart.categories']);
Route::get('/chart/home/budgets', ['uses' => 'ChartController@homeBudgets', 'as' => 'chart.budgets']);
Route::get('/chart/home/info/{accountname}/{day}/{month}/{year}', ['uses' => 'ChartController@homeAccountInfo', 'as' => 'chart.info']);
@@ -42,7 +57,9 @@ Route::group(['before' => 'auth'], function () {
Route::get('/budget/create',['uses' => 'BudgetController@create', 'as' => 'budgets.create']);
Route::get('/budgets',['uses' => 'BudgetController@indexByDate','as' => 'budgets.index']);
Route::get('/budgets/budget',['uses' => 'BudgetController@indexByBudget','as' => 'budgets.index.budget']);
- Route::get('/budget/show/{id}',['uses' => 'BudgetController@show', 'as' => 'budgets.show']);
+ Route::get('/budget/show/{budget}',['uses' => 'BudgetController@show', 'as' => 'budgets.show']);
+ Route::get('/budget/edit/{budget}',['uses' => 'BudgetController@edit', 'as' => 'budgets.edit']);
+ Route::get('/budget/delete/{budget}',['uses' => 'BudgetController@delete', 'as' => 'budgets.delete']);
// limit controller:
Route::get('/budgets/limits/create/{id?}',['uses' => 'LimitController@create','as' => 'budgets.limits.create']);
diff --git a/app/tests/controllers/AccountControllerTest.php b/app/tests/controllers/AccountControllerTest.php
index 7f1bfd6a3b..8167685b4a 100644
--- a/app/tests/controllers/AccountControllerTest.php
+++ b/app/tests/controllers/AccountControllerTest.php
@@ -1,102 +1,210 @@
mock('AccountType');
- $personal->shouldReceive('getAttribute', 'description')->andReturn('Default account');
-
- $bene = $this->mock('AccountType');
- $bene->shouldReceive('getAttribute', 'description')->andReturn('Beneficiary account');
-
- $initial = $this->mock('AccountType');
- $initial->shouldReceive('getAttribute', 'description')->andReturn('Initial balance account');
-
- $cash = $this->mock('AccountType');
- $cash->shouldReceive('getAttribute', 'description')->andReturn('Cash account');
-
-
- // mock account(s)
- $one = $this->mock('Account');
- $one->shouldReceive('getAttribute')->andReturn($personal);
-
- $two = $this->mock('Account');
- $two->shouldReceive('getAttribute')->andReturn($bene);
-
- $three = $this->mock('Account');
- $three->shouldReceive('getAttribute')->andReturn($initial);
-
- $four = $this->mock('Account');
- $four->shouldReceive('getAttribute')->andReturn($cash);
- $c = new \Illuminate\Database\Eloquent\Collection([$one, $two, $three, $four]);
-
- // mock account repository:
- $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
- $accounts->shouldReceive('get')->andReturn($c);
-
-
- $list = [
- 'personal' => [$one],
- 'beneficiaries' => [$two],
- 'initial' => [$three],
- 'cash' => [$four]
- ];
-
- // mock:
- View::shouldReceive('share');
- View::shouldReceive('make')->with('accounts.index')->once()->andReturn(\Mockery::self())
- ->shouldReceive('with')->once()->with('accounts', $list)->andReturn(\Mockery::self())
- ->shouldReceive('with')->once()->with('total', 4)->andReturn(\Mockery::self());
-
-
- // call
- $this->call('GET', '/accounts');
-
- // test
- $this->assertResponseOk();
+ $this->_repository = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
+ $this->_accounts = $this->mock('Firefly\Helper\Controllers\AccountInterface');
+ $this->_user = m::mock('User','Eloquent');
+ $this->app->instance('User', $this->_user);
}
- public function testCreate()
- {
- // mock:
- View::shouldReceive('share');
- View::shouldReceive('make')->with('accounts.create');
-
- // call
- $this->call('GET', '/accounts/create');
-
- // test
- $this->assertResponseOk();
- }
-
- public function testShow()
- {
- // mock account repository:
- $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
- $accounts->shouldReceive('get')->with(1)->andReturn([]);
-
- // call
- $this->call('GET', '/accounts/1');
-
- // test
- $this->assertResponseOk();
- }
-
-
public function tearDown()
{
Mockery::close();
}
+
+ public function testCreate()
+ {
+ $this->action('GET', 'AccountController@create');
+ $this->assertResponseOk();
+
+ }
+
+ public function testDelete()
+ {
+
+ $account = f::create('Account');
+ Auth::shouldReceive('user')->andReturn($this->_user);
+ Auth::shouldReceive('check')->andReturn(true);
+ $this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id);
+ $this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn($account->email);
+
+ $this->action('GET', 'AccountController@delete',$account->id);
+ $this->assertResponseOk();
+ }
+
+ public function testDestroy()
+ {
+ $account = f::create('Account');
+ Auth::shouldReceive('user')->andReturn($this->_user);
+ $this->_repository->shouldReceive('destroy')->once()->with("")->andReturn(true);
+ $this->action('POST', 'AccountController@destroy',$account->id);
+ $this->assertRedirectedToRoute('accounts.index');
+ $this->assertSessionHas('success');
+ }
+
+ public function testDestroyFails()
+ {
+ $account = f::create('Account');
+ $this->_repository->shouldReceive('destroy')->once()->with("")->andReturn(false);
+ $this->action('POST', 'AccountController@destroy',$account->id);
+ $this->assertRedirectedToRoute('accounts.index');
+ $this->assertSessionHas('error');
+ }
+
+ public function testEdit()
+ {
+ $account = f::create('Account');
+
+ Auth::shouldReceive('user')->andReturn($this->_user);
+ Auth::shouldReceive('check')->andReturn(true);
+ $this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id);
+ $this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn($account->email);
+ $this->_accounts->shouldReceive('openingBalanceTransaction')->once()->andReturn(null);
+
+ $this->action('GET', 'AccountController@edit',$account->id);
+ $this->assertResponseOk();
+ }
+
+ public function testIndex()
+ {
+ $account = f::create('Account');
+ $collection = new Collection();
+ $collection->add($account);
+
+ $list = [
+ 'personal' => [],
+ 'beneficiaries' => [],
+ 'initial' => [],
+ 'cash' => []
+ ];
+
+ $this->_repository->shouldReceive('get')->with()->once()->andReturn($collection);
+ $this->_accounts->shouldReceive('index')->with($collection)->once()->andReturn($list);
+ $this->action('GET', 'AccountController@index');
+ $this->assertResponseOk();
+ }
+
+ public function testShow()
+ {
+ $account = f::create('Account');
+
+ Auth::shouldReceive('user')->andReturn($this->_user);
+ Auth::shouldReceive('check')->andReturn(true);
+ $this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id);
+ $this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn($account->email);
+ $this->_accounts->shouldReceive('paginate')->with($account,40)->once()->andReturn();
+
+ $this->action('GET', 'AccountController@show',$account->id);
+ $this->assertResponseOk();
+ }
+
+ public function testStore()
+ {
+// $this->action('POST', 'AccountController@store');
+// $this->assertResponseOk();
+ }
+
+
+//
+// public function testIndex()
+// {
+//// // mock account type(s):
+//// $personal = $this->mock('AccountType');
+//// $personal->shouldReceive('getAttribute', 'description')->andReturn('Default account');
+////
+//// $bene = $this->mock('AccountType');
+//// $bene->shouldReceive('getAttribute', 'description')->andReturn('Beneficiary account');
+////
+//// $initial = $this->mock('AccountType');
+//// $initial->shouldReceive('getAttribute', 'description')->andReturn('Initial balance account');
+////
+//// $cash = $this->mock('AccountType');
+//// $cash->shouldReceive('getAttribute', 'description')->andReturn('Cash account');
+////
+////
+//// // mock account(s)
+//// $one = $this->mock('Account');
+//// $one->shouldReceive('getAttribute')->andReturn($personal);
+////
+//// $two = $this->mock('Account');
+//// $two->shouldReceive('getAttribute')->andReturn($bene);
+////
+//// $three = $this->mock('Account');
+//// $three->shouldReceive('getAttribute')->andReturn($initial);
+////
+//// $four = $this->mock('Account');
+//// $four->shouldReceive('getAttribute')->andReturn($cash);
+//// $c = new \Illuminate\Database\Eloquent\Collection([$one, $two, $three, $four]);
+////
+//// // mock account repository:
+//// $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
+//// $accounts->shouldReceive('get')->andReturn($c);
+////
+////
+//// $list = [
+//// 'personal' => [$one],
+//// 'beneficiaries' => [$two],
+//// 'initial' => [$three],
+//// 'cash' => [$four]
+//// ];
+////
+//// // mock:
+//// View::shouldReceive('share');
+//// View::shouldReceive('make')->with('accounts.index')->once()->andReturn(\Mockery::self())
+//// ->shouldReceive('with')->once()->with('accounts', $list)->andReturn(\Mockery::self())
+//// ->shouldReceive('with')->once()->with('total', 4)->andReturn(\Mockery::self());
+////
+//
+// // call
+// $this->call('GET', '/accounts');
+//
+// // test
+// $this->assertResponseOk();
+//
+// }
+////
+//// public function testCreate()
+//// {
+//// // mock:
+//// View::shouldReceive('share');
+//// View::shouldReceive('make')->with('accounts.create');
+////
+//// // call
+//// $this->call('GET', '/accounts/create');
+////
+//// // test
+//// $this->assertResponseOk();
+//// }
+////
+//// public function testShow()
+//// {
+//// // mock account repository:
+//// $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
+//// $accounts->shouldReceive('get')->with(1)->andReturn([]);
+////
+//// // call
+//// $this->call('GET', '/accounts/1');
+////
+//// // test
+//// $this->assertResponseOk();
+//// }
+////
+
+ public function testUpdate()
+ {
+ }
}
\ No newline at end of file
diff --git a/app/views/accounts/index.blade.php b/app/views/accounts/index.blade.php
index 4c1bbde8ac..2b662071b1 100644
--- a/app/views/accounts/index.blade.php
+++ b/app/views/accounts/index.blade.php
@@ -47,9 +47,4 @@
-@stop
-@section('scripts')
-
-
-
@stop
\ No newline at end of file
diff --git a/app/views/accounts/show.blade.php b/app/views/accounts/show.blade.php
index 0f8a7e34c9..d81d40fb93 100644
--- a/app/views/accounts/show.blade.php
+++ b/app/views/accounts/show.blade.php
@@ -18,18 +18,96 @@
| Related accounts | ++ @foreach($show['statistics']['accounts'] as $acct) + {{{$acct->name}}} + @endforeach + | +
| Related categories | ++ @foreach($show['statistics']['categories'] as $cat) + {{{$cat->name}}} + @endforeach + | +
| Related budgets | ++ @foreach($show['statistics']['budgets'] as $bud) + {{{$bud->name}}} + @endforeach + | +
Use budgets to organize and limit your expenses.
+- These are your budgets and if set, their "limits". 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. + Budgets are groups of expenses that reappear every [period]*. Examples could be "groceries", "bills" or + "drinks with friends". The table below lists all of the budgets you have, if any. + By definition, budgets are an estimated amount + of money, ie. € 400,-. Such an estimation can change over time but should always be set. Budgets + without an actual budget are fairly pointless.
-- Group by date - Create a limit +
+ Use this page to create or change budgets and the estimated amount of money you think is wise. Pages further ahead + will explain what an "envelope" is in the context of budgeting. +
++ * Every month, week, year, etc. +
+ +Use budgets to organize and limit your expenses.
+- These are your budgets and if set, their "limits". 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. + Budgets are groups of expenses that reappear every [period]*. Examples could be "groceries", "bills" or + "drinks with friends". The table below lists all of the budgets you have, if any. + By definition, budgets are an estimated amount + of money, ie. € 400,-. Such an estimation can change over time but should always be set. Budgets + without an actual budget are fairly pointless. +
++ Use this page to create or change budgets and the estimated amount of money you think is wise. Pages further ahead + will explain what an "envelope" is in the context of budgeting. +
++ * Every month, week, year, etc.
| Budget | +Budget | Envelope | Left | ||||
|---|---|---|---|---|---|---|---|
| - {{{$rep->limit->budget->name}}} - + + | ++ + {{{$repetition->limit->budget->name}}} + | - {{mf($rep->amount,false)}} + {{mf($repetition->amount,false)}} | - @if($rep->left() < 0) + @if($repetition->left < 0) - {{mf($rep->left(),false)}} + {{mf($repetition->left,false)}} @else - {{mf($rep->left(),false)}} + {{mf($repetition->left,false)}} @endif | - @if($rep->limit->repeats == 1) + @if($repetition->limit->repeats == 1) auto repeats @endif - Add another limit | |||
| + | Date | +Description | +Amount (€) | +From | +To | ++ | |
|---|---|---|---|---|---|---|---|
| + @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 + | ++ {{$journal->date->format('d F Y')}} + | +{{{$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->transactions[0]->account->name}}} + | ++ {{{$journal->transactions[1]->account->name}}} + | ++ + | +