From 9ecc8ab547398653c6a6844e35812dd2d8da2462 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 22 Aug 2014 07:44:51 +0200 Subject: [PATCH] Small functional changes to all Account related methods and views. --- app/controllers/AccountController.php | 27 +- .../Account/EloquentAccountRepository.php | 38 ++- .../controllers/AccountControllerTest.php | 261 ++++++++++++++++-- app/views/accounts/index.blade.php | 18 +- app/views/accounts/show.blade.php | 10 +- app/views/lists/transactions.blade.php | 2 + 6 files changed, 308 insertions(+), 48 deletions(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index fda3861eb9..5d04d4693d 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -14,7 +14,7 @@ class AccountController extends \BaseController /** * @param ARI $repository - * @param AI $accounts + * @param AI $accounts */ public function __construct(ARI $repository, AI $accounts) { @@ -37,6 +37,12 @@ class AccountController extends \BaseController */ public function delete(Account $account) { + $accountType = $account->accountType()->first(); + + if ($accountType->description == 'Initial balance account' || $accountType->description == 'Cash account') { + return \View::make('error')->with('message', 'Cannot edit this account type (' . $accountType->description . ').'); + } + return View::make('accounts.delete')->with('account', $account); } @@ -47,6 +53,11 @@ class AccountController extends \BaseController */ public function destroy(Account $account) { + $accountType = $account->accountType()->first(); + + if ($accountType->description == 'Initial balance account' || $accountType->description == 'Cash account') { + return View::make('error')->with('message', 'Cannot edit this account type (' . $accountType->description . ').'); + } $result = $this->_repository->destroy($account); if ($result === true) { Session::flash('success', 'The account was deleted.'); @@ -65,6 +76,11 @@ class AccountController extends \BaseController */ public function edit(Account $account) { + $accountType = $account->accountType()->first(); + + if ($accountType->description == 'Initial balance account' || $accountType->description == 'Cash account') { + return View::make('error')->with('message', 'Cannot edit this account type (' . $accountType->description . ').'); + } $openingBalance = $this->_accounts->openingBalanceTransaction($account); return View::make('accounts.edit')->with('account', $account)->with('openingBalance', $openingBalance); @@ -88,6 +104,11 @@ class AccountController extends \BaseController */ public function show(Account $account) { + $accountType = $account->accountType()->first(); + if ($accountType->description == 'Initial balance account' || $accountType->description == 'Cash account') { + return View::make('error')->with('message', 'Cannot show this account type (' . $accountType->description . ').'); + } + $show = $this->_accounts->show($account, 40); return View::make('accounts.show')->with('account', $account)->with('show', $show); @@ -125,6 +146,10 @@ class AccountController extends \BaseController */ public function update(Account $account) { + $accountType = $account->accountType()->first(); + if ($accountType->description == 'Initial balance account' || $accountType->description == 'Cash account') { + return View::make('error')->with('message', 'Cannot show this account type (' . $accountType->description . ').'); + } $account = $this->_repository->update($account, Input::all()); if ($account->validate()) { Session::flash('success', 'Account "' . $account->name . '" updated.'); diff --git a/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php b/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php index 0b89f567dc..3fe48d154c 100644 --- a/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php +++ b/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php @@ -40,7 +40,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface $account = $this->findByName($name, $type); if (!$account) { $data = [ - 'name' => $name, + 'name' => $name, 'account_type' => $type ]; @@ -74,6 +74,38 @@ class EloquentAccountRepository implements AccountRepositoryInterface */ public function destroy(\Account $account) { + // find the oldest transaction which also is a "Opening balance" + $first = \Transaction:: + leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') + ->where('transaction_journals.user_id', \Auth::user()->id) + ->where('transaction_types.type', 'Opening balance') + ->where('account_id', '!=', $account->id) + ->orderBy('transactions.id', 'DESC')->first(['transactions.*']); + + $initialbalanceAccount = null; + if (!is_null($first)) { + $initialbalanceAccount = $first->account()->first(); + } + + + // loop the account, find all transaction journals, and delete them: + $transactions = $account->transactions()->with('transactionjournal')->get(); + $journals = []; + /** @var \Transaction $transaction */ + foreach ($transactions as $transaction) { + $journals[$transaction->transaction_journal_id] = $transaction->transactionJournal; + } + /** @var \TransactionJournal $journal */ + foreach ($journals as $journal) { + $journal->delete(); + } + + if(!is_null($initialbalanceAccount)) { + $initialbalanceAccount->delete(); + } + + $account->delete(); /** @@ -274,8 +306,8 @@ class EloquentAccountRepository implements AccountRepositoryInterface /** * @param \Account $account - * @param int $amount - * @param Carbon $date + * @param int $amount + * @param Carbon $date * * @return bool * @SuppressWarnings(PHPMD.CamelCaseMethodName) diff --git a/app/tests/controllers/AccountControllerTest.php b/app/tests/controllers/AccountControllerTest.php index 3bc06d7da5..bbb9c34a0c 100644 --- a/app/tests/controllers/AccountControllerTest.php +++ b/app/tests/controllers/AccountControllerTest.php @@ -2,8 +2,8 @@ use Carbon\Carbon; use Illuminate\Database\Eloquent\Collection; -use Mockery as m; use League\FactoryMuffin\Facade as f; +use Mockery as m; /** * Class AccountControllerTest @@ -21,9 +21,6 @@ class AccountControllerTest extends TestCase public function setUp() { parent::setUp(); - - - Artisan::call('migrate'); Artisan::call('db:seed'); $this->_repository = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface'); @@ -55,21 +52,50 @@ class AccountControllerTest extends TestCase */ public function testDelete() { - + /** @var \Account $account */ $account = f::create('Account'); + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + // for successful binding: 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')->andReturn('some@email'); - // view - View::shouldReceive('make')->once()->with('accounts.delete')->andReturn(m::self())->shouldReceive('with')->with( - 'account', m::any() - ); + $this->action('GET', 'AccountController@delete', $account->id); + $this->assertViewHas('account'); + $this->assertResponseOk(); + } + + /** + * @covers ::delete + */ + public function testDeleteWrongType() + { + /** @var \Account $account */ + $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Initial balance account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + + // for successful binding: + 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')->andReturn('some@email'); $this->action('GET', 'AccountController@delete', $account->id); + $this->assertViewHas('message'); $this->assertResponseOk(); } @@ -78,8 +104,17 @@ class AccountControllerTest extends TestCase */ public function testDestroy() { + /** @var \Account $account */ $account = f::create('Account'); + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + + // for successful binding: Auth::shouldReceive('user')->once()->andReturn($this->_user); Auth::shouldReceive('check')->once()->andReturn(true); @@ -91,13 +126,47 @@ class AccountControllerTest extends TestCase $this->assertSessionHas('success'); } + /** + * @covers ::destroy + */ + public function testDestroyWrongType() + { + /** @var \Account $account */ + $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Initial balance account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + + + // for successful binding: + Auth::shouldReceive('user')->once()->andReturn($this->_user); + Auth::shouldReceive('check')->once()->andReturn(true); + $this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id); + + $this->action('POST', 'AccountController@destroy', $account->id); + $this->assertViewHas('message'); + $this->assertResponseOk(); + } + /** * @covers ::destroy */ public function testDestroyFails() { + /** @var \Account $account */ $account = f::create('Account'); + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + // for successful binding: Auth::shouldReceive('user')->once()->andReturn($this->_user); Auth::shouldReceive('check')->once()->andReturn(true); @@ -111,8 +180,16 @@ class AccountControllerTest extends TestCase public function testEdit() { + /** @var \Account $account */ $account = f::create('Account'); + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + // for successful binding. Auth::shouldReceive('user')->andReturn($this->_user); Auth::shouldReceive('check')->andReturn(true); @@ -130,23 +207,50 @@ class AccountControllerTest extends TestCase $this->assertResponseOk(); } + + public function testEditWrongType() + { + /** @var \Account $account */ + $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Initial balance account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + + // for successful binding. + 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')->andReturn('some@email'); + + $this->action('GET', 'AccountController@edit', $account->id); + $this->assertViewHas('message'); + $this->assertResponseOk(); + } + public function testIndex() { + /** @var \Account $account */ $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + $collection = new Collection(); $collection->add($account); - // create some fake accounts: - $personal = f::create('Account'); - $bene = f::create('Account'); - $init = f::create('Account'); - $cash = f::create('Account'); - $list = [ - 'personal' => [$personal], - 'beneficiaries' => [$bene], - 'initial' => [$init], - 'cash' => [$cash] + 'personal' => [], + 'beneficiaries' => [], + 'initial' => [], + 'cash' => [] ]; $this->_repository->shouldReceive('get')->once()->andReturn($collection); @@ -157,8 +261,16 @@ class AccountControllerTest extends TestCase public function testShow() { + /** @var \Account $account */ $account = f::create('Account'); + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + // for successful binding. Auth::shouldReceive('user')->andReturn($this->_user); Auth::shouldReceive('check')->andReturn(true); @@ -171,19 +283,19 @@ class AccountControllerTest extends TestCase $data = [ 'statistics' => [ - 'period' => [ - 'in' => 0, - 'out' => 0, - 'diff' => 0, - 't_in' => 0, - 't_out' => 0, + 'period' => [ + 'in' => 0, + 'out' => 0, + 'diff' => 0, + 't_in' => 0, + 't_out' => 0, 't_diff' => 0 ], 'categories' => [], - 'budgets' => [], - 'accounts' => [] + 'budgets' => [], + 'accounts' => [] ], - 'journals' => $paginator, + 'journals' => $paginator, ]; $this->_accounts->shouldReceive('show')->once()->andReturn($data); @@ -191,9 +303,42 @@ class AccountControllerTest extends TestCase $this->assertResponseOk(); } + public function testShowWrongType() + { + /** @var \Account $account */ + $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Initial balance account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + + // for successful binding. + 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')->andReturn($account->email); + + + $this->action('GET', 'AccountController@show', $account->id); + $this->assertViewHas('message'); + $this->assertResponseOk(); + } + public function testStore() { + /** @var \Account $account */ $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + $this->_repository->shouldReceive('store')->andReturn($account); $this->action('POST', 'AccountController@store'); $this->assertRedirectedToRoute('accounts.index'); @@ -201,7 +346,16 @@ class AccountControllerTest extends TestCase public function testStoreFails() { + /** @var \Account $account */ $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + unset($account->name); $this->_repository->shouldReceive('store')->andReturn($account); $this->action('POST', 'AccountController@store'); @@ -210,7 +364,16 @@ class AccountControllerTest extends TestCase public function testStoreRecreate() { + /** @var \Account $account */ $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + $this->_repository->shouldReceive('store')->andReturn($account); $this->action('POST', 'AccountController@store', ['create' => '1']); $this->assertRedirectedToRoute('accounts.create'); @@ -218,7 +381,16 @@ class AccountControllerTest extends TestCase public function testUpdate() { + /** @var \Account $account */ $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + // for successful binding. Auth::shouldReceive('user')->andReturn($this->_user); Auth::shouldReceive('check')->andReturn(true); @@ -230,9 +402,42 @@ class AccountControllerTest extends TestCase } + public function testUpdateWrongType() + { + /** @var \Account $account */ + $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Initial balance account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + + // for successful binding. + Auth::shouldReceive('user')->andReturn($this->_user); + Auth::shouldReceive('check')->andReturn(true); + $this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id); + $this->_repository->shouldReceive('update')->andReturn($account); + + $this->action('POST', 'AccountController@update', $account->id); + $this->assertViewHas('message'); + $this->assertResponseOk(); + + } + public function testUpdateFails() { + /** @var \Account $account */ $account = f::create('Account'); + + /** @var \AccountType $accountType */ + $accountType = f::create('AccountType'); + $accountType->description = 'Default account'; + $accountType->save(); + $account->accountType()->associate($accountType); + $account->save(); + unset($account->name); // for successful binding. Auth::shouldReceive('user')->andReturn($this->_user); diff --git a/app/views/accounts/index.blade.php b/app/views/accounts/index.blade.php index bea833be0b..545d3f6fc6 100644 --- a/app/views/accounts/index.blade.php +++ b/app/views/accounts/index.blade.php @@ -20,33 +20,23 @@
+ @if(count($accounts['personal']) > 0)

Your accounts

These are your personal accounts.

@include('accounts.list',['accounts' => $accounts['personal']]) + @endif + @if(count($accounts['beneficiaries']) > 0)

Beneficiaries

These are beneficiaries; places where you spend money or people who pay you.

- @include('accounts.list',['accounts' => $accounts['beneficiaries']]) + @endif -

Initial balances

-

- These are system accounts; created to add balance to the books when you add a personal account - which already has money in it. That money has to come from somewhere. -

- @include('accounts.list',['accounts' => $accounts['initial']]) - -

Cash

-

- This is a system account. When you don't specify a beneficiary or draw many from an ATM (or put cash in your - personal accounts) it gets added or drawn from this account. -

- @include('accounts.list',['accounts' => $accounts['cash']])
diff --git a/app/views/accounts/show.blade.php b/app/views/accounts/show.blade.php index b1408b5e9b..646724a9af 100644 --- a/app/views/accounts/show.blade.php +++ b/app/views/accounts/show.blade.php @@ -62,6 +62,7 @@
+ @if(count($show['statistics']['accounts']) > 0) + @endif + @if(count($show['statistics']['categories']) > 0) + @endif + @if(count($show['statistics']['budgets']) > 0) + @endif
Related accounts @@ -70,22 +71,27 @@ @endforeach
Related categories @foreach($show['statistics']['categories'] as $cat) - {{{$cat->name}}} + {{{$cat->name}}} @endforeach
Related budgets @foreach($show['statistics']['budgets'] as $bud) - {{{$bud->name}}} + {{{$bud->name}}} @endforeach
diff --git a/app/views/lists/transactions.blade.php b/app/views/lists/transactions.blade.php index c09b7d4b54..838b05d163 100644 --- a/app/views/lists/transactions.blade.php +++ b/app/views/lists/transactions.blade.php @@ -63,6 +63,7 @@ {{{$journal->transactions[1]->account->name}}} + @if($journal->transactiontype->type != 'Opening balance')
@@ -70,6 +71,7 @@
+ @endif @endforeach