mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-05 04:03:26 +00:00
- Updated transaction controller to need less code for the same work.
- Small feedback bug in migration controller - Better database create scripts. - Fixed bug in seed scripts. - Cleanup and fixed sorting in various helpers - Extended some tests to catch changed code. - Created show(journal) and edit(journal) (untested) [skip-ci]
This commit is contained in:
@@ -35,6 +35,9 @@ class MigrationController extends BaseController
|
||||
$migration->loadFile($file);
|
||||
if ($migration->validFile()) {
|
||||
$migration->migrate();
|
||||
} else {
|
||||
echo 'Invalid file.';
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -34,26 +34,7 @@ class TransactionController extends BaseController
|
||||
View::share('menu', 'home');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this|\Illuminate\View\View
|
||||
*/
|
||||
public function createWithdrawal()
|
||||
{
|
||||
|
||||
// get accounts with names and id's.
|
||||
$accounts = $this->_accounts->getActiveDefaultAsSelectList();
|
||||
|
||||
$budgets = $this->_budgets->getAsSelectList();
|
||||
|
||||
$budgets[0] = '(no budget)';
|
||||
|
||||
return View::make('transactions.withdrawal')->with('accounts', $accounts)->with('budgets', $budgets);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this|\Illuminate\View\View
|
||||
*/
|
||||
public function createDeposit()
|
||||
public function create($what)
|
||||
{
|
||||
// get accounts with names and id's.
|
||||
$accounts = $this->_accounts->getActiveDefaultAsSelectList();
|
||||
@@ -62,38 +43,39 @@ class TransactionController extends BaseController
|
||||
|
||||
$budgets[0] = '(no budget)';
|
||||
|
||||
return View::make('transactions.deposit')->with('accounts', $accounts)->with('budgets', $budgets);
|
||||
|
||||
return View::make('transactions.create')->with('accounts', $accounts)->with('budgets', $budgets)->with(
|
||||
'what', $what
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this|\Illuminate\View\View
|
||||
*/
|
||||
public function createTransfer()
|
||||
public function store($what)
|
||||
{
|
||||
// get accounts with names and id's.
|
||||
$accounts = $this->_accounts->getActiveDefaultAsSelectList();
|
||||
// $fromAccount and $toAccount are found
|
||||
// depending on the $what
|
||||
|
||||
$budgets = $this->_budgets->getAsSelectList();
|
||||
$fromAccount = null;
|
||||
$toAccount = null;
|
||||
|
||||
$budgets[0] = '(no budget)';
|
||||
|
||||
return View::make('transactions.transfer')->with('accounts', $accounts)->with('budgets', $budgets);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
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();
|
||||
switch ($what) {
|
||||
case 'withdrawal':
|
||||
$fromAccount = $this->_accounts->find(intval(Input::get('account_id')));
|
||||
$toAccount = $this->_accounts->createOrFindBeneficiary(Input::get('beneficiary'));
|
||||
break;
|
||||
case 'deposit':
|
||||
$fromAccount = $this->_accounts->createOrFindBeneficiary(Input::get('beneficiary'));
|
||||
$toAccount = $this->_accounts->find(intval(Input::get('account_id')));
|
||||
break;
|
||||
case 'transfer':
|
||||
$fromAccount = $this->_accounts->find(intval(Input::get('account_from_id')));
|
||||
$toAccount = $this->_accounts->find(intval(Input::get('account_to_id')));
|
||||
break;
|
||||
}
|
||||
// fall back to cash if necessary:
|
||||
if (is_null($fromAccount)) {
|
||||
$fromAccount = $this->_accounts->getCashAccount();
|
||||
}
|
||||
if (is_null($toAccount)) {
|
||||
$toAccount = $this->_accounts->getCashAccount();
|
||||
}
|
||||
|
||||
// create or find category:
|
||||
@@ -102,9 +84,6 @@ class TransactionController extends BaseController
|
||||
// find budget:
|
||||
$budget = $this->_budgets->find(intval(Input::get('budget_id')));
|
||||
|
||||
// find account:
|
||||
$account = $this->_accounts->find(intval(Input::get('account_id')));
|
||||
|
||||
// find amount & description:
|
||||
$description = trim(Input::get('description'));
|
||||
$amount = floatval(Input::get('amount'));
|
||||
@@ -113,9 +92,9 @@ class TransactionController extends BaseController
|
||||
// create journal
|
||||
/** @var \TransactionJournal $journal */
|
||||
try {
|
||||
$journal = $this->_journal->createSimpleJournal($account, $beneficiary, $description, $amount, $date);
|
||||
$journal = $this->_journal->createSimpleJournal($fromAccount, $toAccount, $description, $amount, $date);
|
||||
} catch (\Firefly\Exception\FireflyException $e) {
|
||||
return Redirect::route('transactions.withdrawal')->withInput();
|
||||
return Redirect::route('transactions.create', $what)->withInput();
|
||||
}
|
||||
|
||||
// attach bud/cat (?)
|
||||
@@ -128,80 +107,27 @@ class TransactionController extends BaseController
|
||||
|
||||
Session::flash('success', 'Transaction saved');
|
||||
return Redirect::route('index');
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postCreateDeposit()
|
||||
public function show($journalId)
|
||||
{
|
||||
// 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();
|
||||
$journal = $this->_journal->find($journalId);
|
||||
if ($journal) {
|
||||
return View::make('transactions.show')->with('journal', $journal);
|
||||
}
|
||||
|
||||
// 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->_journal->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');
|
||||
return View::make('error')->with('message', 'Invalid journal');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postCreateTransfer()
|
||||
public function edit($journalId)
|
||||
{
|
||||
// create or find category:
|
||||
$category = $this->_categories->createOrFind(Input::get('category'));
|
||||
|
||||
// find account to:
|
||||
$toAccount = $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->_journal->createSimpleJournal($from, $toAccount, $description, $amount, $date);
|
||||
} catch (\Firefly\Exception\FireflyException $e) {
|
||||
return Redirect::route('transactions.transfer')->withInput();
|
||||
$journal = $this->_journal->find($journalId);
|
||||
if ($journal) {
|
||||
$accounts = $this->_accounts->getActiveDefaultAsSelectList();
|
||||
return View::make('transactions.edit')->with('journal', $journal)->with('accounts', $accounts);
|
||||
}
|
||||
if (!is_null($category)) {
|
||||
$journal->categories()->save($category);
|
||||
}
|
||||
|
||||
Session::flash('success', 'Transaction saved');
|
||||
return Redirect::route('index');
|
||||
return View::make('error')->with('message', 'Invalid journal');
|
||||
}
|
||||
|
||||
}
|
@@ -16,6 +16,7 @@ class CreateTransactionJournalsTable extends Migration {
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
$table->integer('user_id')->unsigned();
|
||||
$table->integer('transaction_type_id')->unsigned();
|
||||
$table->integer('transaction_currency_id')->unsigned();
|
||||
$table->string('description',255)->nullable();
|
||||
@@ -31,6 +32,11 @@ class CreateTransactionJournalsTable extends Migration {
|
||||
$table->foreign('transaction_currency_id')
|
||||
->references('id')->on('transaction_currencies')
|
||||
->onDelete('cascade');
|
||||
|
||||
// connect users
|
||||
$table->foreign('user_id')
|
||||
->references('id')->on('users')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1,42 +1,49 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class CreateTransactionsTable extends Migration {
|
||||
class CreateTransactionsTable extends Migration
|
||||
{
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('transactions', function(Blueprint $table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
$table->integer('account_id')->integer();
|
||||
$table->integer('transaction_journal_id')->integer()->unsigned();
|
||||
$table->string('description',255)->nullable();
|
||||
$table->decimal('amount',10,2);
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create(
|
||||
'transactions', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
$table->integer('account_id')->unsigned();
|
||||
$table->integer('transaction_journal_id')->unsigned();
|
||||
$table->string('description', 255)->nullable();
|
||||
$table->decimal('amount', 10, 2);
|
||||
|
||||
// connect transactions to transaction journals
|
||||
$table->foreign('transaction_journal_id')
|
||||
->references('id')->on('transaction_journals')
|
||||
->onDelete('cascade');
|
||||
// connect transactions to transaction journals
|
||||
$table->foreign('transaction_journal_id')
|
||||
->references('id')->on('transaction_journals')
|
||||
->onDelete('cascade');
|
||||
|
||||
});
|
||||
}
|
||||
// connect account id:
|
||||
$table->foreign('account_id')
|
||||
->references('id')->on('accounts')
|
||||
->onDelete('cascade');
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('transactions');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('transactions');
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -12,9 +12,10 @@ class DefaultUserSeeder extends Seeder
|
||||
'password' => Hash::make('sander'),
|
||||
'reset' => null,
|
||||
'remember_token' => null,
|
||||
'migrated' => false
|
||||
'migrated' => 0
|
||||
]
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -74,7 +74,8 @@ class MigrationHelper implements MigrationHelperInterface
|
||||
$cashAT = \AccountType::where('description', 'Cash account')->first();
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$cash = $accounts->store(['name' => 'Cash account', 'account_type' => $cashAT, 'active' => false]);
|
||||
$cash = $accounts->store(['name' => 'Cash account', 'account_type' => $cashAT, 'active' => 0]);
|
||||
\Log::info('Created cash account (#'.$cash->id.')');
|
||||
$this->map['cash'] = $cash;
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
|
||||
public function get()
|
||||
{
|
||||
return \Auth::user()->accounts()->with('accounttype')->get();
|
||||
return \Auth::user()->accounts()->with('accounttype')->orderBy('name','ASC')->get();
|
||||
}
|
||||
|
||||
public function getBeneficiaries()
|
||||
@@ -23,7 +23,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
)
|
||||
->where('account_types.description', 'Beneficiary account')->where('accounts.active', 1)
|
||||
|
||||
->get(['accounts.*']);
|
||||
->orderBy('accounts.name','ASC')->get(['accounts.*']);
|
||||
return $list;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
|
||||
public function getByIds($ids)
|
||||
{
|
||||
return \Auth::user()->accounts()->with('accounttype')->whereIn('id', $ids)->get();
|
||||
return \Auth::user()->accounts()->with('accounttype')->whereIn('id', $ids)->orderBy('name','ASC')->get();
|
||||
}
|
||||
|
||||
public function getDefault()
|
||||
@@ -42,7 +42,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
return \Auth::user()->accounts()->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.description', 'Default account')
|
||||
|
||||
->get(['accounts.*']);
|
||||
->orderBy('accounts.name','ASC')->get(['accounts.*']);
|
||||
}
|
||||
|
||||
public function getActiveDefault()
|
||||
@@ -60,7 +60,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
)
|
||||
->where('account_types.description', 'Default account')->where('accounts.active', 1)
|
||||
|
||||
->get(['accounts.*']);
|
||||
->orderBy('accounts.name','ASC')->get(['accounts.*']);
|
||||
$return = [];
|
||||
foreach ($list as $entry) {
|
||||
$return[intval($entry->id)] = $entry->name;
|
||||
|
@@ -9,32 +9,52 @@ use Firefly\Exception\FireflyException;
|
||||
class EloquentTransactionJournalRepository implements TransactionJournalRepositoryInterface
|
||||
{
|
||||
|
||||
public function find($journalId)
|
||||
{
|
||||
return \Auth::user()->transactionjournals()->with(
|
||||
['transactions', 'transactioncurrency', 'transactiontype', 'components', 'transactions.account',
|
||||
'transactions.account.accounttype']
|
||||
)
|
||||
->where('id', $journalId)->first();
|
||||
}
|
||||
/*
|
||||
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* We're building this thinking the money goes from A to B.
|
||||
* If the amount is negative however, the money still goes
|
||||
* from A to B but the balances are reversed.
|
||||
*
|
||||
* Aka:
|
||||
*
|
||||
* Amount = 200
|
||||
* A loses 200 (-200). * -1
|
||||
* B gains 200 (200). * 1
|
||||
*
|
||||
* Final balance: -200 for A, 200 for B.
|
||||
*
|
||||
* When the amount is negative:
|
||||
*
|
||||
* Amount = -200
|
||||
* A gains 200 (200). * -1
|
||||
* B loses 200 (-200). * 1
|
||||
*
|
||||
* @param \Account $from
|
||||
* @param \Account $to
|
||||
* @param $description
|
||||
* @param $amount
|
||||
* @param \Carbon\Carbon $date
|
||||
*
|
||||
* @return \TransactionJournal
|
||||
* @throws \Firefly\Exception\FireflyException
|
||||
*/
|
||||
public function createSimpleJournal(\Account $from, \Account $to, $description, $amount, \Carbon\Carbon $date)
|
||||
{
|
||||
|
||||
\Log::debug('Creating tranaction "' . $description . '".');
|
||||
/*
|
||||
* We're building this thinking the money goes from A to B.
|
||||
* If the amount is negative however, the money still goes
|
||||
* from A to B but the balances are reversed.
|
||||
*
|
||||
* Aka:
|
||||
*
|
||||
* Amount = 200
|
||||
* A loses 200 (-200). * -1
|
||||
* B gains 200 (200). * 1
|
||||
*
|
||||
* Final balance: -200 for A, 200 for B.
|
||||
*
|
||||
* When the amount is negative:
|
||||
*
|
||||
* Amount = -200
|
||||
* A gains 200 (200). * -1
|
||||
* B loses 200 (-200). * 1
|
||||
*
|
||||
*/
|
||||
|
||||
// amounts:
|
||||
$amountFrom = $amount * -1;
|
||||
$amountTo = $amount;
|
||||
|
||||
@@ -61,10 +81,8 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
$journalType = \TransactionType::where('type', 'Opening balance')->first();
|
||||
break;
|
||||
|
||||
// both are yours:
|
||||
case ($fromAT == 'Default account' && $toAT == 'Default account'):
|
||||
// determin transaction type. If both accounts are new, it's an initial
|
||||
// balance transfer.
|
||||
case ($fromAT == 'Default account' && $toAT == 'Default account'): // both are yours:
|
||||
// determin transaction type. If both accounts are new, it's an initial balance transfer.
|
||||
$journalType = \TransactionType::where('type', 'Transfer')->first();
|
||||
break;
|
||||
case ($amount < 0):
|
||||
@@ -102,6 +120,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
$journal = new \TransactionJournal();
|
||||
$journal->transactionType()->associate($journalType);
|
||||
$journal->transactionCurrency()->associate($currency);
|
||||
$journal->user()->associate(\Auth::user());
|
||||
$journal->completed = false;
|
||||
$journal->description = $description;
|
||||
$journal->date = $date;
|
||||
@@ -184,7 +203,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
// has to be one:
|
||||
if (!isset($journal->transactions[0])) {
|
||||
throw new FireflyException('Journal #' . $journal->id . ' has ' . count($journal->transactions)
|
||||
. ' transactions!');
|
||||
. ' transactions!');
|
||||
}
|
||||
$transaction = $journal->transactions[0];
|
||||
$amount = floatval($transaction->amount);
|
||||
@@ -201,6 +220,10 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
|
||||
}
|
||||
unset($journal, $transaction, $budget, $name, $amount);
|
||||
|
||||
// sort
|
||||
arsort($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -233,6 +256,8 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
)
|
||||
->after($start)->before($end)
|
||||
->whereIn('transaction_type_id', $types)
|
||||
->orderBy('date', 'DESC')
|
||||
->orderBy('id', 'DESC')
|
||||
->get(['transaction_journals.*']);
|
||||
foreach ($journals as $journal) {
|
||||
foreach ($journal->transactions as $t) {
|
||||
@@ -244,6 +269,10 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
}
|
||||
}
|
||||
}
|
||||
// sort result:
|
||||
arsort($result);
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@@ -9,6 +9,8 @@ interface TransactionJournalRepositoryInterface
|
||||
|
||||
public function get();
|
||||
|
||||
public function find($journalId);
|
||||
|
||||
public function getByAccount(\Account $account, $count = 25);
|
||||
|
||||
public function homeBudgetChart(\Carbon\Carbon $start, \Carbon\Carbon $end);
|
||||
|
@@ -6,32 +6,32 @@ use LaravelBook\Ardent\Ardent;
|
||||
/**
|
||||
* TransactionJournal
|
||||
*
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property integer $transaction_type_id
|
||||
* @property integer $transaction_currency_id
|
||||
* @property string $description
|
||||
* @property boolean $completed
|
||||
* @property \Carbon\Carbon $date
|
||||
* @property-read \TransactionType $transactionType
|
||||
* @property-read \TransactionCurrency $transactionCurrency
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property integer $transaction_type_id
|
||||
* @property integer $transaction_currency_id
|
||||
* @property string $description
|
||||
* @property boolean $completed
|
||||
* @property \Carbon\Carbon $date
|
||||
* @property-read \TransactionType $transactionType
|
||||
* @property-read \TransactionCurrency $transactionCurrency
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\Component[] $components
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\Component[] $components
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionTypeId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionCurrencyId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDescription($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCompleted($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDate($value)
|
||||
* @method static \TransactionJournal after($date)
|
||||
* @method static \TransactionJournal before($date)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionTypeId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionCurrencyId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDescription($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCompleted($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDate($value)
|
||||
* @method static \TransactionJournal after($date)
|
||||
* @method static \TransactionJournal before($date)
|
||||
*/
|
||||
class TransactionJournal extends Ardent
|
||||
{
|
||||
@@ -51,6 +51,7 @@ class TransactionJournal extends Ardent
|
||||
'transaction_currency_id' => 'factory|TransactionCurrency',
|
||||
'description' => 'string',
|
||||
'completed' => '1',
|
||||
'user_id' => 'factory|User',
|
||||
'date' => 'date|Y-m-d'
|
||||
];
|
||||
|
||||
@@ -59,6 +60,17 @@ class TransactionJournal extends Ardent
|
||||
return $this->belongsTo('TransactionType');
|
||||
}
|
||||
|
||||
/**
|
||||
* User
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('User');
|
||||
}
|
||||
|
||||
|
||||
public function transactionCurrency()
|
||||
{
|
||||
return $this->belongsTo('TransactionCurrency');
|
||||
|
@@ -91,4 +91,8 @@ class User extends Ardent implements UserInterface, RemindableInterface
|
||||
return $this->hasMany('Category');
|
||||
}
|
||||
|
||||
public function transactionjournals() {
|
||||
return $this->hasMany('TransactionJournal');
|
||||
}
|
||||
|
||||
}
|
@@ -32,9 +32,13 @@ Route::group(['before' => 'auth'], function () {
|
||||
|
||||
|
||||
// transaction controller:
|
||||
Route::get('/transactions/add/withdrawal', ['uses' => 'TransactionController@createWithdrawal', 'as' => 'transactions.withdrawal']);
|
||||
Route::get('/transactions/add/deposit', ['uses' => 'TransactionController@createDeposit', 'as' => 'transactions.deposit']);
|
||||
Route::get('/transactions/add/transfer', ['uses' => 'TransactionController@createTransfer', 'as' => 'transactions.transfer']);
|
||||
Route::get('/transactions/create/{what}', ['uses' => 'TransactionController@create', 'as' => 'transactions.create'])
|
||||
->where(['what' => 'withdrawal|deposit|transfer']);
|
||||
|
||||
|
||||
Route::get('/transaction/show/{id}',['uses' => 'TransactionController@show','as' => 'transactions.show']);
|
||||
Route::get('/transaction/edit/{id}',['uses' => 'TransactionController@edit','as' => 'transactions.edit']);
|
||||
Route::get('/transaction/delete/{id}',['uses' => 'TransactionController@delete','as' => 'transactions.delete']);
|
||||
// migration controller
|
||||
Route::get('/migrate', ['uses' => 'MigrationController@index', 'as' => 'migrate']);
|
||||
|
||||
@@ -56,9 +60,9 @@ Route::group(['before' => 'csrf|auth'], function () {
|
||||
Route::get('/accounts/store', ['uses' => 'AccountController@store', 'as' => 'accounts.store']);
|
||||
|
||||
// transaction controller:
|
||||
Route::post('/transactions/add/withdrawal', ['uses' => 'TransactionController@postCreateWithdrawal']);
|
||||
Route::post('/transactions/add/deposit', ['uses' => 'TransactionController@postCreateDeposit']);
|
||||
Route::post('/transactions/add/transfer', ['uses' => 'TransactionController@postCreateTransfer']);
|
||||
Route::post('/transactions/store/{what}', ['uses' => 'TransactionController@store', 'as' => 'transactions.store'])
|
||||
->where(['what' => 'withdrawal|deposit|transfer']);
|
||||
Route::post('/transaction/update/{id}',['uses' => 'TransactionController@update','as' => 'transactions.update']);
|
||||
|
||||
}
|
||||
);
|
||||
|
@@ -28,7 +28,10 @@ class TransactionControllerTest extends TestCase
|
||||
|
||||
$set = [0 => '(no budget)'];
|
||||
View::shouldReceive('share');
|
||||
View::shouldReceive('make')->with('transactions.withdrawal')->andReturn(\Mockery::self())
|
||||
View::shouldReceive('make')->with('transactions.create')->andReturn(\Mockery::self())
|
||||
->shouldReceive('with')->once()
|
||||
->with('what','withdrawal')
|
||||
->andReturn(Mockery::self())
|
||||
->shouldReceive('with')->once()
|
||||
->with('accounts', [])
|
||||
->andReturn(Mockery::self())
|
||||
@@ -45,7 +48,7 @@ class TransactionControllerTest extends TestCase
|
||||
|
||||
|
||||
// call
|
||||
$this->call('GET', '/transactions/add/withdrawal');
|
||||
$this->call('GET', '/transactions/create/withdrawal');
|
||||
|
||||
// test
|
||||
$this->assertResponseOk();
|
||||
@@ -56,7 +59,11 @@ class TransactionControllerTest extends TestCase
|
||||
|
||||
$set = [0 => '(no budget)'];
|
||||
View::shouldReceive('share');
|
||||
View::shouldReceive('make')->with('transactions.deposit')->andReturn(\Mockery::self())
|
||||
View::shouldReceive('make')->with('transactions.create')->andReturn(\Mockery::self())
|
||||
->shouldReceive('with')->once()
|
||||
->with('what','deposit')
|
||||
->andReturn(Mockery::self())
|
||||
|
||||
->shouldReceive('with')->once()
|
||||
->with('accounts', [])
|
||||
->andReturn(Mockery::self())
|
||||
@@ -73,7 +80,7 @@ class TransactionControllerTest extends TestCase
|
||||
|
||||
|
||||
// call
|
||||
$this->call('GET', '/transactions/add/deposit');
|
||||
$this->call('GET', '/transactions/create/deposit');
|
||||
|
||||
// test
|
||||
$this->assertResponseOk();
|
||||
@@ -84,7 +91,10 @@ class TransactionControllerTest extends TestCase
|
||||
|
||||
$set = [0 => '(no budget)'];
|
||||
View::shouldReceive('share');
|
||||
View::shouldReceive('make')->with('transactions.transfer')->andReturn(\Mockery::self())
|
||||
View::shouldReceive('make')->with('transactions.create')->andReturn(\Mockery::self())
|
||||
->shouldReceive('with')->once()
|
||||
->with('what', 'transfer')
|
||||
->andReturn(Mockery::self())
|
||||
->shouldReceive('with')->once()
|
||||
->with('accounts', [])
|
||||
->andReturn(Mockery::self())
|
||||
@@ -101,7 +111,7 @@ class TransactionControllerTest extends TestCase
|
||||
|
||||
|
||||
// call
|
||||
$this->call('GET', '/transactions/add/transfer');
|
||||
$this->call('GET', '/transactions/create/transfer');
|
||||
|
||||
// test
|
||||
$this->assertResponseOk();
|
||||
@@ -148,7 +158,7 @@ class TransactionControllerTest extends TestCase
|
||||
$tj->shouldReceive('createSimpleJournal')->once()->andReturn($journal);
|
||||
|
||||
// call
|
||||
$this->call('POST', '/transactions/add/withdrawal', $data);
|
||||
$this->call('POST', '/transactions/store/withdrawal', $data);
|
||||
|
||||
// test
|
||||
$this->assertRedirectedToRoute('index');
|
||||
@@ -186,8 +196,13 @@ class TransactionControllerTest extends TestCase
|
||||
$tj = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||
$tj->shouldReceive('createSimpleJournal')->once()->andReturn($journal);
|
||||
|
||||
// mock budget repository
|
||||
$budgets = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
||||
$budgets->shouldReceive('createOrFind')->with('')->andReturn(null);
|
||||
$budgets->shouldReceive('find')->andReturn(null);
|
||||
|
||||
// call
|
||||
$this->call('POST', '/transactions/add/deposit', $data);
|
||||
$this->call('POST', '/transactions/store/deposit', $data);
|
||||
|
||||
// test
|
||||
$this->assertRedirectedToRoute('index');
|
||||
@@ -225,8 +240,13 @@ class TransactionControllerTest extends TestCase
|
||||
$tj = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||
$tj->shouldReceive('createSimpleJournal')->once()->andReturn($journal);
|
||||
|
||||
// mock budget repository
|
||||
$budgets = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
||||
$budgets->shouldReceive('createOrFind')->with('')->andReturn(null);
|
||||
$budgets->shouldReceive('find')->andReturn(null);
|
||||
|
||||
// call
|
||||
$this->call('POST', '/transactions/add/transfer', $data);
|
||||
$this->call('POST', '/transactions/store/transfer', $data);
|
||||
|
||||
// test
|
||||
$this->assertRedirectedToRoute('index');
|
||||
@@ -273,7 +293,7 @@ class TransactionControllerTest extends TestCase
|
||||
$tj->shouldReceive('createSimpleJournal')->once()->andReturn($journal);
|
||||
|
||||
// call
|
||||
$this->call('POST', '/transactions/add/withdrawal', $data);
|
||||
$this->call('POST', '/transactions/store/withdrawal', $data);
|
||||
|
||||
// test
|
||||
$this->assertRedirectedToRoute('index');
|
||||
@@ -320,7 +340,7 @@ class TransactionControllerTest extends TestCase
|
||||
$tj->shouldReceive('createSimpleJournal')->once()->andReturn($journal);
|
||||
|
||||
// call
|
||||
$this->call('POST', '/transactions/add/deposit', $data);
|
||||
$this->call('POST', '/transactions/store/deposit', $data);
|
||||
|
||||
// test
|
||||
$this->assertRedirectedToRoute('index');
|
||||
@@ -370,10 +390,10 @@ class TransactionControllerTest extends TestCase
|
||||
$tj->shouldReceive('createSimpleJournal')->andThrow('Firefly\Exception\FireflyException');
|
||||
|
||||
// call
|
||||
$this->call('POST', '/transactions/add/withdrawal', $data);
|
||||
$this->call('POST', '/transactions/store/withdrawal', $data);
|
||||
|
||||
// test
|
||||
$this->assertRedirectedToRoute('transactions.withdrawal');
|
||||
$this->assertRedirectedToRoute('transactions.create',['what' => 'withdrawal']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -420,10 +440,10 @@ class TransactionControllerTest extends TestCase
|
||||
$tj->shouldReceive('createSimpleJournal')->andThrow('Firefly\Exception\FireflyException');
|
||||
|
||||
// call
|
||||
$this->call('POST', '/transactions/add/deposit', $data);
|
||||
$this->call('POST', '/transactions/store/deposit', $data);
|
||||
|
||||
// test
|
||||
$this->assertRedirectedToRoute('transactions.deposit');
|
||||
$this->assertRedirectedToRoute('transactions.create',['what' => 'deposit']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -455,15 +475,20 @@ class TransactionControllerTest extends TestCase
|
||||
$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('')->andReturn(null);
|
||||
$budgets->shouldReceive('find')->andReturn(null);
|
||||
|
||||
// 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);
|
||||
$this->call('POST', '/transactions/store/transfer', $data);
|
||||
|
||||
// test
|
||||
$this->assertRedirectedToRoute('transactions.transfer');
|
||||
$this->assertRedirectedToRoute('transactions.create',['what' => 'transfer']);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
|
@@ -18,10 +18,9 @@
|
||||
<button name="range" value="3M" class="btn btn-default @if($r=='3M') btn-info @endif btn-sm" type="submit">3M</button>
|
||||
<button name="range" value="6M" class="btn btn-default @if($r=='6M') btn-info @endif btn-sm" type="submit">6M</button>
|
||||
</span>
|
||||
<input value="{{Session::get('start')->format('Y-m-d')}}" name="start" type="date" style="width:15%;" class="form-control input-sm">
|
||||
<input value="{{Session::get('end')->format('Y-m-d')}}" name="end" type="date" style="width:15%;" class="form-control input-sm">
|
||||
<input value="{{Session::get('start')->format('Y-m-d')}}" name="start" type="date" style="width:15%;border-right:0;" class="form-control input-sm">
|
||||
<input value="{{Session::get('end')->format('Y-m-d')}}" name="end" type="date" style="width:15%;border-right:0;" class="form-control input-sm">
|
||||
<button class="btn btn-default btn-sm @if($r=='custom') btn-info @endif" type="submit" name="range" value="custom">Custom</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
@@ -4,9 +4,9 @@
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Add... <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
|
||||
<li><a href="{{route('transactions.withdrawal')}}" title="For when you spend money"><span class="glyphicon glyphicon-arrow-left"></span> Withdrawal</a></li>
|
||||
<li><a href="{{route('transactions.deposit')}}" title="For when you earn money"><span class="glyphicon glyphicon-arrow-right"></span> Deposit</a></li>
|
||||
<li><a href="{{route('transactions.transfer')}}" title="For when you move money around"><span class="glyphicon glyphicon-resize-full"></span> Transfer</a></li>
|
||||
<li><a href="{{route('transactions.create','withdrawal')}}" title="For when you spend money"><span class="glyphicon glyphicon-arrow-left"></span> Withdrawal</a></li>
|
||||
<li><a href="{{route('transactions.create','deposit')}}" title="For when you earn money"><span class="glyphicon glyphicon-arrow-right"></span> Deposit</a></li>
|
||||
<li><a href="{{route('transactions.create','transfer')}}" title="For when you move money around"><span class="glyphicon glyphicon-resize-full"></span> Transfer</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
164
app/views/transactions/create.blade.php
Normal file
164
app/views/transactions/create.blade.php
Normal file
@@ -0,0 +1,164 @@
|
||||
@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 {{$what}}</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">
|
||||
@if($what == 'withdrawal')
|
||||
A withdrawal is when you spend money on something, moving an amount to a <em>beneficiary</em>.
|
||||
@endif
|
||||
@if($what == 'deposit')
|
||||
A deposit is when you earn money, moving an amount from a beneficiary into your own account.
|
||||
@endif
|
||||
@if($what == 'transfer')
|
||||
TRANSFER
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{Form::open(['class' => 'form-horizontal','url' => route('transactions.store',$what)])}}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||
<h4>Mandatory fields</h4>
|
||||
|
||||
<!-- ALWAYS AVAILABLE -->
|
||||
<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>
|
||||
|
||||
<!-- SHOW ACCOUNT (FROM) ONLY FOR WITHDRAWALS AND DEPOSITS -->
|
||||
@if($what == 'deposit' || $what == 'withdrawal')
|
||||
<div class="form-group">
|
||||
<label for="account_id" class="col-sm-4 control-label">
|
||||
@if($what == 'deposit')
|
||||
Receiving account
|
||||
@endif
|
||||
@if($what == 'withdrawal')
|
||||
Paid from account
|
||||
@endif
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
{{Form::select('account_id',$accounts,Input::old('account_id'),['class' => 'form-control'])}}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- SHOW BENEFICIARY (ACCOUNT TO) ONLY FOR WITHDRAWALS AND DEPOSITS -->
|
||||
@if($what == 'deposit' || $what == 'withdrawal')
|
||||
<div class="form-group">
|
||||
<label for="beneficiary" class="col-sm-4 control-label">
|
||||
@if($what == 'deposit')
|
||||
Paying beneficiary
|
||||
@endif
|
||||
@if($what == 'withdrawal')
|
||||
Beneficiary
|
||||
@endif
|
||||
</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>
|
||||
@endif
|
||||
|
||||
<!-- ONLY SHOW FROM/TO ACCOUNT WHEN CREATING TRANSFER -->
|
||||
@if($what == 'transfer')
|
||||
<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>
|
||||
@endif
|
||||
|
||||
<!-- ALWAYS SHOW AMOUNT -->
|
||||
<div class="form-group">
|
||||
<label for="amount" class="col-sm-4 control-label">
|
||||
@if($what == 'withdrawal')
|
||||
Amount spent
|
||||
@endif
|
||||
@if($what == 'deposit')
|
||||
Amount received
|
||||
@endif
|
||||
@if($what == 'transfer')
|
||||
Amount transferred
|
||||
@endif
|
||||
</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>
|
||||
|
||||
<!-- ALWAYS SHOW DATE -->
|
||||
<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>
|
||||
|
||||
<!-- ALWAYS SHOW SUBMit -->
|
||||
<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 {{$what}}" class="btn btn-info" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||
<h4>Optional fields</h4>
|
||||
|
||||
<!-- ONLY WHEN CREATING A WITHDRAWAL -->
|
||||
@if($what == 'withdrawal')
|
||||
<div class="form-group">
|
||||
<label for="budget_id" class="col-sm-4 control-label">Budget</label>
|
||||
<div class="col-sm-8">
|
||||
{{Form::select('budget_id',$budgets,Input::old('budget_id') ?: 0,['class' => 'form-control'])}}
|
||||
<span class="help-block">Select one of your budgets to make this transaction a part of it.</span>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<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
|
98
app/views/transactions/edit.blade.php
Normal file
98
app/views/transactions/edit.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>Edit transaction ""</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
|
@@ -20,7 +20,7 @@
|
||||
@endif
|
||||
|
||||
</td>
|
||||
<td><a href="#">{{{$journal->description}}}</a></td>
|
||||
<td><a href="{{route('transactions.show',$journal->id)}}">{{{$journal->description}}}</a></td>
|
||||
<td>{{$journal->date->format('jS M Y')}}</td>
|
||||
<td>
|
||||
@foreach($journal->transactions as $t)
|
||||
|
77
app/views/transactions/show.blade.php
Normal file
77
app/views/transactions/show.blade.php
Normal file
@@ -0,0 +1,77 @@
|
||||
@extends('layouts.default')
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<h1>Firefly
|
||||
<small>Transaction "{{{$journal->description}}}"</small>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<h3>Metadata</h3>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>Date</td>
|
||||
<td>{{{$journal->date->format('jS F Y')}}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Currency</td>
|
||||
<td>{{{$journal->transactioncurrency->code}}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td>{{{$journal->transactiontype->type}}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Completed</td>
|
||||
<td>
|
||||
@if($journal->completed == 1)
|
||||
<span class="text-success">Yes</span>
|
||||
@else
|
||||
<span class="text-danger">No</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@foreach($journal->components as $component)
|
||||
<tr>
|
||||
<td>{{$component->class}}</td>
|
||||
<td>{{{$component->name}}}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<h3>Transactions</h3>
|
||||
@foreach($journal->transactions as $t)
|
||||
<h4>{{{$t->account->name}}}<br /><small>{{{$t->account->accounttype->description}}}</small></h4>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>Amount</td>
|
||||
<td>{{mf($t->amount)}}</td>
|
||||
</tr>
|
||||
@if(!is_null($t->description))
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>{{{$t->description}}}</td>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
@endforeach
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default" href="{{route('transactions.edit',$journal->id)}}"><span class="glyphicon glyphicon-pencil"></span> Edit</a> <a href="{{route('transactions.delete',$journal->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
||||
@section('scripts')
|
||||
@stop
|
@@ -16,16 +16,37 @@ $(function () {
|
||||
title: {
|
||||
text: obj.data('title')
|
||||
},
|
||||
yAxis: {
|
||||
title: {
|
||||
text: 'Balance (€)'
|
||||
},
|
||||
formatter: function () {
|
||||
return '$' + Highcharts.numberFormat(this.y, 0);
|
||||
}
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
type: 'datetime'
|
||||
floor: 0,
|
||||
type: 'datetime',
|
||||
dateTimeLabelFormats: {
|
||||
month: '%e %b',
|
||||
year: '%b'
|
||||
},
|
||||
title: {
|
||||
text: 'Date'
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
valuePrefix: '€ '
|
||||
valuePrefix: '€ ',
|
||||
formatter: function () {
|
||||
return '€ ' + Highcharts.numberFormat(this.y, 2);
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
|
||||
line: {
|
||||
negativeColor: '#FF0000',
|
||||
threshold: 0,
|
||||
lineWidth: 1,
|
||||
marker: {
|
||||
radius: 2
|
||||
|
Reference in New Issue
Block a user