diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 034a908009..605401a120 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -66,7 +66,8 @@ class AccountController extends \BaseController public function edit(Account $account) { $openingBalance = $this->_accounts->openingBalanceTransaction($account); - return View::make('accounts.edit')->with('account', $account)->with('openingBalance', $openingBalance)->with('title','Edit account "'.$account->name.'"'); + return View::make('accounts.edit')->with('account', $account)->with('openingBalance', $openingBalance) + ->with('title', 'Edit account "' . $account->name . '"'); } /** @@ -90,7 +91,7 @@ class AccountController extends \BaseController } } - return View::make('accounts.index')->with('accounts', $set)->with('title','All your accounts'); + return View::make('accounts.index')->with('accounts', $set)->with('title', 'All your accounts'); } /** diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php index 9536b74b6f..326f388547 100644 --- a/app/controllers/BudgetController.php +++ b/app/controllers/BudgetController.php @@ -14,12 +14,12 @@ class BudgetController extends BaseController protected $_repository; /** - * @param BI $budgets + * @param BI $budgets * @param BRI $repository */ public function __construct(BI $budgets, BRI $repository) { - $this->_budgets = $budgets; + $this->_budgets = $budgets; $this->_repository = $repository; } @@ -30,7 +30,7 @@ class BudgetController extends BaseController { $periods = \Config::get('firefly.periods_to_text'); - return View::make('budgets.create')->with('periods', $periods); + return View::make('budgets.create')->with('periods', $periods)->with('title', 'Create a new budget'); } /** @@ -40,7 +40,8 @@ class BudgetController extends BaseController */ public function delete(Budget $budget) { - return View::make('budgets.delete')->with('budget', $budget); + return View::make('budgets.delete')->with('budget', $budget) + ->with('title', 'Delete budget "' . $budget->name . '"'); } /** @@ -50,20 +51,16 @@ class BudgetController extends BaseController */ public function destroy(Budget $budget) { + // remove budget Event::fire('budgets.destroy', [$budget]); // just before deletion. - $result = $this->_repository->destroy($budget); - if ($result === true) { - Session::flash('success', 'The budget was deleted.'); - if (Input::get('from') == 'date') { - return Redirect::route('budgets.index'); - } else { - return Redirect::route('budgets.index.budget'); - } - } else { - Session::flash('error', 'Could not delete the budget. Check the logs to be sure.'); - } + $this->_repository->destroy($budget); + Session::flash('success', 'The budget was deleted.'); - return Redirect::route('budgets.index'); + // redirect: + if (Input::get('from') == 'date') { + return Redirect::route('budgets.index'); + } + return Redirect::route('budgets.index.budget'); } @@ -74,7 +71,8 @@ class BudgetController extends BaseController */ public function edit(Budget $budget) { - return View::make('budgets.edit')->with('budget', $budget); + return View::make('budgets.edit')->with('budget', $budget) + ->with('title', 'Edit budget "' . $budget->name . '"'); } @@ -84,62 +82,70 @@ class BudgetController extends BaseController public function indexByBudget() { $budgets = $this->_repository->get(); - $today = new Carbon; - - return View::make('budgets.indexByBudget')->with('budgets', $budgets)->with('today', $today); + return View::make('budgets.indexByBudget')->with('budgets', $budgets)->with('today', new Carbon) + ->with('title', 'Budgets grouped by budget'); } /** - * @return $this|\Illuminate\View\View - * @throws Firefly\Exception\FireflyException + * @return $this */ public function indexByDate() { // get a list of dates by getting all repetitions: - $set = $this->_repository->get(); + $set = $this->_repository->get(); $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.'); } /** + * Three use cases for this view: + * + * - Show everything. + * - Show a specific repetition. + * - Show everything shows NO repetition. + * * @param Budget $budget * * @return int */ public function show(Budget $budget) { - /** - * Use the - */ $useSessionDates = Input::get('useSession') == 'true' ? true : false; + $view = null; + $title = null; - - $filters = []; - - if (!is_null(Input::get('rep'))) { - $repetitionId = intval(Input::get('rep')); - $repetitions = $this->_budgets->organizeRepetition($repetitionId); - $filters[] = $repetitions[0]['limit']; - $filters[] = $repetitions[0]['limitrepetition']; - } else { - if (Input::get('noenvelope') == 'true') { - $repetitions = $this->_budgets->outsideRepetitions($budget); - $filters[] = 'no_envelope'; - } else { - // grab all limit repetitions, order them, show them: - $repetitions = $this->_budgets->organizeRepetitions($budget, $useSessionDates); - } + switch (true) { + case (!is_null(Input::get('rep'))): + $repetitionId = intval(Input::get('rep')); + $data = $this->_budgets->organizeRepetition($repetitionId); + $view = 1; + $title = $budget->name.', '. $data[0]['limitrepetition']->periodShow().', '.mf($data[0]['limit']->amount,false); + break; + case (Input::get('noenvelope') == 'true'): + $data = $this->_budgets->outsideRepetitions($budget); + $view = 2; + $title = $budget->name.', transactions outside an envelope.'; + break; + default: + $data = $this->_budgets->organizeRepetitions($budget, $useSessionDates); + $view = $useSessionDates ? 3 : 4; + $title = $useSessionDates ? $budget->name.' in session period' : $budget->name; + break; } - return View::make('budgets.show')->with('budget', $budget)->with('repetitions', $repetitions)->with( - 'filters', $filters - )->with('highlight', Input::get('highlight'))->with('useSessionDates', $useSessionDates); + return View::make('budgets.show') + ->with('budget', $budget) + ->with('repetitions', $data) + ->with('view', $view) + ->with('highlight', Input::get('highlight')) + ->with('useSessionDates', $useSessionDates) + ->with('title', $title); } /** diff --git a/app/lib/Firefly/Queue/Import.php b/app/lib/Firefly/Queue/Import.php index f7b20816d9..5fefd59972 100644 --- a/app/lib/Firefly/Queue/Import.php +++ b/app/lib/Firefly/Queue/Import.php @@ -52,6 +52,30 @@ class Import } + /** + * @param Job $job + * @param array $payload + */ + public function cleanImportAccount(Job $job, array $payload) + { + $importAccountType = $this->_accounts->findAccountType('Import account'); + $importAccounts = $this->_accounts->getByAccountType($importAccountType); + if (count($importAccounts) == 0) { + $job->delete(); + } else if (count($importAccounts) == 1) { + /** @var \Account $importAccount */ + $importAccount = $importAccounts[0]; + $transactions = $importAccount->transactions()->get(); + /** @var \Transaction $transaction */ + foreach ($transactions as $transaction) { + $transaction->account()->associate($importAccount); + $transaction->save(); + } + \Log::debug('Updated ' . count($transactions) . ' transactions from Import Account to cash.'); + } + $job->delete(); + } + /** * @param Job $job * @param array $payload @@ -611,8 +635,13 @@ class Import \Queue::push($jobFunction, ['data' => $entry, 'mapID' => $importMap->id]); } + // queue a job to clean up the "import account", it should properly fall back + // to the cash account (which it doesn't always do for some reason). + \Queue::push('Firefly\Queue\Import@cleanImportAccount', ['mapID' => $importMap->id]); } + + \Log::debug('Done with job "start"'); // this is it, close the job: $job->delete(); diff --git a/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php b/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php index 11757184b6..296e0bd613 100644 --- a/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php +++ b/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php @@ -101,6 +101,12 @@ interface AccountRepositoryInterface */ public function getDefault(); + /** + * @param \AccountType $type + * @return mixed + */ + public function getByAccountType(\AccountType $type); + /** * @param \User $user * @return mixed diff --git a/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php b/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php index 209e71f48e..f6d4fed6d4 100644 --- a/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php +++ b/app/lib/Firefly/Storage/Account/EloquentAccountRepository.php @@ -209,6 +209,12 @@ class EloquentAccountRepository implements AccountRepositoryInterface return $list; } + public function getByAccountType(\AccountType $type) + { + return $this->_user->accounts()->with('accounttype')->orderBy('name', 'ASC') + ->where('account_type_id', $type->id)->get(); + } + /** * @param $ids * diff --git a/app/tests/controllers/AccountTest.php b/app/tests/AccountTest.php similarity index 95% rename from app/tests/controllers/AccountTest.php rename to app/tests/AccountTest.php index c58213581f..c7f33f66bd 100644 --- a/app/tests/controllers/AccountTest.php +++ b/app/tests/AccountTest.php @@ -8,7 +8,11 @@ use Mockery as m; /** * Class AccountTest * - * Test EVERYTHING related to accounts. Models, views controllers. + * Test EVERYTHING related to accounts. Models, views, and controllers. + * + * This class does not cover the /lib/ map, it is for a later date. + * + * As far as I am concerned, this class is complete! Yay! * * @SuppressWarnings(PHPMD.TooManyMethods) * @SuppressWarnings(PHPMD.CamelCasePropertyName) @@ -68,20 +72,20 @@ class AccountTest extends TestCase // user should equal test user: $this->assertEquals($user->id, $account->user()->first()->id); - $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); + foreach (\AccountType::get() as $t) { + \Log::debug('AccountType: #' . $t->id . ', ' . $t->type); } // whatever the account type of this account, searching for it using the // scope method should return one account: $accountType = $account->accounttype()->first(); - $accounts = $accountType->accounts()->count(); + $accounts = $accountType->accounts()->count(); $this->assertCount($accounts, \Account::AccountTypeIn([$accountType->type])->get()); } @@ -199,7 +203,7 @@ class AccountTest extends TestCase { // two account types: $personalType = \AccountType::whereType('Default account')->first(); - $benType = \AccountType::whereType('Beneficiary account')->first(); + $benType = \AccountType::whereType('Beneficiary account')->first(); // create two accounts: /** @var \Account $account */ @@ -303,6 +307,9 @@ class AccountTest extends TestCase $this->assertSessionHas('error'); } + /** + * @covers ::store + */ public function testStoreRecreate() { /** @var \Account $account */ @@ -319,6 +326,9 @@ class AccountTest extends TestCase $this->assertSessionHas('success'); } + /** + * @covers ::update + */ public function testUpdate() { /** @var \Account $account */ @@ -344,6 +354,9 @@ class AccountTest extends TestCase } + /** + * @covers ::update + */ public function testUpdateFails() { /** @var \Account $account */ diff --git a/app/views/budgets/show.blade.php b/app/views/budgets/show.blade.php index d9a6f05661..6ae14f8c53 100644 --- a/app/views/budgets/show.blade.php +++ b/app/views/budgets/show.blade.php @@ -7,38 +7,34 @@

Budgets can help you cut back on spending.

- @if(isset($filters[0]) && is_object($filters[0]) && get_class($filters[0]) == 'Limit') + @if($view == 1)

This view is filtered to show only the envelope from {{{$repetitions[0]['limitrepetition']->periodShow()}}}, which contains {{mf($repetitions[0]['limit']->amount,false)}}.

-

- Reset the filter(s). -

+ @endif - @if(isset($filters[0]) && $filters[0] == 'no_envelope') + @if($view == 2)

This view is filtered to show transactions not in an envelope only.

-

- Reset the filter(s). -

@endif - - @if($useSessionDates == true) + + @if($view == 3)

This view is filtered to only show transactions between {{Session::get('start')->format('d M Y')}} and {{Session::get('end')->format('d M Y')}}.

- -

- Reset the filter(s). -

@endif + @if($view != 4) +

+ Reset the filter(s). +

+ @endif @@ -46,17 +42,22 @@
- @if(isset($filters[0]) && is_object($filters[0]) && get_class($filters[0]) == 'Limit') + @if($view == 1)
- @elseif(isset($filters[0]) && $filters[0] == 'no_envelope') -
- @elseif($useSessionDates == true) -
- @else -
@endif + @if($view == 2) +
+ @endif + + @if($view == 3) +
+ @endif + + @if($view == 4) +
+ @endif
diff --git a/public/fonts/glyphicons-halflings-regular.eot b/public/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000..4a4ca865d6 Binary files /dev/null and b/public/fonts/glyphicons-halflings-regular.eot differ diff --git a/public/fonts/glyphicons-halflings-regular.svg b/public/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 0000000000..e3e2dc739d --- /dev/null +++ b/public/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/fonts/glyphicons-halflings-regular.ttf b/public/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000..67fa00bf83 Binary files /dev/null and b/public/fonts/glyphicons-halflings-regular.ttf differ diff --git a/public/fonts/glyphicons-halflings-regular.woff b/public/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000000..8c54182aa5 Binary files /dev/null and b/public/fonts/glyphicons-halflings-regular.woff differ