mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	Create deposits, transfers and withdrawals. Also tests!
This commit is contained in:
		| @@ -35,16 +35,46 @@ class TransactionController extends BaseController | ||||
|  | ||||
|         $budgets[0] = '(no budget)'; | ||||
|  | ||||
|  | ||||
|         return View::make('transactions.withdrawal')->with('accounts', $accounts)->with('budgets', $budgets); | ||||
|     } | ||||
|  | ||||
|     public function createDeposit() | ||||
|     { | ||||
|         // get accounts with names and id's. | ||||
|         $accounts = $this->accounts->getActiveDefaultAsSelectList(); | ||||
|  | ||||
|         $budgets = $this->budgets->getAsSelectList(); | ||||
|  | ||||
|         $budgets[0] = '(no budget)'; | ||||
|  | ||||
|         return View::make('transactions.deposit')->with('accounts', $accounts)->with('budgets', $budgets); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function createTransfer() | ||||
|     { | ||||
|         // get accounts with names and id's. | ||||
|         $accounts = $this->accounts->getActiveDefaultAsSelectList(); | ||||
|  | ||||
|         $budgets = $this->budgets->getAsSelectList(); | ||||
|  | ||||
|         $budgets[0] = '(no budget)'; | ||||
|  | ||||
|         return View::make('transactions.transfer')->with('accounts', $accounts)->with('budgets', $budgets); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     public function postCreateWithdrawal() | ||||
|     { | ||||
|  | ||||
|         // create or find beneficiary: | ||||
|         $beneficiary = $this->accounts->createOrFindBeneficiary(Input::get('beneficiary')); | ||||
|  | ||||
|         // fall back to cash account if empty: | ||||
|         if (is_null($beneficiary)) { | ||||
|             $beneficiary = $this->accounts->getCashAccount(); | ||||
|         } | ||||
|  | ||||
|         // create or find category: | ||||
|         $category = $this->categories->createOrFind(Input::get('category')); | ||||
|  | ||||
| @@ -61,7 +91,11 @@ class TransactionController extends BaseController | ||||
|  | ||||
|         // create journal | ||||
|         /** @var \TransactionJournal $journal */ | ||||
|         $journal = $this->tj->createSimpleJournal($account, $beneficiary, $description, $amount, $date); | ||||
|         try { | ||||
|             $journal = $this->tj->createSimpleJournal($account, $beneficiary, $description, $amount, $date); | ||||
|         } catch (\Firefly\Exception\FireflyException $e) { | ||||
|             return Redirect::route('transactions.withdrawal')->withInput(); | ||||
|         } | ||||
|  | ||||
|         // attach bud/cat (?) | ||||
|         if (!is_null($budget)) { | ||||
| @@ -75,4 +109,72 @@ class TransactionController extends BaseController | ||||
|         return Redirect::route('index'); | ||||
|     } | ||||
|  | ||||
|     public function postCreateDeposit() | ||||
|     { | ||||
|         // create or find beneficiary: | ||||
|         $beneficiary = $this->accounts->createOrFindBeneficiary(Input::get('beneficiary')); | ||||
|  | ||||
|         // fall back to cash account if empty: | ||||
|         if (is_null($beneficiary)) { | ||||
|             $beneficiary = $this->accounts->getCashAccount(); | ||||
|         } | ||||
|  | ||||
|         // create or find category: | ||||
|         $category = $this->categories->createOrFind(Input::get('category')); | ||||
|  | ||||
|         // find account: | ||||
|         $account = $this->accounts->find(intval(Input::get('account_id'))); | ||||
|  | ||||
|         // find amount & description: | ||||
|         $description = trim(Input::get('description')); | ||||
|         $amount = floatval(Input::get('amount')); | ||||
|         $date = new \Carbon\Carbon(Input::get('date')); | ||||
|  | ||||
|         // create journal | ||||
|         /** @var \TransactionJournal $journal */ | ||||
|         try { | ||||
|             $journal = $this->tj->createSimpleJournal($beneficiary, $account, $description, $amount, $date); | ||||
|         } catch (\Firefly\Exception\FireflyException $e) { | ||||
|             return Redirect::route('transactions.deposit')->withInput(); | ||||
|         } | ||||
|  | ||||
|         if (!is_null($category)) { | ||||
|             $journal->categories()->save($category); | ||||
|         } | ||||
|  | ||||
|         Session::flash('success', 'Transaction saved'); | ||||
|         return Redirect::route('index'); | ||||
|     } | ||||
|  | ||||
|     public function postCreateTransfer() | ||||
|     { | ||||
|         // create or find category: | ||||
|         $category = $this->categories->createOrFind(Input::get('category')); | ||||
|  | ||||
|         // find account to: | ||||
|         $to = $this->accounts->find(intval(Input::get('account_to_id'))); | ||||
|  | ||||
|         // find account from | ||||
|         $from = $this->accounts->find(intval(Input::get('account_from_id'))); | ||||
|  | ||||
|         // find amount & description: | ||||
|         $description = trim(Input::get('description')); | ||||
|         $amount = floatval(Input::get('amount')); | ||||
|         $date = new \Carbon\Carbon(Input::get('date')); | ||||
|  | ||||
|         // create journal | ||||
|         /** @var \TransactionJournal $journal */ | ||||
|         try { | ||||
|             $journal = $this->tj->createSimpleJournal($from, $to, $description, $amount, $date); | ||||
|         } catch (\Firefly\Exception\FireflyException $e) { | ||||
|             return Redirect::route('transactions.transfer')->withInput(); | ||||
|         } | ||||
|         if (!is_null($category)) { | ||||
|             $journal->categories()->save($category); | ||||
|         } | ||||
|  | ||||
|         Session::flash('success', 'Transaction saved'); | ||||
|         return Redirect::route('index'); | ||||
|     } | ||||
|  | ||||
| }  | ||||
| @@ -17,6 +17,8 @@ interface AccountRepositoryInterface | ||||
|  | ||||
|     public function findByName($name); | ||||
|  | ||||
|     public function getCashAccount(); | ||||
|  | ||||
|     public function getByIds($ids); | ||||
|  | ||||
|     public function getDefault(); | ||||
|   | ||||
| @@ -129,6 +129,9 @@ class EloquentAccountRepository implements AccountRepositoryInterface | ||||
|  | ||||
|     public function createOrFindBeneficiary($name) | ||||
|     { | ||||
|         if (is_null($name) || strlen($name) == 0) { | ||||
|             return null; | ||||
|         } | ||||
|         $type = \AccountType::where('description', 'Beneficiary account')->first(); | ||||
|         return $this->createOrFind($name, $type); | ||||
|     } | ||||
| @@ -151,4 +154,12 @@ class EloquentAccountRepository implements AccountRepositoryInterface | ||||
|         return \Auth::user()->accounts()->where('name', 'like', '%' . $name . '%')->first(); | ||||
|     } | ||||
|  | ||||
|     public function getCashAccount() | ||||
|     { | ||||
|         $type = \AccountType::where('description','Cash account')->first(); | ||||
|         $cash = \Auth::user()->accounts()->where('account_type_id',$type->id)->first(); | ||||
|         return $cash; | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -4,6 +4,8 @@ | ||||
| namespace Firefly\Storage\TransactionJournal; | ||||
|  | ||||
|  | ||||
| use Firefly\Exception\FireflyException; | ||||
|  | ||||
| class EloquentTransactionJournalRepository implements TransactionJournalRepositoryInterface | ||||
| { | ||||
|  | ||||
| @@ -36,6 +38,18 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito | ||||
|         $amountFrom = $amount * -1; | ||||
|         $amountTo = $amount; | ||||
|  | ||||
|         if(round(floatval($amount),2) == 0.00) { | ||||
|             \Log::error('Transaction will never save: amount = 0'); | ||||
|             \Session::flash('error','The amount should not be empty or zero.'); | ||||
|             throw new \Firefly\Exception\FireflyException('Could not figure out transaction type.'); | ||||
|         } | ||||
|         // same account: | ||||
|         if($from->id == $to->id) { | ||||
|             \Log::error('Accounts cannot be equal'); | ||||
|             \Session::flash('error','Select two different accounts.'); | ||||
|             throw new \Firefly\Exception\FireflyException('Select two different accounts.'); | ||||
|         } | ||||
|  | ||||
|         // account types for both: | ||||
|         $toAT = $to->accountType->description; | ||||
|         $fromAT = $from->accountType->description; | ||||
| @@ -94,6 +108,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito | ||||
|         if (!$journal->save()) { | ||||
|             \Log::error('Cannot create valid journal.'); | ||||
|             \Log::error('Errors: ' . print_r($journal->errors()->all(), true)); | ||||
|             \Session::flash('error','Could not create journal: ' . $journal->errors()->first()); | ||||
|             throw new \Firefly\Exception\FireflyException('Cannot create valid journal.'); | ||||
|         } | ||||
|         $journal->save(); | ||||
| @@ -158,6 +173,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito | ||||
|                     }] | ||||
|             ) | ||||
|             ->after($start)->before($end) | ||||
|             ->where('completed',1) | ||||
|             ->whereIn('transaction_type_id', $types) | ||||
|             ->get(['transaction_journals.*']); | ||||
|         unset($types); | ||||
| @@ -166,6 +182,9 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito | ||||
|  | ||||
|         foreach ($journals as $journal) { | ||||
|             // has to be one: | ||||
|             if(!isset($journal->transactions[0])) { | ||||
|                 throw new FireflyException('Journal #'.$journal->id.' has ' . count($journal->transactions).' transactions!'); | ||||
|             } | ||||
|             $transaction = $journal->transactions[0]; | ||||
|             $amount = floatval($transaction->amount); | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <?php | ||||
|  | ||||
| use \League\FactoryMuffin\Facade\FactoryMuffin; | ||||
| use League\FactoryMuffin\Facade\FactoryMuffin; | ||||
|  | ||||
| class TransactionControllerTest extends TestCase | ||||
| { | ||||
| @@ -51,6 +51,63 @@ class TransactionControllerTest extends TestCase | ||||
|         $this->assertResponseOk(); | ||||
|     } | ||||
|  | ||||
|     public function testCreateDeposit() | ||||
|     { | ||||
|  | ||||
|         $set = [0 => '(no budget)']; | ||||
|         View::shouldReceive('share'); | ||||
|         View::shouldReceive('make')->with('transactions.deposit')->andReturn(\Mockery::self()) | ||||
|             ->shouldReceive('with')->once() | ||||
|             ->with('accounts', []) | ||||
|             ->andReturn(Mockery::self()) | ||||
|             ->shouldReceive('with')->once() | ||||
|             ->with('budgets', $set)->andReturn(Mockery::self()); | ||||
|  | ||||
|         // mock account repository: | ||||
|         $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $accounts->shouldReceive('getActiveDefaultAsSelectList')->andReturn([]); | ||||
|  | ||||
|         // mock budget repository: | ||||
|         $budgets = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface'); | ||||
|         $budgets->shouldReceive('getAsSelectList')->andReturn($set); | ||||
|  | ||||
|  | ||||
|         // call | ||||
|         $this->call('GET', '/transactions/add/deposit'); | ||||
|  | ||||
|         // test | ||||
|         $this->assertResponseOk(); | ||||
|     } | ||||
|  | ||||
|     public function testCreateTransfer() | ||||
|     { | ||||
|  | ||||
|         $set = [0 => '(no budget)']; | ||||
|         View::shouldReceive('share'); | ||||
|         View::shouldReceive('make')->with('transactions.transfer')->andReturn(\Mockery::self()) | ||||
|             ->shouldReceive('with')->once() | ||||
|             ->with('accounts', []) | ||||
|             ->andReturn(Mockery::self()) | ||||
|             ->shouldReceive('with')->once() | ||||
|             ->with('budgets', $set)->andReturn(Mockery::self()); | ||||
|  | ||||
|         // mock account repository: | ||||
|         $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $accounts->shouldReceive('getActiveDefaultAsSelectList')->andReturn([]); | ||||
|  | ||||
|         // mock budget repository: | ||||
|         $budgets = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface'); | ||||
|         $budgets->shouldReceive('getAsSelectList')->andReturn($set); | ||||
|  | ||||
|  | ||||
|         // call | ||||
|         $this->call('GET', '/transactions/add/transfer'); | ||||
|  | ||||
|         // test | ||||
|         $this->assertResponseOk(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     public function testPostCreateWithdrawal() | ||||
|     { | ||||
|         // create objects. | ||||
| @@ -90,7 +147,130 @@ class TransactionControllerTest extends TestCase | ||||
|         $tj = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|         $tj->shouldReceive('createSimpleJournal')->once()->andReturn($journal); | ||||
|  | ||||
| //        $tj->shouldReceive('createSimpleJournal')->with($account, $beneficiary, $data['description'], $data['amount'], new \Carbon\Carbon($data['date']))->once()->andReturn($journal); | ||||
|         // call | ||||
|         $this->call('POST', '/transactions/add/withdrawal', $data); | ||||
|  | ||||
|         // test | ||||
|         $this->assertRedirectedToRoute('index'); | ||||
|     } | ||||
|  | ||||
|     public function testPostCreateDeposit() | ||||
|     { | ||||
|         // create objects. | ||||
|         $account = FactoryMuffin::create('Account'); | ||||
|         $beneficiary = FactoryMuffin::create('Account'); | ||||
|         $category = FactoryMuffin::create('Category'); | ||||
|  | ||||
|  | ||||
|         // data to send: | ||||
|         $data = [ | ||||
|             'beneficiary' => $beneficiary->name, | ||||
|             'category'    => $category->name, | ||||
|             'account_id'  => $account->id, | ||||
|             'description' => 'Bla', | ||||
|             'amount'      => 1.2, | ||||
|             'date'        => '2012-01-01' | ||||
|         ]; | ||||
|         $journal = FactoryMuffin::create('TransactionJournal'); | ||||
|  | ||||
|         // mock account repository: | ||||
|         $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $accounts->shouldReceive('createOrFindBeneficiary')->with($beneficiary->name)->andReturn($beneficiary); | ||||
|         $accounts->shouldReceive('find')->andReturn($account); | ||||
|  | ||||
|         // mock category repository | ||||
|         $categories = $this->mock('Firefly\Storage\Category\CategoryRepositoryInterface'); | ||||
|         $categories->shouldReceive('createOrFind')->with($category->name)->andReturn($category); | ||||
|  | ||||
|         // mock transaction journal: | ||||
|         $tj = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|         $tj->shouldReceive('createSimpleJournal')->once()->andReturn($journal); | ||||
|  | ||||
|         // call | ||||
|         $this->call('POST', '/transactions/add/deposit', $data); | ||||
|  | ||||
|         // test | ||||
|         $this->assertRedirectedToRoute('index'); | ||||
|     } | ||||
|  | ||||
|     public function testPostCreateTransfer() | ||||
|     { | ||||
|         // create objects. | ||||
|         $from = FactoryMuffin::create('Account'); | ||||
|         $to = FactoryMuffin::create('Account'); | ||||
|         $category = FactoryMuffin::create('Category'); | ||||
|  | ||||
|  | ||||
|         // data to send: | ||||
|         $data = [ | ||||
|             'category'        => $category->name, | ||||
|             'account_from_id' => $from->id, | ||||
|             'account_to_id'   => $to->id, | ||||
|             'description'     => 'Bla', | ||||
|             'amount'          => 1.2, | ||||
|             'date'            => '2012-01-01' | ||||
|         ]; | ||||
|         $journal = FactoryMuffin::create('TransactionJournal'); | ||||
|  | ||||
|         // mock account repository: | ||||
|         $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $accounts->shouldReceive('find')->with($from->id)->andReturn($from); | ||||
|         $accounts->shouldReceive('find')->with($to->id)->andReturn($to); | ||||
|  | ||||
|         // mock category repository | ||||
|         $categories = $this->mock('Firefly\Storage\Category\CategoryRepositoryInterface'); | ||||
|         $categories->shouldReceive('createOrFind')->with($category->name)->andReturn($category); | ||||
|  | ||||
|         // mock transaction journal: | ||||
|         $tj = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|         $tj->shouldReceive('createSimpleJournal')->once()->andReturn($journal); | ||||
|  | ||||
|         // call | ||||
|         $this->call('POST', '/transactions/add/transfer', $data); | ||||
|  | ||||
|         // test | ||||
|         $this->assertRedirectedToRoute('index'); | ||||
|     } | ||||
|  | ||||
|     public function testPostCreateWithdrawalEmptyBeneficiary() | ||||
|     { | ||||
|         // create objects. | ||||
|         $account = FactoryMuffin::create('Account'); | ||||
|         $beneficiary = FactoryMuffin::create('Account'); | ||||
|         $category = FactoryMuffin::create('Category'); | ||||
|         $budget = FactoryMuffin::create('Budget'); | ||||
|  | ||||
|  | ||||
|         // data to send: | ||||
|         $data = [ | ||||
|             'beneficiary' => '', | ||||
|             'category'    => $category->name, | ||||
|             'budget_id'   => $budget->id, | ||||
|             'account_id'  => $account->id, | ||||
|             'description' => 'Bla', | ||||
|             'amount'      => 1.2, | ||||
|             'date'        => '2012-01-01' | ||||
|         ]; | ||||
|         $journal = FactoryMuffin::create('TransactionJournal'); | ||||
|  | ||||
|         // mock account repository: | ||||
|         $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $accounts->shouldReceive('createOrFindBeneficiary')->with('')->andReturn(null); | ||||
|         $accounts->shouldReceive('getCashAccount')->andReturn($beneficiary); | ||||
|         $accounts->shouldReceive('find')->andReturn($account); | ||||
|  | ||||
|         // mock category repository | ||||
|         $categories = $this->mock('Firefly\Storage\Category\CategoryRepositoryInterface'); | ||||
|         $categories->shouldReceive('createOrFind')->with($category->name)->andReturn($category); | ||||
|  | ||||
|         // mock budget repository | ||||
|         $budgets = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface'); | ||||
|         $budgets->shouldReceive('createOrFind')->with($budget->name)->andReturn($budget); | ||||
|         $budgets->shouldReceive('find')->andReturn($budget); | ||||
|  | ||||
|         // mock transaction journal: | ||||
|         $tj = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|         $tj->shouldReceive('createSimpleJournal')->once()->andReturn($journal); | ||||
|  | ||||
|         // call | ||||
|         $this->call('POST', '/transactions/add/withdrawal', $data); | ||||
| @@ -98,6 +278,194 @@ class TransactionControllerTest extends TestCase | ||||
|         // test | ||||
|         $this->assertRedirectedToRoute('index'); | ||||
|     } | ||||
|  | ||||
|     public function testPostCreateDepositEmptyBeneficiary() | ||||
|     { | ||||
|         // create objects. | ||||
|         $account = FactoryMuffin::create('Account'); | ||||
|         $beneficiary = FactoryMuffin::create('Account'); | ||||
|         $category = FactoryMuffin::create('Category'); | ||||
|         $budget = FactoryMuffin::create('Budget'); | ||||
|  | ||||
|  | ||||
|         // data to send: | ||||
|         $data = [ | ||||
|             'beneficiary' => '', | ||||
|             'category'    => $category->name, | ||||
|             'budget_id'   => $budget->id, | ||||
|             'account_id'  => $account->id, | ||||
|             'description' => 'Bla', | ||||
|             'amount'      => 1.2, | ||||
|             'date'        => '2012-01-01' | ||||
|         ]; | ||||
|         $journal = FactoryMuffin::create('TransactionJournal'); | ||||
|  | ||||
|         // mock account repository: | ||||
|         $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $accounts->shouldReceive('createOrFindBeneficiary')->with('')->andReturn(null); | ||||
|         $accounts->shouldReceive('getCashAccount')->andReturn($beneficiary); | ||||
|         $accounts->shouldReceive('find')->andReturn($account); | ||||
|  | ||||
|         // mock category repository | ||||
|         $categories = $this->mock('Firefly\Storage\Category\CategoryRepositoryInterface'); | ||||
|         $categories->shouldReceive('createOrFind')->with($category->name)->andReturn($category); | ||||
|  | ||||
|         // mock budget repository | ||||
|         $budgets = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface'); | ||||
|         $budgets->shouldReceive('createOrFind')->with($budget->name)->andReturn($budget); | ||||
|         $budgets->shouldReceive('find')->andReturn($budget); | ||||
|  | ||||
|         // mock transaction journal: | ||||
|         $tj = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|         $tj->shouldReceive('createSimpleJournal')->once()->andReturn($journal); | ||||
|  | ||||
|         // call | ||||
|         $this->call('POST', '/transactions/add/deposit', $data); | ||||
|  | ||||
|         // test | ||||
|         $this->assertRedirectedToRoute('index'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @expectedException Firefly\Exception\FireflyException; | ||||
|      */ | ||||
|     public function testPostCreateWithdrawalException() | ||||
|     { | ||||
|         // create objects. | ||||
|         $account = FactoryMuffin::create('Account'); | ||||
|         $beneficiary = FactoryMuffin::create('Account'); | ||||
|         $category = FactoryMuffin::create('Category'); | ||||
|         $budget = FactoryMuffin::create('Budget'); | ||||
|  | ||||
|  | ||||
|         // data to send: | ||||
|         $data = [ | ||||
|             'beneficiary' => '', | ||||
|             'category'    => $category->name, | ||||
|             'budget_id'   => $budget->id, | ||||
|             'account_id'  => $account->id, | ||||
|             'description' => 'Bla', | ||||
|             'amount'      => 1.2, | ||||
|             'date'        => '2012-01-01' | ||||
|         ]; | ||||
|         $journal = FactoryMuffin::create('TransactionJournal'); | ||||
|  | ||||
|         // mock account repository: | ||||
|         $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $accounts->shouldReceive('createOrFindBeneficiary')->with('')->andReturn(null); | ||||
|         $accounts->shouldReceive('getCashAccount')->andReturn($beneficiary); | ||||
|         $accounts->shouldReceive('find')->andReturn($account); | ||||
|  | ||||
|         // mock category repository | ||||
|         $categories = $this->mock('Firefly\Storage\Category\CategoryRepositoryInterface'); | ||||
|         $categories->shouldReceive('createOrFind')->with($category->name)->andReturn($category); | ||||
|  | ||||
|         // mock budget repository | ||||
|         $budgets = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface'); | ||||
|         $budgets->shouldReceive('createOrFind')->with($budget->name)->andReturn($budget); | ||||
|         $budgets->shouldReceive('find')->andReturn($budget); | ||||
|  | ||||
|         // mock transaction journal: | ||||
|         $tj = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|         $tj->shouldReceive('createSimpleJournal')->andThrow('Firefly\Exception\FireflyException'); | ||||
|  | ||||
|         // call | ||||
|         $this->call('POST', '/transactions/add/withdrawal', $data); | ||||
|  | ||||
|         // test | ||||
|         $this->assertRedirectedToRoute('transactions.withdrawal'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @expectedException Firefly\Exception\FireflyException; | ||||
|      */ | ||||
|     public function testPostCreateDepositException() | ||||
|     { | ||||
|         // create objects. | ||||
|         $account = FactoryMuffin::create('Account'); | ||||
|         $beneficiary = FactoryMuffin::create('Account'); | ||||
|         $category = FactoryMuffin::create('Category'); | ||||
|         $budget = FactoryMuffin::create('Budget'); | ||||
|  | ||||
|  | ||||
|         // data to send: | ||||
|         $data = [ | ||||
|             'beneficiary' => '', | ||||
|             'category'    => $category->name, | ||||
|             'budget_id'   => $budget->id, | ||||
|             'account_id'  => $account->id, | ||||
|             'description' => 'Bla', | ||||
|             'amount'      => 1.2, | ||||
|             'date'        => '2012-01-01' | ||||
|         ]; | ||||
|         $journal = FactoryMuffin::create('TransactionJournal'); | ||||
|  | ||||
|         // mock account repository: | ||||
|         $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $accounts->shouldReceive('createOrFindBeneficiary')->with('')->andReturn(null); | ||||
|         $accounts->shouldReceive('getCashAccount')->andReturn($beneficiary); | ||||
|         $accounts->shouldReceive('find')->andReturn($account); | ||||
|  | ||||
|         // mock category repository | ||||
|         $categories = $this->mock('Firefly\Storage\Category\CategoryRepositoryInterface'); | ||||
|         $categories->shouldReceive('createOrFind')->with($category->name)->andReturn($category); | ||||
|  | ||||
|         // mock budget repository | ||||
|         $budgets = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface'); | ||||
|         $budgets->shouldReceive('createOrFind')->with($budget->name)->andReturn($budget); | ||||
|         $budgets->shouldReceive('find')->andReturn($budget); | ||||
|  | ||||
|         // mock transaction journal: | ||||
|         $tj = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|         $tj->shouldReceive('createSimpleJournal')->andThrow('Firefly\Exception\FireflyException'); | ||||
|  | ||||
|         // call | ||||
|         $this->call('POST', '/transactions/add/deposit', $data); | ||||
|  | ||||
|         // test | ||||
|         $this->assertRedirectedToRoute('transactions.deposit'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @expectedException Firefly\Exception\FireflyException; | ||||
|      */ | ||||
|     public function testPostCreateTransferException() | ||||
|     { | ||||
|         // create objects. | ||||
|         $from = FactoryMuffin::create('Account'); | ||||
|         $category = FactoryMuffin::create('Category'); | ||||
|  | ||||
|  | ||||
|         // data to send: | ||||
|         $data = [ | ||||
|             'category'        => $category->name, | ||||
|             'account_from_id' => $from->id, | ||||
|             'account_to_id'   => $from->id, | ||||
|             'description'     => 'Bla', | ||||
|             'amount'          => 1.2, | ||||
|             'date'            => '2012-01-01' | ||||
|         ]; | ||||
|  | ||||
|         // mock account repository: | ||||
|         $accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $accounts->shouldReceive('find')->with($from->id)->andReturn($from); | ||||
|         $accounts->shouldReceive('find')->with($from->id)->andReturn($from); | ||||
|  | ||||
|         // mock category repository | ||||
|         $categories = $this->mock('Firefly\Storage\Category\CategoryRepositoryInterface'); | ||||
|         $categories->shouldReceive('createOrFind')->with($category->name)->andReturn($category); | ||||
|  | ||||
|         // mock transaction journal: | ||||
|         $tj = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|         $tj->shouldReceive('createSimpleJournal')->andThrow('Firefly\Exception\FireflyException'); | ||||
|  | ||||
|         // call | ||||
|         $this->call('POST', '/transactions/add/transfer', $data); | ||||
|  | ||||
|         // test | ||||
|         $this->assertRedirectedToRoute('transactions.transfer'); | ||||
|     } | ||||
|  | ||||
|     public function tearDown() | ||||
|     { | ||||
|         Mockery::close(); | ||||
|   | ||||
							
								
								
									
										98
									
								
								app/views/transactions/deposit.blade.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								app/views/transactions/deposit.blade.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| @extends('layouts.default') | ||||
| @section('content') | ||||
| <div class="row"> | ||||
|     <div class="col-lg-12 col-md-12 col-sm-12"> | ||||
|         <h1>Firefly | ||||
|             <small>Add a new deposit</small> | ||||
|         </h1> | ||||
|     </div> | ||||
| </div> | ||||
| <div class="row"> | ||||
|     <div class="col-lg-6 col-md-12 col-sm-12"> | ||||
|         <p class="text-info"> | ||||
|             Technically speaking, withdrawals, deposits and transfers are all transactions, moving money from | ||||
|             account <em>A</em> to account <em>B</em>. | ||||
|         </p> | ||||
|         <p class="text-info"> | ||||
|             A deposit is when you earn money, moving an amount from a beneficiary into your own account. | ||||
|         </p> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| {{Form::open(['class' => 'form-horizontal'])}} | ||||
|  | ||||
| <div class="row"> | ||||
|     <div class="col-lg-6 col-md-12 col-sm-12"> | ||||
|         <h4>Mandatory fields</h4> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="description" class="col-sm-4 control-label">Description</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="text" name="description" value="{{{Input::old('description')}}}" autocomplete="off" class="form-control" placeholder="Description" /> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|  | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="beneficiary" class="col-sm-4 control-label">Beneficiary (payer)</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="text" name="beneficiary" value="{{{Input::old('beneficiary')}}}" autocomplete="off" class="form-control" placeholder="Beneficiary" /> | ||||
|                 <span class="help-block">This field will auto-complete your existing beneficiaries (if any), but you can type freely to create new ones.</span> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="account_id" class="col-sm-4 control-label">Account</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 {{Form::select('account_id',$accounts,Input::old('account_id'),['class' => 'form-control'])}} | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|  | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="amount" class="col-sm-4 control-label">Amount spent</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="number" name="amount" min="0.01" value="{{Input::old('amount') or 0}}" step="any" class="form-control" /> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="date" class="col-sm-4 control-label">Date</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="date" name="date" value="{{Input::old('date') ?: date('Y-m-d')}}" class="form-control" /> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="submit" class="col-sm-4 control-label"> </label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="submit" name="submit" value="Create deposit" class="btn btn-info" /> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|     </div> | ||||
|     <div class="col-lg-6 col-md-12 col-sm-12"> | ||||
|         <h4>Optional fields</h4> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="category" class="col-sm-4 control-label">Category</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="text" name="category"  value="" autocomplete="off" class="form-control" placeholder="Category" /> | ||||
|                 <span class="help-block">Add more fine-grained information to this transaction by entering a category. | ||||
|                 Like the beneficiary-field, this field will auto-complete existing categories but can also be used | ||||
|                     to create new ones. | ||||
|                 </span> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|     </div> | ||||
|  | ||||
|  | ||||
|  | ||||
| @stop | ||||
| @section('scripts') | ||||
|  | ||||
|     <script type="text/javascript" src="assets/javascript/withdrawal.js"></script> | ||||
| @stop | ||||
							
								
								
									
										96
									
								
								app/views/transactions/transfer.blade.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								app/views/transactions/transfer.blade.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| @extends('layouts.default') | ||||
| @section('content') | ||||
| <div class="row"> | ||||
|     <div class="col-lg-12 col-md-12 col-sm-12"> | ||||
|         <h1>Firefly | ||||
|             <small>Add a new transfer</small> | ||||
|         </h1> | ||||
|     </div> | ||||
| </div> | ||||
| <div class="row"> | ||||
|     <div class="col-lg-6 col-md-12 col-sm-12"> | ||||
|         <p class="text-info"> | ||||
|             Technically speaking, withdrawals, deposits and transfers are all transactions, moving money from | ||||
|             account <em>A</em> to account <em>B</em>. | ||||
|         </p> | ||||
|         <p class="text-info"> | ||||
|             A transfer moves money between your own accounts. | ||||
|         </p> | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| {{Form::open(['class' => 'form-horizontal'])}} | ||||
|  | ||||
| <div class="row"> | ||||
|     <div class="col-lg-6 col-md-12 col-sm-12"> | ||||
|         <h4>Mandatory fields</h4> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="description" class="col-sm-4 control-label">Description</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="text" name="description" value="{{{Input::old('description')}}}" autocomplete="off" class="form-control" placeholder="Description" /> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|  | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="account_from_id" class="col-sm-4 control-label">Account from</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 {{Form::select('account_to_id',$accounts,Input::old('account_from_id'),['class' => 'form-control'])}} | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="account_to_id" class="col-sm-4 control-label">Account to</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 {{Form::select('account_from_id',$accounts,Input::old('account_to_id'),['class' => 'form-control'])}} | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="amount" class="col-sm-4 control-label">Amount spent</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="number" name="amount" min="0.01" value="{{floatval(Input::old('amount'))}}" step="any" class="form-control" /> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="date" class="col-sm-4 control-label">Date</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="date" name="date" value="{{Input::old('date') ?: date('Y-m-d')}}" class="form-control" /> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="submit" class="col-sm-4 control-label"> </label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="submit" name="submit" value="Create transfer" class="btn btn-info" /> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|     </div> | ||||
|     <div class="col-lg-6 col-md-12 col-sm-12"> | ||||
|         <h4>Optional fields</h4> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label for="category" class="col-sm-4 control-label">Category</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="text" name="category"  value="" autocomplete="off" class="form-control" placeholder="Category" /> | ||||
|                 <span class="help-block">Add more fine-grained information to this transaction by entering a category. | ||||
|                 Like the beneficiary-field, this field will auto-complete existing categories but can also be used | ||||
|                     to create new ones. | ||||
|                 </span> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|     </div> | ||||
|  | ||||
|  | ||||
|  | ||||
| @stop | ||||
| @section('scripts') | ||||
|  | ||||
|     <script type="text/javascript" src="assets/javascript/withdrawal.js"></script> | ||||
| @stop | ||||
| @@ -52,7 +52,7 @@ | ||||
|         <div class="form-group"> | ||||
|             <label for="amount" class="col-sm-4 control-label">Amount spent</label> | ||||
|             <div class="col-sm-8"> | ||||
|                 <input type="number" name="amount" min="0.01" step="any" class="form-control" /> | ||||
|                 <input type="number" name="amount" min="0.01" value="{{Input::old('amount') or 0}}" step="any" class="form-control" /> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user