Slowly working my way "down" the list of controllers to fix and enhance.

This commit is contained in:
James Cole
2014-09-03 16:50:53 +02:00
parent c3fd5c7136
commit 9136b50e3c
17 changed files with 657 additions and 573 deletions

View File

@@ -6,6 +6,9 @@ use Firefly\Storage\Budget\BudgetRepositoryInterface as BRI;
/** /**
* Class BudgetController * Class BudgetController
*
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
*
*/ */
class BudgetController extends BaseController class BudgetController extends BaseController
{ {
@@ -84,7 +87,7 @@ class BudgetController extends BaseController
$budgets = $this->_repository->get(); $budgets = $this->_repository->get();
return View::make('budgets.indexByBudget')->with('budgets', $budgets)->with('today', new Carbon) return View::make('budgets.indexByBudget')->with('budgets', $budgets)->with('today', new Carbon)
->with('title', 'Budgets grouped by budget'); ->with('title', 'All your budgets grouped by budget');
} }
@@ -97,8 +100,8 @@ class BudgetController extends BaseController
$set = $this->_repository->get(); $set = $this->_repository->get();
$budgets = $this->_budgets->organizeByDate($set); $budgets = $this->_budgets->organizeByDate($set);
return View::make('budgets.indexByDate')->with('budgets', $budgets)
return View::make('budgets.indexByDate')->with('budgets', $budgets)->with('title', 'Budgets grouped by date.'); ->with('title', 'All your budgets grouped by date');
} }
@@ -111,31 +114,32 @@ class BudgetController extends BaseController
* - Show everything shows NO repetition. * - Show everything shows NO repetition.
* *
* @param Budget $budget * @param Budget $budget
* @param LimitRepetition $repetition
* *
* @return int * @return int
*/ */
public function show(Budget $budget) public function show(Budget $budget, \LimitRepetition $repetition = null)
{ {
$useSessionDates = Input::get('useSession') == 'true' ? true : false; $useSessionDates = Input::get('useSession') == 'true' ? true : false;
$view = null; $view = null;
$title = null; $title = null;
\Log::debug('Is envelope true? ' . (Input::get('noenvelope') == 'true'));
switch (true) { switch (true) {
case (!is_null(Input::get('rep'))): case (!is_null($repetition)):
$repetitionId = intval(Input::get('rep')); $data = $this->_budgets->organizeRepetition($repetition);
$data = $this->_budgets->organizeRepetition($repetitionId); $view = 1;
$view = 1; $title = $budget->name . ', ' . $repetition->periodShow() . ', ' . mf($repetition->limit->amount,
$title = $budget->name.', '. $data[0]['limitrepetition']->periodShow().', '.mf($data[0]['limit']->amount,false); false);
break; break;
case (Input::get('noenvelope') == 'true'): case (Input::get('noenvelope') == 'true'):
$data = $this->_budgets->outsideRepetitions($budget); $data = $this->_budgets->outsideRepetitions($budget);
$view = 2; $view = 2;
$title = $budget->name.', transactions outside an envelope.'; $title = $budget->name . ', transactions outside an envelope';
break; break;
default: default:
$data = $this->_budgets->organizeRepetitions($budget, $useSessionDates); $data = $this->_budgets->organizeRepetitions($budget, $useSessionDates);
$view = $useSessionDates ? 3 : 4; $view = $useSessionDates ? 3 : 4;
$title = $useSessionDates ? $budget->name.' in session period' : $budget->name; $title = $useSessionDates ? $budget->name . ' in session period' : $budget->name;
break; break;
} }

View File

@@ -13,12 +13,12 @@ class CategoryController extends BaseController
/** /**
* @param CRI $repository * @param CRI $repository
* @param CI $category * @param CI $category
*/ */
public function __construct(CRI $repository, CI $category) public function __construct(CRI $repository, CI $category)
{ {
$this->_repository = $repository; $this->_repository = $repository;
$this->_category = $category; $this->_category = $category;
} }
/** /**
@@ -26,7 +26,7 @@ class CategoryController extends BaseController
*/ */
public function create() public function create()
{ {
return View::make('categories.create'); return View::make('categories.create')->with('title', 'Create a new category');
} }
/** /**
@@ -36,7 +36,8 @@ class CategoryController extends BaseController
*/ */
public function delete(Category $category) public function delete(Category $category)
{ {
return View::make('categories.delete')->with('category', $category); return View::make('categories.delete')->with('category', $category)
->with('title', 'Delete category "' . $category->name . '"');
} }
/** /**
@@ -46,13 +47,8 @@ class CategoryController extends BaseController
*/ */
public function destroy(Category $category) public function destroy(Category $category)
{ {
$result = $this->_repository->destroy($category); $this->_repository->destroy($category);
if ($result === true) { Session::flash('success', 'The category was deleted.');
Session::flash('success', 'The category was deleted.');
} else {
Session::flash('error', 'Could not delete the category. Check the logs to be sure.');
}
return Redirect::route('categories.index'); return Redirect::route('categories.index');
} }
@@ -63,7 +59,8 @@ class CategoryController extends BaseController
*/ */
public function edit(Category $category) public function edit(Category $category)
{ {
return View::make('categories.edit')->with('category', $category); return View::make('categories.edit')->with('category', $category)
->with('title', 'Edit category "' . $category->name . '"');
} }
/** /**
@@ -73,7 +70,8 @@ class CategoryController extends BaseController
{ {
$categories = $this->_repository->get(); $categories = $this->_repository->get();
return View::make('categories.index')->with('categories', $categories); return View::make('categories.index')->with('categories', $categories)
->with('title', 'All your categories');
} }
/** /**
@@ -84,14 +82,14 @@ class CategoryController extends BaseController
public function show(Category $category) public function show(Category $category)
{ {
$start = \Session::get('start'); $start = \Session::get('start');
$end = \Session::get('end'); $end = \Session::get('end');
$journals = $this->_category->journalsInRange($category, $start, $end); $journals = $this->_category->journalsInRange($category, $start, $end);
return View::make('categories.show')->with('category', $category)->with('journals', $journals)->with( return View::make('categories.show')->with('category', $category)->with('journals', $journals)->with(
'highlight', Input::get('highlight') 'highlight', Input::get('highlight')
); )->with('title', 'Overview for category "'.$category->name.'"');;
} }
/** /**

View File

@@ -2,8 +2,6 @@
namespace Firefly\Helper\Controllers; namespace Firefly\Helper\Controllers;
use Firefly\Exception\FireflyException;
/** /**
* Class Account * Class Account
* *
@@ -11,15 +9,15 @@ use Firefly\Exception\FireflyException;
*/ */
class Account implements AccountInterface class Account implements AccountInterface
{ {
/** /**
* @param \Account $account * @param \Account $account
* * @return \TransactionJournal|null
* @return mixed
*/ */
public function openingBalanceTransaction(\Account $account) public function openingBalanceTransaction(\Account $account)
{ {
return \TransactionJournal:: return \TransactionJournal::withRelevantData()
withRelevantData()->account($account) ->account($account)
->leftJoin('transaction_types', 'transaction_types.id', '=', ->leftJoin('transaction_types', 'transaction_types.id', '=',
'transaction_journals.transaction_type_id') 'transaction_journals.transaction_type_id')
->where('transaction_types.type', 'Opening balance') ->where('transaction_types.type', 'Opening balance')
@@ -27,55 +25,54 @@ class Account implements AccountInterface
} }
/** /**
* @param \Account $account * Since it is entirely possible the database is messed up somehow it might be that a transaction
* @param $perPage * journal has only one transaction. This is mainly caused by wrong deletions and other artefacts from the past.
* *
* @return mixed|void * If it is the case, we remove $item and continue like nothing ever happened. This will however,
* mess up some statisics but we can live with that. We might be needing some cleanup routine in the future.
*
* For now, we simply warn the user of this.
*
* @param \Account $account
* @param $perPage
* @return array|mixed
* @throws \Firefly\Exception\FireflyException
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/ */
public function show(\Account $account, $perPage) public function show(\Account $account, $perPage)
{ {
$start = \Session::get('start'); $start = \Session::get('start');
$end = \Session::get('end'); $end = \Session::get('end');
$stats = [ $stats = [
'budgets' => [], 'accounts' => []
'categories' => [],
'accounts' => []
]; ];
$items = []; $items = [];
// build a query: // build a query:
$query = \TransactionJournal::withRelevantData()->defaultSorting()->account($account)->after($start) $query = \TransactionJournal::withRelevantData()
->defaultSorting()
->account($account)
->after($start)
->before($end); ->before($end);
// filter some: // filter some:
if (\Input::get('type')) { switch (\Input::get('type')) {
switch (\Input::get('type')) { case 'transactions':
case 'transactions': $query->transactionTypes(['Deposit', 'Withdrawal']);
$query->transactionTypes(['Deposit', 'Withdrawal']); break;
break; case 'transfers':
case 'transfers': $query->transactionTypes(['Transfer']);
$query->transactionTypes(['Transfer']); break;
break;
default:
throw new FireflyException('No case for type "' . \Input::get('type') . '"!');
break;
}
} }
if (\Input::get('show')) { switch (\Input::get('show')) {
switch (\Input::get('show')) { case 'expenses':
case 'expenses': case 'out':
case 'out': $query->lessThan(0);
$query->lessThan(0); break;
break; case 'income':
case 'income': case 'in':
case 'in': $query->moreThan(0);
$query->moreThan(0); break;
break;
default:
throw new FireflyException('No case for show "' . \Input::get('show') . '"!');
break;
}
} }
@@ -91,26 +88,11 @@ class Account implements AccountInterface
foreach ($result as $index => $item) { foreach ($result as $index => $item) {
foreach ($item->components as $component) { foreach ($item->components as $component) {
if ($component->class == 'Budget') { $stats[$component->class][$component->id] = $component;
$stats['budgets'][$component->id] = $component;
}
if ($component->class == 'Category') {
$stats['categories'][$component->id] = $component;
}
} }
// since it is entirely possible the database is messed up somehow
// it might be that a transaction journal has only one transaction.
// this is mainly caused by wrong deletions and other artefacts from the past.
// if it is the case, we remove $item and continue like nothing ever happened.
// this will however, mess up some statisics but we can live with that.
// we might be needing some cleanup routine in the future.
// for now, we simply warn the user of this.
if (count($item->transactions) < 2) { if (count($item->transactions) < 2) {
\Session::flash('warning', \Session::flash('warning', 'Some transactions are incomplete; they will not be shown.');
'Some transactions are incomplete; they will not be shown. Statistics may differ.');
unset($result[$index]); unset($result[$index]);
continue; continue;
} }
@@ -138,7 +120,6 @@ class Account implements AccountInterface
->transactionTypes(['Transfer'])->sum('transactions.amount')); ->transactionTypes(['Transfer'])->sum('transactions.amount'));
$trfDiff = $trfIn + $trfOut; $trfDiff = $trfIn + $trfOut;
$stats['period'] = [ $stats['period'] = [
'in' => $trIn, 'in' => $trIn,
'out' => $trOut, 'out' => $trOut,
@@ -155,7 +136,5 @@ class Account implements AccountInterface
]; ];
return $return; return $return;
} }
} }

View File

@@ -13,6 +13,11 @@ class Budget implements BudgetInterface
{ {
/** /**
* First, loop all budgets, all of their limits and all repetitions to get an overview per period
* and some basic information about that repetition's data.
*
*
*
* @param Collection $budgets * @param Collection $budgets
* *
* @return mixed|void * @return mixed|void
@@ -21,32 +26,30 @@ class Budget implements BudgetInterface
{ {
$return = []; $return = [];
/** @var \Budget $budget */
foreach ($budgets as $budget) { foreach ($budgets as $budget) {
/** @var \Limit $limit */
foreach ($budget->limits as $limit) { foreach ($budget->limits as $limit) {
/** @var \LimitRepetition $rep */ /** @var \LimitRepetition $repetition */
foreach ($limit->limitrepetitions as $rep) { foreach ($limit->limitrepetitions as $repetition) {
$periodOrder = $rep->periodOrder(); $repetition->left = $repetition->left();
$period = $rep->periodShow(); $periodOrder = $repetition->periodOrder();
$return[$periodOrder] = isset($return[$periodOrder]) $period = $repetition->periodShow();
? $return[$periodOrder] if (!isset($return[$periodOrder])) {
: ['date' => $period,
'dateObject' => $rep->startdate,
'start' => $rep->startdate,
'end' => $rep->enddate,
'budget_id' => $limit->budget_id];
} $return[$periodOrder] = [
} 'date' => $period,
} 'start' => $repetition->startdate,
// put all the budgets under their respective date: 'end' => $repetition->enddate,
foreach ($budgets as $budget) { 'budget_id' => $budget->id,
foreach ($budget->limits as $limit) { 'limitrepetitions' => [$repetition]
foreach ($limit->limitrepetitions as $rep) { ];
$rep->left = $rep->left(); } else {
$return[$periodOrder]['limitrepetitions'][] = $repetition;
}
$month = $rep->periodOrder();
$return[$month]['limitrepetitions'][] = $rep;
} }
} }
} }
@@ -56,30 +59,24 @@ class Budget implements BudgetInterface
} }
/** /**
* Get a repetition (complex because of user check)
* and then get the transactions in it.
* @param $repetitionId * @param $repetitionId
* *
* @return array * @return array
*/ */
public function organizeRepetition($repetitionId) public function organizeRepetition(\LimitRepetition $repetition)
{ {
$result = []; $result = [];
$repetition = \LimitRepetition::with('limit', 'limit.budget')->leftJoin(
'limits', 'limit_repetitions.limit_id', '=', 'limits.id'
)->leftJoin('components', 'limits.component_id', '=', 'components.id')->where(
'components.user_id', \Auth::user()->id
)
->where('limit_repetitions.id', $repetitionId)->first(['limit_repetitions.*']);
// get transactions: // get transactions:
$set = $repetition->limit->budget->transactionjournals()->with( $set = $repetition->limit->budget
'transactions', 'transactions.account', 'components', 'transactiontype' ->transactionjournals()
)->leftJoin( ->withRelevantData()
'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id' ->transactionTypes(['Withdrawal'])
)->where('transaction_types.type', 'Withdrawal')->where( ->after($repetition->startdate)
'date', '>=', $repetition->startdate->format('Y-m-d') ->before($repetition->enddate)
)->where('date', '<=', $repetition->enddate->format('Y-m-d'))->orderBy('date', 'DESC')->orderBy( ->defaultSorting()
'id', 'DESC' ->get(['transaction_journals.*']);
)->get(['transaction_journals.*']);
$result[0] = [ $result[0] = [
'date' => $repetition->periodShow(), 'date' => $repetition->periodShow(),
@@ -93,8 +90,10 @@ class Budget implements BudgetInterface
} }
/** /**
*
*
* @param \Budget $budget * @param \Budget $budget
* @param bool $useSessionDates * @param bool $useSessionDates
* *
* @return array|mixed * @return array|mixed
* @throws \Firefly\Exception\FireflyException * @throws \Firefly\Exception\FireflyException
@@ -102,15 +101,15 @@ class Budget implements BudgetInterface
public function organizeRepetitions(\Budget $budget, $useSessionDates = false) public function organizeRepetitions(\Budget $budget, $useSessionDates = false)
{ {
$sessionStart = \Session::get('start'); $sessionStart = \Session::get('start');
$sessionEnd = \Session::get('end'); $sessionEnd = \Session::get('end');
$result = []; $result = [];
$inRepetition = []; $inRepetition = [];
// get the limits: // get the limits:
if ($useSessionDates) { if ($useSessionDates) {
$limits = $budget->limits()->where('startdate', '>=', $sessionStart->format('Y-m-d'))->where( $limits = $budget->limits()->where('startdate', '>=', $sessionStart->format('Y-m-d'))->where(
'startdate', '<=', $sessionEnd->format('Y-m-d') 'startdate', '<=', $sessionEnd->format('Y-m-d')
)->get(); )->get();
} else { } else {
$limits = $budget->limits; $limits = $budget->limits;
@@ -119,7 +118,7 @@ class Budget implements BudgetInterface
/** @var \Limit $limit */ /** @var \Limit $limit */
foreach ($limits as $limit) { foreach ($limits as $limit) {
foreach ($limit->limitrepetitions as $repetition) { foreach ($limit->limitrepetitions as $repetition) {
$order = $repetition->periodOrder(); $order = $repetition->periodOrder();
$result[$order] = [ $result[$order] = [
'date' => $repetition->periodShow(), 'date' => $repetition->periodShow(),
'limitrepetition' => $repetition, 'limitrepetition' => $repetition,
@@ -127,16 +126,14 @@ class Budget implements BudgetInterface
'journals' => [], 'journals' => [],
'paginated' => false 'paginated' => false
]; ];
$transactions = []; $transactions = [];
$set = $budget->transactionjournals()->with( $set = $budget->transactionjournals()
'transactions', 'transactions.account', 'components', 'transactiontype' ->withRelevantData()
)->leftJoin( ->transactionTypes(['Withdrawal'])
'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id' ->after($repetition->startdate)
)->where('transaction_types.type', 'Withdrawal')->where( ->before($repetition->enddate)
'date', '>=', $repetition->startdate->format('Y-m-d') ->defaultSorting()
)->where('date', '<=', $repetition->enddate->format('Y-m-d'))->orderBy('date', 'DESC')->orderBy( ->get(['transaction_journals.*']);
'id', 'DESC'
)->get(['transaction_journals.*']);
foreach ($set as $entry) { foreach ($set as $entry) {
$transactions[] = $entry; $transactions[] = $entry;
$inRepetition[] = $entry->id; $inRepetition[] = $entry->id;
@@ -146,30 +143,17 @@ class Budget implements BudgetInterface
} }
if ($useSessionDates === false) { if ($useSessionDates === false) {
$query = $budget->transactionjournals()->withRelevantData()->defaultSorting();
if (count($inRepetition) > 0) { if (count($inRepetition) > 0) {
$query = $budget->transactionjournals()->with( $query->whereNotIn('transaction_journals.id', $inRepetition);
'transactions', 'transactions.account', 'components', 'transactiontype',
'transactions.account.accounttype'
)->whereNotIn(
'transaction_journals.id', $inRepetition
)->orderBy('date', 'DESC')->orderBy(
'transaction_journals.id', 'DESC'
);
} else {
$query = $budget->transactionjournals()->with(
'transactions', 'transactions.account', 'components', 'transactiontype',
'transactions.account.accounttype'
)->orderBy('date', 'DESC')->orderBy(
'transaction_journals.id', 'DESC'
);
} }
// build paginator: // build paginator:
$perPage = 25; $perPage = 25;
$totalItems = $query->count(); $totalItems = $query->count();
$page = intval(\Input::get('page')) > 1 ? intval(\Input::get('page')) : 1; $page = intval(\Input::get('page')) > 1 ? intval(\Input::get('page')) : 1;
$skip = ($page - 1) * $perPage; $skip = ($page - 1) * $perPage;
$set = $query->skip($skip)->take($perPage)->get(); $set = $query->skip($skip)->take($perPage)->get();
// stupid paginator! // stupid paginator!
$items = []; $items = [];
@@ -177,9 +161,12 @@ class Budget implements BudgetInterface
foreach ($set as $item) { foreach ($set as $item) {
$items[] = $item; $items[] = $item;
} }
$paginator = \Paginator::make($items, $totalItems, $perPage); $paginator = \Paginator::make($items, $totalItems, $perPage);
$result['0000'] = ['date' => 'Not in an envelope', 'limit' => null, 'paginated' => true, $result['0000'] = [
'journals' => $paginator]; 'date' => 'Not in an envelope',
'limit' => null,
'paginated' => true,
'journals' => $paginator];
} }
krsort($result); krsort($result);
@@ -196,13 +183,12 @@ class Budget implements BudgetInterface
$inRepetitions = []; $inRepetitions = [];
foreach ($budget->limits as $limit) { foreach ($budget->limits as $limit) {
foreach ($limit->limitrepetitions as $repetition) { foreach ($limit->limitrepetitions as $repetition) {
$set = $budget->transactionjournals()->leftJoin( $set = $budget->transactionjournals()
'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id' ->transactionTypes(['Withdrawal'])
)->where('transaction_types.type', 'Withdrawal')->where( ->after($repetition->startdate)
'date', '>=', $repetition->startdate->format('Y-m-d') ->before($repetition->enddate)
)->where('date', '<=', $repetition->enddate->format('Y-m-d'))->orderBy('date', 'DESC')->get( ->defaultSorting()
['transaction_journals.id'] ->get(['transaction_journals.id']);
);
foreach ($set as $item) { foreach ($set as $item) {
$inRepetitions[] = $item->id; $inRepetitions[] = $item->id;
} }
@@ -210,21 +196,17 @@ class Budget implements BudgetInterface
} }
$query = $budget->transactionjournals()->with( $query = $budget->transactionjournals()
'transactions', 'transactions.account', 'components', 'transactiontype', ->withRelevantData()
'transactions.account.accounttype' ->whereNotIn('transaction_journals.id', $inRepetitions)
)->whereNotIn( ->defaultSorting();
'transaction_journals.id', $inRepetitions
)->orderBy('date', 'DESC')->orderBy(
'transaction_journals.id', 'DESC'
);
// build paginator: // build paginator:
$perPage = 25; $perPage = 25;
$totalItems = $query->count(); $totalItems = $query->count();
$page = intval(\Input::get('page')) > 1 ? intval(\Input::get('page')) : 1; $page = intval(\Input::get('page')) > 1 ? intval(\Input::get('page')) : 1;
$skip = ($page - 1) * $perPage; $skip = ($page - 1) * $perPage;
$set = $query->skip($skip)->take($perPage)->get(); $set = $query->skip($skip)->take($perPage)->get();
// stupid paginator! // stupid paginator!
$items = []; $items = [];
@@ -233,8 +215,12 @@ class Budget implements BudgetInterface
$items[] = $item; $items[] = $item;
} }
$paginator = \Paginator::make($items, $totalItems, $perPage); $paginator = \Paginator::make($items, $totalItems, $perPage);
$result = [0 => ['date' => 'Not in an envelope', 'limit' => null, 'paginated' => true, $result = [0 => [
'journals' => $paginator]]; 'date' => 'Not in an envelope',
'limit' => null,
'paginated' => true,
'journals' => $paginator
]];
return $result; return $result;
} }

View File

@@ -23,7 +23,7 @@ interface BudgetInterface
* *
* @return mixed * @return mixed
*/ */
public function organizeRepetition($repetitionId); public function organizeRepetition(\LimitRepetition $repetition);
/** /**

View File

@@ -3,11 +3,15 @@
namespace Firefly\Storage\Budget; namespace Firefly\Storage\Budget;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
/** /**
* Class EloquentBudgetRepository * Class EloquentBudgetRepository
* *
* @package Firefly\Storage\Budget * @package Firefly\Storage\Budget
*
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
*
*/ */
class EloquentBudgetRepository implements BudgetRepositoryInterface class EloquentBudgetRepository implements BudgetRepositoryInterface
{ {
@@ -24,7 +28,7 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
/** /**
* @param \Budget $budget * @param \Budget $budget
* *
* @return bool|mixed * @return bool
*/ */
public function destroy(\Budget $budget) public function destroy(\Budget $budget)
{ {
@@ -36,7 +40,7 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
/** /**
* @param $budgetId * @param $budgetId
* *
* @return mixed * @return \Budget|null
*/ */
public function find($budgetId) public function find($budgetId)
{ {
@@ -44,6 +48,10 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
return $this->_user->budgets()->find($budgetId); return $this->_user->budgets()->find($budgetId);
} }
/**
* @param $budgetName
* @return \Budget|null
*/
public function findByName($budgetName) public function findByName($budgetName)
{ {
@@ -51,16 +59,16 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
} }
/** /**
* @return mixed * @return Collection
*/ */
public function get() public function get()
{ {
$set = $this->_user->budgets()->with( $set = $this->_user->budgets()->with(
['limits' => function ($q) { ['limits' => function ($q) {
$q->orderBy('limits.startdate', 'DESC'); $q->orderBy('limits.startdate', 'DESC');
}, 'limits.limitrepetitions' => function ($q) { }, 'limits.limitrepetitions' => function ($q) {
$q->orderBy('limit_repetitions.startdate', 'ASC'); $q->orderBy('limit_repetitions.startdate', 'ASC');
}] }]
)->orderBy('name', 'ASC')->get(); )->orderBy('name', 'ASC')->get();
foreach ($set as $budget) { foreach ($set as $budget) {
foreach ($budget->limits as $limit) { foreach ($budget->limits as $limit) {
@@ -74,12 +82,12 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
} }
/** /**
* @return array|mixed * @return array
*/ */
public function getAsSelectList() public function getAsSelectList()
{ {
$list = $this->_user->budgets()->with( $list = $this->_user->budgets()->with(
['limits', 'limits.limitrepetitions'] ['limits', 'limits.limitrepetitions']
)->orderBy('name', 'ASC')->get(); )->orderBy('name', 'ASC')->get();
$return = []; $return = [];
foreach ($list as $entry) { foreach ($list as $entry) {
@@ -89,11 +97,20 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
return $return; return $return;
} }
/**
* @param \User $user
* @return mixed|void
*/
public function overruleUser(\User $user)
{
$this->_user = $user;
return true;
}
/** /**
* @param $data * @param $data
* *
* @return \Budget|mixed * @return \Budget
*/ */
public function store($data) public function store($data)
{ {
@@ -104,41 +121,21 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
// if limit, create limit (repetition itself will be picked up elsewhere). // if limit, create limit (repetition itself will be picked up elsewhere).
if (isset($data['amount']) && floatval($data['amount']) > 0) { if (isset($data['amount']) && floatval($data['amount']) > 0) {
$limit = new \Limit;
$limit->budget()->associate($budget);
$startDate = new Carbon; $startDate = new Carbon;
switch ($data['repeat_freq']) { $limitData = [
case 'daily': 'budget_id' => $budget->id,
$startDate->startOfDay(); 'startdate' => $startDate->format('Y-m-d'),
break; 'period' => $data['repeat_freq'],
case 'weekly': 'amount' => floatval($data['amount']),
$startDate->startOfWeek(); 'repeats' => 0
break; ];
case 'monthly': /** @var \Firefly\Storage\Limit\LimitRepositoryInterface $limitRepository */
$startDate->startOfMonth(); $limitRepository = \App::make('Firefly\Storage\Limit\LimitRepositoryInterface');
break; $limitRepository->overruleUser($this->_user);
case 'quarterly': $limit = $limitRepository->store($limitData);
$startDate->firstOfQuarter(); \Event::fire('limits.store', [$limit]);
break;
case 'half-year':
$startDate->startOfYear();
if (intval($startDate->format('m')) >= 7) {
$startDate->addMonths(6);
}
break;
case 'yearly':
$startDate->startOfYear();
break;
}
$limit->startdate = $startDate;
$limit->amount = $data['amount'];
$limit->repeats = isset($data['repeats']) ? $data['repeats'] : 0;
$limit->repeat_freq = $data['repeat_freq'];
if ($limit->validate()) {
$limit->save();
\Event::fire('limits.store', [$limit]);
}
} }
if ($budget->validate()) { if ($budget->validate()) {
$budget->save(); $budget->save();
} }
@@ -163,14 +160,4 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
return $budget; return $budget;
} }
/**
* @param \User $user
* @return mixed|void
*/
public function overruleUser(\User $user)
{
$this->_user = $user;
return true;
}
} }

View File

@@ -33,7 +33,7 @@ class Budget extends Component
} }
/** /**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany|\TransactionJournal
*/ */
public function transactionjournals() public function transactionjournals()
{ {

View File

@@ -27,7 +27,7 @@ class Component extends SingleTableInheritanceEntity
public static $rules public static $rules
= [ = [
'user_id' => 'exists:users,id|required', 'user_id' => 'exists:users,id|required',
'name' => 'required|between:1,255', 'name' => ['required', 'between:1,100', 'alphabasic'],
'class' => 'required', 'class' => 'required',
]; ];
protected $table = 'components'; protected $table = 'components';

View File

@@ -134,7 +134,7 @@ Route::group(['before' => 'auth'], function () {
Route::get('/budgets',['uses' => 'BudgetController@indexByDate','as' => 'budgets.index']); Route::get('/budgets',['uses' => 'BudgetController@indexByDate','as' => 'budgets.index']);
Route::get('/budgets/create',['uses' => 'BudgetController@create', 'as' => 'budgets.create']); Route::get('/budgets/create',['uses' => 'BudgetController@create', 'as' => 'budgets.create']);
Route::get('/budgets/budget',['uses' => 'BudgetController@indexByBudget','as' => 'budgets.index.budget']); Route::get('/budgets/budget',['uses' => 'BudgetController@indexByBudget','as' => 'budgets.index.budget']);
Route::get('/budgets/show/{budget}',['uses' => 'BudgetController@show', 'as' => 'budgets.show']); Route::get('/budgets/show/{budget}/{limitrepetition?}',['uses' => 'BudgetController@show', 'as' => 'budgets.show']);
Route::get('/budgets/edit/{budget}',['uses' => 'BudgetController@edit', 'as' => 'budgets.edit']); 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/delete/{budget}',['uses' => 'BudgetController@delete', 'as' => 'budgets.delete']);

View File

@@ -16,7 +16,7 @@ use Mockery as m;
* *
* @SuppressWarnings(PHPMD.TooManyMethods) * @SuppressWarnings(PHPMD.TooManyMethods)
* @SuppressWarnings(PHPMD.CamelCasePropertyName) * @SuppressWarnings(PHPMD.CamelCasePropertyName)
* @coversDefaultClass \AccountController *
*/ */
class AccountTest extends TestCase class AccountTest extends TestCase
{ {
@@ -24,6 +24,9 @@ class AccountTest extends TestCase
protected $_user; protected $_user;
protected $_accounts; protected $_accounts;
/**
*
*/
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
@@ -35,12 +38,19 @@ class AccountTest extends TestCase
} }
/**
*
*/
public function tearDown() public function tearDown()
{ {
Mockery::close(); Mockery::close();
} }
/**
* @covers \Account
* @covers \AccountType
*/
public function testAccountModel() public function testAccountModel()
{ {
// create account and user: // create account and user:
@@ -74,14 +84,6 @@ class AccountTest extends TestCase
$this->assertEquals('testing', \App::environment()); $this->assertEquals('testing', \App::environment());
\Log::debug('Hello from test!');
\Log::debug('Number of accounts: ' . \Account::count());
\Log::debug('Number of account types: ' . \AccountType::count());
foreach (\AccountType::get() as $t) {
\Log::debug('AccountType: #' . $t->id . ', ' . $t->type);
}
// whatever the account type of this account, searching for it using the // whatever the account type of this account, searching for it using the
// scope method should return one account: // scope method should return one account:
$accountType = $account->accounttype()->first(); $accountType = $account->accounttype()->first();
@@ -91,7 +93,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::create * @covers \AccountController::create
*/ */
public function testCreate() public function testCreate()
{ {
@@ -106,7 +108,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::delete * @covers \AccountController::delete
*/ */
public function testDelete() public function testDelete()
{ {
@@ -136,7 +138,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::destroy * @covers \AccountController::destroy
*/ */
public function testDestroy() public function testDestroy()
{ {
@@ -165,7 +167,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::edit * @covers \AccountController::edit
*/ */
public function testEdit() public function testEdit()
{ {
@@ -197,7 +199,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::index * @covers \AccountController::index
*/ */
public function testIndex() public function testIndex()
{ {
@@ -237,7 +239,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::show * @covers \AccountController::show
*/ */
public function testShow() public function testShow()
{ {
@@ -269,7 +271,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::store * @covers \AccountController::store
*/ */
public function testStore() public function testStore()
{ {
@@ -288,7 +290,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::store * @covers \AccountController::store
*/ */
public function testStoreFails() public function testStoreFails()
{ {
@@ -308,7 +310,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::store * @covers \AccountController::store
*/ */
public function testStoreRecreate() public function testStoreRecreate()
{ {
@@ -327,7 +329,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::update * @covers \AccountController::update
*/ */
public function testUpdate() public function testUpdate()
{ {
@@ -355,7 +357,7 @@ class AccountTest extends TestCase
} }
/** /**
* @covers ::update * @covers \AccountController::update
*/ */
public function testUpdateFails() public function testUpdateFails()
{ {

410
app/tests/BudgetTest.php Normal file
View File

@@ -0,0 +1,410 @@
<?php
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use League\FactoryMuffin\Facade as f;
use Mockery as m;
/**
* Class BudgetTest
*
* @SuppressWarnings(PHPMD.TooManyMethods)
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
*/
class BudgetTest extends TestCase
{
protected $_repository;
protected $_user;
protected $_budgets;
/**
*
*/
public function setUp()
{
parent::setUp();
Artisan::call('migrate');
Artisan::call('db:seed');
$this->_repository = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface');
$this->_budgets = $this->mock('Firefly\Helper\Controllers\BudgetInterface');
$this->_user = m::mock('User', 'Eloquent');
}
/**
* @covers \Budget
*
*/
public function testBudgetModel() {
// create budget:
$budget = f::create('Budget');
// create some transaction journals:
$t1 = f::create('TransactionJournal');
$t2 = f::create('TransactionJournal');
$budget->transactionjournals()->save($t1);
$budget->transactionjournals()->save($t2);
$this->assertCount(2,$budget->transactionjournals()->get());
$this->assertEquals($budget->id,$t1->budgets()->first()->id);
}
public function tearDown()
{
Mockery::close();
}
public function testCreate()
{
// test config:
$periods = [
'weekly' => 'A week',
'monthly' => 'A month',
'quarterly' => 'A quarter',
'half-year' => 'Six months',
'yearly' => 'A year',
];
// test the view:
View::shouldReceive('make')->with('budgets.create')->once()->andReturn(m::self())
->shouldReceive('with')->with('periods', $periods)->once()->andReturn(m::self())
->shouldReceive('with')->with('title', 'Create a new budget')->once();
$this->action('GET', 'BudgetController@create');
$this->assertResponseOk();
}
public function testDelete()
{
$budget = f::create('Budget');
// test the view:
View::shouldReceive('make')->with('budgets.delete')->once()->andReturn(m::self())
->shouldReceive('with')->with('budget', m::any())->once()->andReturn(m::self())
->shouldReceive('with')->with('title', 'Delete budget "' . $budget->name . '"')->once();
// for successful binding with the budget to delete:
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
$this->action('GET', 'BudgetController@delete', $budget->id);
$this->assertResponseOk();
}
public function testDestroy()
{
$budget = f::create('Budget');
// for successful binding with the budget to delete:
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
// fire the event:
Event::shouldReceive('fire')->once()->with('budgets.destroy', [$budget]);
// fire the repository:
$this->_repository->shouldReceive('destroy')->once()->andReturn(true);
// fire and test:
$this->action('POST', 'BudgetController@destroy', $budget->id);
$this->assertRedirectedToRoute('budgets.index.budget');
$this->assertSessionHas('success');
}
public function testDestroyFromDate()
{
$budget = f::create('Budget');
// for successful binding with the budget to delete:
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
// fire the event:
Event::shouldReceive('fire')->once()->with('budgets.destroy', [$budget]);
// fire the repository:
$this->_repository->shouldReceive('destroy')->once()->andReturn(true);
// fire and test:
$this->action('POST', 'BudgetController@destroy', [$budget->id, 'from' => 'date']);
$this->assertRedirectedToRoute('budgets.index');
$this->assertSessionHas('success');
}
public function testEdit()
{
$budget = f::create('Budget');
// for successful binding with the budget to delete:
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email'); //
// test the view:
View::shouldReceive('make')->with('budgets.edit')->once()->andReturn(m::self())
->shouldReceive('with')->with('budget', m::any())->once()->andReturn(m::self())
->shouldReceive('with')->with('title', 'Edit budget "' . $budget->name . '"')->once();
$this->action('GET', 'BudgetController@edit', $budget->id);
$this->assertResponseOk();
}
public function testIndexByBudget()
{
$this->_repository->shouldReceive('get')->once()->andReturn([]);
// test the view:
View::shouldReceive('make')->with('budgets.indexByBudget')->once()->andReturn(m::self())
->shouldReceive('with')->with('budgets', [])->once()->andReturn(m::self())
->shouldReceive('with')->with('today', m::any())->once()->andReturn(m::self())
->shouldReceive('with')->with('title', 'All your budgets grouped by budget')->once();
$this->action('GET', 'BudgetController@indexByBudget');
$this->assertResponseOk();
}
public function testIndexByDate()
{
$collection = new Collection();
// test the view:
View::shouldReceive('make')->with('budgets.indexByDate')->once()->andReturn(m::self())
->shouldReceive('with')->with('budgets', [])->once()->andReturn(m::self())
->shouldReceive('with')->with('title', 'All your budgets grouped by date')->once();
$this->_repository->shouldReceive('get')->once()->andReturn($collection);
$this->_budgets->shouldReceive('organizeByDate')->with($collection)->andReturn([]);
$this->action('GET', 'BudgetController@indexByDate');
$this->assertResponseOk();
}
public function testShowDefault()
{
$budget = f::create('Budget');
// for successful binding with the budget to show:
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email'); //
// test repository:
$this->_budgets->shouldReceive('organizeRepetitions')->with(m::any(), false)->once()->andReturn([]);
// test the view:
View::shouldReceive('make')->with('budgets.show')->once()->andReturn(m::self())
->shouldReceive('with')->with('budget', m::any())->once()->andReturn(m::self())
->shouldReceive('with')->with('repetitions', [])->once()->andReturn(m::self())
->shouldReceive('with')->with('view', 4)->once()->andReturn(m::self())
->shouldReceive('with')->with('highlight', null)->once()->andReturn(m::self())
->shouldReceive('with')->with('useSessionDates', false)->once()->andReturn(m::self())
->shouldReceive('with')->with('title', $budget->name)->once();
$this->action('GET', 'BudgetController@show', $budget->id);
$this->assertResponseOk();
}
public function testShowOutsideEnvelope()
{
$budget = f::create('Budget');
// for successful binding with the budget to show:
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
$this->_user->shouldReceive('getAttribute')->with('id')->between(0, 2)->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
$this->session(['start' => new Carbon, 'end' => new Carbon]);
// test repository:
$this->_budgets->shouldReceive('outsideRepetitions')->with(m::any())->once()->andReturn([]);
// test the view:
View::shouldReceive('make')->with('budgets.show')->once()->andReturn(m::self())
->shouldReceive('with')->with('budget', m::any())->once()->andReturn(m::self())
->shouldReceive('with')->with('repetitions', [])->once()->andReturn(m::self())
->shouldReceive('with')->with('view', 2)->once()->andReturn(m::self())
->shouldReceive('with')->with('highlight', null)->once()->andReturn(m::self())
->shouldReceive('with')->with('useSessionDates', false)->once()->andReturn(m::self())
->shouldReceive('with')->with('title', $budget->name . ', transactions outside an envelope')->once();
$this->action('GET', 'BudgetController@show', [$budget->id, null, 'noenvelope' => 'true']);
$this->assertResponseOk();
}
public function testShowWithRepetition()
{
$budget = f::create('Budget');
$limit = f::create('Limit');
$repetition = f::create('LimitRepetition');
$limit->limitrepetitions()->save($repetition);
$budget->limits()->save($limit);
// for successful binding with the budget to show:
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
$this->_user->shouldReceive('getAttribute')->with('id')->between(0, 2)->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
$this->session(['start' => new Carbon, 'end' => new Carbon]);
// test repository:
$this->_budgets->shouldReceive('organizeRepetition')->with(m::any())->once()->andReturn([]);
// test the view:
View::shouldReceive('make')->with('budgets.show')->once()->andReturn(m::self())
->shouldReceive('with')->with('budget', m::any())->once()->andReturn(m::self())
->shouldReceive('with')->with('repetitions', [])->once()->andReturn(m::self())
->shouldReceive('with')->with('view', 1)->once()->andReturn(m::self())
->shouldReceive('with')->with('highlight', null)->once()->andReturn(m::self())
->shouldReceive('with')->with('useSessionDates', false)->once()->andReturn(m::self())
->shouldReceive('with')->with('title',
$budget->name . ', ' . $repetition->periodShow() . ', ' .
mf($limit->amount, false))->once();
$this->action('GET', 'BudgetController@show', [$budget->id, $repetition->id]);
$this->assertResponseOk();
}
public function testStore()
{
$budget = f::create('Budget');
// test repository:
$this->_repository->shouldReceive('store')->andReturn($budget);
// test event:
Event::shouldReceive('fire')->with('budgets.store', [$budget])->once();
$this->action('POST', 'BudgetController@store');
$this->assertRedirectedToRoute('budgets.index.budget');
$this->assertSessionHas('success');
}
public function testStoreComingFromDate()
{
$budget = f::create('Budget');
// test repository:
$this->_repository->shouldReceive('store')->andReturn($budget);
// test event:
Event::shouldReceive('fire')->with('budgets.store', [$budget])->once();
$this->action('POST', 'BudgetController@store', ['from' => 'date']);
$this->assertRedirectedToRoute('budgets.index');
$this->assertSessionHas('success');
}
public function testStoreFails()
{
$budget = f::create('Budget');
unset($budget->name);
// test repository:
$this->_repository->shouldReceive('store')->once()->andReturn($budget);
// test event:
$this->action('POST', 'BudgetController@store', ['name' => null]);
$this->assertRedirectedToRoute('budgets.create');
$this->assertSessionHas('error');
}
public function testStoreWithRecreation()
{
$budget = f::create('Budget');
// test repository:
$this->_repository->shouldReceive('store')->once()->andReturn($budget);
// test event:
Event::shouldReceive('fire')->with('budgets.store', [$budget])->once();
$this->action('POST', 'BudgetController@store', ['name' => $budget->name, 'create' => '1']);
$this->assertRedirectedTo('http://localhost/budgets/create?');
$this->assertSessionHas('success');
}
public function testUpdate()
{
$budget = f::create('Budget');
// for successful binding with the budget to update:
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
$this->_user->shouldReceive('getAttribute')->with('id')->between(0, 2)->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
// update the budget
$this->_repository->shouldReceive('update')->andReturn($budget);
// fire in the hole!
Event::shouldReceive('fire')->with('budgets.update', [$budget]);
$this->action('POST', 'BudgetController@update', $budget->id);
$this->assertRedirectedToRoute('budgets.index.budget');
$this->assertSessionHas('success');
}
public function testUpdateFails()
{
$budget = f::create('Budget');
unset($budget->name);
// for successful binding with the budget to update:
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
$this->_user->shouldReceive('getAttribute')->with('id')->between(0, 2)->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
// update the budget
$this->_repository->shouldReceive('update')->andReturn($budget);
$this->action('POST', 'BudgetController@update', [$budget->id]);
$this->assertRedirectedToRoute('budgets.edit',$budget->id);
$this->assertSessionHas('error');
}
public function testUpdateFromDate()
{
$budget = f::create('Budget');
// for successful binding with the budget to update:
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
$this->_user->shouldReceive('getAttribute')->with('id')->between(0, 2)->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
// update the budget
$this->_repository->shouldReceive('update')->andReturn($budget);
// fire in the hole!
Event::shouldReceive('fire')->with('budgets.update', [$budget]);
$this->action('POST', 'BudgetController@update', [$budget->id, 'from' => 'date']);
$this->assertRedirectedToRoute('budgets.index');
$this->assertSessionHas('success');
}
}

View File

@@ -6,12 +6,12 @@ use League\FactoryMuffin\Facade as f;
use Mockery as m; use Mockery as m;
/** /**
* Class CategoryControllerTest * Class CategoryTest
* *
* @SuppressWarnings(PHPMD.TooManyMethods) * @SuppressWarnings(PHPMD.TooManyMethods)
* @SuppressWarnings(PHPMD.CamelCasePropertyName) * @SuppressWarnings(PHPMD.CamelCasePropertyName)
*/ */
class CategoryControllerTest extends TestCase class CategoryTest extends TestCase
{ {
protected $_repository; protected $_repository;
protected $_user; protected $_user;
@@ -70,21 +70,6 @@ class CategoryControllerTest extends TestCase
$this->assertSessionHas('success'); $this->assertSessionHas('success');
} }
public function testDestroyFails()
{
$category = f::create('Category');
// for successful binding:
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($category->user_id);
$this->_repository->shouldReceive('destroy')->once()->andReturn(false);
$this->action('POST', 'CategoryController@destroy', $category->id);
$this->assertRedirectedToRoute('categories.index');
$this->assertSessionHas('error');
}
public function testEdit() public function testEdit()
{ {
$category = f::create('Category'); $category = f::create('Category');

View File

@@ -1,274 +0,0 @@
<?php
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use League\FactoryMuffin\Facade as f;
use Mockery as m;
/**
* Class BudgetControllerTest
*
* @SuppressWarnings(PHPMD.TooManyMethods)
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
*/
class BudgetControllerTest extends TestCase
{
protected $_repository;
protected $_user;
protected $_budgets;
public function setUp()
{
parent::setUp();
Artisan::call('migrate');
Artisan::call('db:seed');
$this->_repository = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface');
$this->_budgets = $this->mock('Firefly\Helper\Controllers\BudgetInterface');
$this->_user = m::mock('User', 'Eloquent');
}
public function tearDown()
{
Mockery::close();
}
public function testCreate()
{
$this->action('GET', 'BudgetController@create');
$this->assertResponseOk();
}
public function testDelete()
{
$budget = f::create('Budget');
// for successful binding:
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
$this->action('GET', 'BudgetController@delete', $budget->id);
$this->assertResponseOk();
}
public function testDestroy()
{
$budget = f::create('Budget');
// for successful binding:
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
Event::shouldReceive('fire')->once()->with('budgets.destroy', [$budget]);
$this->_repository->shouldReceive('destroy')->once()->andReturn(true);
$this->action('POST', 'BudgetController@destroy', $budget->id);
$this->assertRedirectedToRoute('budgets.index.budget');
$this->assertSessionHas('success');
}
public function testDestroyByDate()
{
$budget = f::create('Budget');
// for successful binding:
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
Event::shouldReceive('fire')->once()->with('budgets.destroy', [$budget]);
$this->_repository->shouldReceive('destroy')->once()->andReturn(true);
$this->action('POST', 'BudgetController@destroy', [$budget->id, 'from' => 'date']);
$this->assertRedirectedToRoute('budgets.index');
$this->assertSessionHas('success');
}
public function testDestroyFails()
{
$budget = f::create('Budget');
// for successful binding:
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
Event::shouldReceive('fire')->once()->with('budgets.destroy', [$budget]);
$this->_repository->shouldReceive('destroy')->once()->andReturn(false);
$this->action('POST', 'BudgetController@destroy', $budget->id);
$this->assertRedirectedToRoute('budgets.index');
$this->assertSessionHas('error');
}
public function testEdit()
{
$budget = f::create('Budget');
// for successful binding.
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
$this->action('GET', 'BudgetController@edit', $budget->id);
$this->assertResponseOk();
}
public function testIndexByBudget()
{
$this->_repository->shouldReceive('get')->once()->andReturn([]);
$this->action('GET', 'BudgetController@indexByBudget');
$this->assertResponseOk();
}
public function testIndexByDate()
{
$collection = new Collection();
$this->_repository->shouldReceive('get')->once()->andReturn($collection);
$this->_budgets->shouldReceive('organizeByDate')->with($collection)->andReturn([]);
$this->action('GET', 'BudgetController@indexByDate');
$this->assertResponseOk();
}
public function testShow()
{
$budget = f::create('Budget');
// for successful binding.
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn($budget->email);
$this->session(['start' => new Carbon, 'end' => new Carbon]);
$this->_budgets->shouldReceive('organizeRepetitions')->once()->andReturn([]);
$this->action('GET', 'BudgetController@show', $budget->id);
$this->assertResponseOk();
}
public function testShowNoEnvelope()
{
$budget = f::create('Budget');
// for successful binding.
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn($budget->email);
$this->session(['start' => new Carbon, 'end' => new Carbon]);
$this->_budgets->shouldReceive('outsideRepetitions')->once()->andReturn([]);
$this->action('GET', 'BudgetController@show', [$budget->id, 'noenvelope' => 'true']);
$this->assertResponseOk();
}
public function testShowWithRep()
{
$budget = f::create('Budget');
// for successful binding.
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn($budget->email);
$this->session(['start' => new Carbon, 'end' => new Carbon]);
// $this->_budgets->shouldReceive('show')->once()->andReturn([]);
$arr = [0 => ['limitrepetition' => null, 'limit' => null, 'date' => '']];
$this->_budgets->shouldReceive('organizeRepetition')->once()->andReturn($arr);
$this->action('GET', 'BudgetController@show', [$budget->id, 'rep' => '1']);
$this->assertResponseOk();
}
public function testStore()
{
$budget = f::create('Budget');
$this->_repository->shouldReceive('store')->andReturn($budget);
$this->action('POST', 'BudgetController@store');
$this->assertRedirectedToRoute('budgets.index.budget');
}
public function testStoreFromDate()
{
$budget = f::create('Budget');
$this->_repository->shouldReceive('store')->andReturn($budget);
$this->action('POST', 'BudgetController@store', ['from' => 'date']);
$this->assertRedirectedToRoute('budgets.index');
}
public function testStoreFails()
{
$budget = f::create('Budget');
unset($budget->name);
$this->_repository->shouldReceive('store')->andReturn($budget);
$this->action('POST', 'BudgetController@store', ['from' => 'budget']);
$this->assertRedirectedToRoute('budgets.create');
}
public function testStoreRecreate()
{
$budget = f::create('Budget');
$this->_repository->shouldReceive('store')->andReturn($budget);
$this->action('POST', 'BudgetController@store', ['from' => 'budget', 'create' => '1']);
$this->assertRedirectedToRoute('budgets.create', ['from' => 'budget']);
}
public function testUpdate()
{
$budget = f::create('Budget');
// for successful binding.
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_repository->shouldReceive('update')->andReturn($budget);
Event::shouldReceive('fire')->with('budgets.update', [$budget]);
$this->action('POST', 'BudgetController@update', $budget->id);
$this->assertRedirectedToRoute('budgets.index.budget');
}
public function testUpdateFromDate()
{
$budget = f::create('Budget');
// for successful binding.
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_repository->shouldReceive('update')->andReturn($budget);
Event::shouldReceive('fire')->with('budgets.update', [$budget]);
//$this->_user->shouldReceive('budgets')->andReturn([]); // trigger
$this->action('POST', 'BudgetController@update', [$budget->id, 'from' => 'date']);
$this->assertRedirectedToRoute('budgets.index');
}
public function testUpdateFails()
{
$budget = f::create('Budget');
unset($budget->name);
// for successful binding.
Auth::shouldReceive('user')->andReturn($this->_user);
Auth::shouldReceive('check')->andReturn(true);
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
$this->_repository->shouldReceive('update')->andReturn($budget);
$this->action('POST', 'BudgetController@update', $budget->id);
$this->assertRedirectedToRoute('budgets.edit', $budget->id);
}
}

View File

@@ -72,21 +72,21 @@
</td> </td>
</tr> </tr>
@endif @endif
@if(count($show['statistics']['categories']) > 0) @if(isset($show['statistics']['Category']) && count($show['statistics']['Category']) > 0)
<tr> <tr>
<td>Related categories</td> <td>Related categories</td>
<td> <td>
@foreach($show['statistics']['categories'] as $cat) @foreach($show['statistics']['Category'] as $cat)
<a href="{{route('categories.show',$cat->id)}}" class="btn btn-default btn-xs">{{{$cat->name}}}</a> <a href="{{route('categories.show',$cat->id)}}" class="btn btn-default btn-xs">{{{$cat->name}}}</a>
@endforeach @endforeach
</td> </td>
</tr> </tr>
@endif @endif
@if(count($show['statistics']['budgets']) > 0) @if(isset($show['statistics']['Budget']) && count($show['statistics']['Budget']) > 0)
<tr> <tr>
<td>Related budgets</td> <td>Related budgets</td>
<td> <td>
@foreach($show['statistics']['budgets'] as $bud) @foreach($show['statistics']['Budget'] as $bud)
<a href="{{route('budgets.show',$bud->id)}}?useSession=true" class="btn btn-default btn-xs">{{{$bud->name}}}</a> <a href="{{route('budgets.show',$bud->id)}}?useSession=true" class="btn btn-default btn-xs">{{{$bud->name}}}</a>
@endforeach @endforeach
</td> </td>

View File

@@ -81,7 +81,7 @@
</div> </div>
<div class="col-sm-3"> <div class="col-sm-3">
<small> <small>
<a href="{{route('budgets.show',$budget->id)}}?rep={{$rep->id}}"> <a href="{{route('budgets.show',$budget->id,$rep->id)}}">
{{$rep->periodShow()}} {{$rep->periodShow()}}
</a> </a>
</small> </small>

View File

@@ -35,7 +35,7 @@
<div class="row"> <div class="row">
<div class="col-lg-12 col-md-12 col-sm-12"> <div class="col-lg-12 col-md-12 col-sm-12">
<h3><a href="{{route('transactions.index')}}?startdate={{$entry['start']->format('Y-m-d')}}&amp;enddate={{$entry['end']->format('Y-m-d')}}">{{$entry['date']}}</a> <h3><a href="{{route('transactions.index')}}?startdate={{$entry['start']->format('Y-m-d')}}&amp;enddate={{$entry['end']->format('Y-m-d')}}">{{$entry['date']}}</a>
<a class="btn btn-default btn-xs" href ="{{route('budgets.limits.create')}}?startdate={{$entry['dateObject']->format('Y-m-d')}}"><span class="glyphicon glyphicon-plus-sign"></span> Create a new envelope for {{$entry['date']}}</a> <a class="btn btn-default btn-xs" href ="{{route('budgets.limits.create')}}?startdate={{$entry['start']->format('Y-m-d')}}"><span class="glyphicon glyphicon-plus-sign"></span> Create a new envelope for {{$entry['date']}}</a>
</h3> </h3>
<table class="table table-bordered table-striped"> <table class="table table-bordered table-striped">
<tr> <tr>
@@ -53,7 +53,7 @@
</div> </div>
</td> </td>
<td> <td>
<a href="{{route('budgets.show',$repetition->limit->budget->id)}}?rep={{$repetition->id}}"> <a href="{{route('budgets.show',$repetition->limit->budget->id,$repetition->id)}}">
{{{$repetition->limit->budget->name}}} {{{$repetition->limit->budget->name}}}
</a> </a>
</td> </td>

View File

@@ -6,8 +6,9 @@
<small>Overview for budget "{{{$budget->name}}}"</small> <small>Overview for budget "{{{$budget->name}}}"</small>
</h1> </h1>
<p class="lead">Budgets can help you cut back on spending.</p> <p class="lead">Budgets can help you cut back on spending.</p>
<!-- warning for selected limit -->
@if($view == 1) @if($view == 1)
<!-- warning for selected limit -->
<p class="bg-primary" style="padding:15px;"> <p class="bg-primary" style="padding:15px;">
This view is filtered to show only the envelope from This view is filtered to show only the envelope from
{{{$repetitions[0]['limitrepetition']->periodShow()}}}, {{{$repetitions[0]['limitrepetition']->periodShow()}}},
@@ -16,15 +17,16 @@
@endif @endif
<!-- warning for non-caught only -->
@if($view == 2) @if($view == 2)
<!-- warning for non-caught only -->
<p class="bg-primary" style="padding:15px;"> <p class="bg-primary" style="padding:15px;">
This view is filtered to show transactions not in an envelope only. This view is filtered to show transactions not in an envelope only.
</p> </p>
@endif @endif
<!-- warning for session date -->
@if($view == 3) @if($view == 3)
<!-- warning for session date -->
<p class="bg-primary" style="padding:15px;"> <p class="bg-primary" style="padding:15px;">
This view is filtered to only show transactions between {{Session::get('start')->format('d M Y')}} This view is filtered to only show transactions between {{Session::get('start')->format('d M Y')}}
and {{Session::get('end')->format('d M Y')}}. and {{Session::get('end')->format('d M Y')}}.
@@ -32,7 +34,7 @@
@endif @endif
@if($view != 4) @if($view != 4)
<p class="bg-info" style="padding:15px;"> <p class="bg-info" style="padding:15px;">
<a href="{{route('budgets.show',$budget->id)}}" class="text-info">Reset the filter(s).</a> <a class="btn btn-default btn-sm" href="{{route('budgets.show',$budget->id)}}">Reset the filter</a>
</p> </p>
@endif @endif
@@ -74,7 +76,7 @@
{{$repetition['date']}}</a> <small>paginated</small></h4> {{$repetition['date']}}</a> <small>paginated</small></h4>
@else @else
<h4> <h4>
<a href="{{route('budgets.show',$budget->id)}}?rep={{$repetition['limitrepetition']->id}}"> <a href="{{route('budgets.show',$budget->id,$repetition['limitrepetition']->id)}}">
{{$repetition['date']}} {{$repetition['date']}}
</a> </a>
</h4> </h4>
@@ -101,13 +103,18 @@
@stop @stop
@section('scripts') @section('scripts')
@if(isset($filters[0]) && is_object($filters[0]) && get_class($filters[0]) == 'Limit') @if($view == 1)
<?php echo javascript_include_tag('budgets-limit'); ?> <?php echo javascript_include_tag('budgets-limit'); ?>
@elseif(isset($filters[0]) && $filters[0] == 'no_envelope') @endif
@if($view == 2)
<?php echo javascript_include_tag('budgets-nolimit'); ?> <?php echo javascript_include_tag('budgets-nolimit'); ?>
@elseif($useSessionDates == true) @endif
@if($view == 3)
<?php echo javascript_include_tag('budgets-session'); ?> <?php echo javascript_include_tag('budgets-session'); ?>
@else @endif
@if($view == 4)
<?php echo javascript_include_tag('budgets-default'); ?> <?php echo javascript_include_tag('budgets-default'); ?>
@endif @endif