Create deposits, transfers and withdrawals. Also tests!

This commit is contained in:
James Cole 2014-07-15 20:58:35 +02:00
parent 1f4436cb75
commit 9687b5fb33
8 changed files with 701 additions and 5 deletions

View File

@ -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');
}
}

View File

@ -17,6 +17,8 @@ interface AccountRepositoryInterface
public function findByName($name);
public function getCashAccount();
public function getByIds($ids);
public function getDefault();

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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();

View 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">&nbsp;</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

View 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">&nbsp;</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

View File

@ -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>