Some new code, transaction groups among them.

This commit is contained in:
James Cole 2014-11-30 14:52:17 +01:00
parent 3e5f615ffc
commit 0a2cbaa047
13 changed files with 287 additions and 33 deletions

View File

@ -115,8 +115,11 @@ class ReportController extends BaseController
$journals = App::make('FireflyIII\Database\TransactionJournal'); $journals = App::make('FireflyIII\Database\TransactionJournal');
/** @var TransactionJournal $journal */ /** @var TransactionJournal $journal */
$journal = $journals->first(); $journal = $journals->first();
if (is_null($journal)) {
$date = Carbon::now();
} else {
$date = clone $journal->date; $date = clone $journal->date;
}
$years = []; $years = [];
$months = []; $months = [];
while ($date <= Carbon::now()) { while ($date <= Carbon::now()) {
@ -124,7 +127,11 @@ class ReportController extends BaseController
$date->addYear(); $date->addYear();
} }
// months // months
if (is_null($journal)) {
$date = Carbon::now();
} else {
$date = clone $journal->date; $date = clone $journal->date;
}
while ($date <= Carbon::now()) { while ($date <= Carbon::now()) {
$months[] = [ $months[] = [
'formatted' => $date->format('F Y'), 'formatted' => $date->format('F Y'),
@ -182,15 +189,15 @@ class ReportController extends BaseController
} }
); );
/* /*
* Filter transfers: * Filter transfers (not yet used)
*/ */
$transfers = $journals->filter( // $transfers = $journals->filter(
function (TransactionJournal $journal) { // function (TransactionJournal $journal) {
if ($journal->transactionType->type == 'Transfer') { // if ($journal->transactionType->type == 'Transfer') {
return $journal; // return $journal;
} // }
} // }
); // );
/* /*
* Filter withdrawals without a counter-transfer (into this account) * Filter withdrawals without a counter-transfer (into this account)
@ -205,24 +212,22 @@ class ReportController extends BaseController
->where('account_id', '=', $transaction->account_id) ->where('account_id', '=', $transaction->account_id)
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.description', 'LIKE', '%' . e($journal->description) . '%') ->where('transaction_journals.description', 'LIKE', '%' . e($journal->description) . '%')
->count(); ->get(['transactions.*']);
if($counters == 0) { if ($counters->count() == 0) {
return $journal; return $journal;
} }
} }
} }
} }
); );
/* /*
* Filter deposits without a counter-transfer (away from this account) * Filter deposits without a counter-transfer (away from this account)
*/ */
$deposits = $deposits->filter( $deposits = $deposits->filter(
function (TransactionJournal $journal) { function (TransactionJournal $journal) {
echo 'Now at #'.$journal->id.': '.$journal->description.'<br>';
foreach ($journal->transactions as $transaction) { foreach ($journal->transactions as $transaction) {
if (floatval($transaction->amount) < 0) { if (floatval($transaction->amount) > 0) {
$account = $transaction->account; $account = $transaction->account;
// find counter transfer: // find counter transfer:
$counters = $account->transactions()->where('amount', floatval($transaction->amount) * -1) $counters = $account->transactions()->where('amount', floatval($transaction->amount) * -1)
@ -230,21 +235,15 @@ class ReportController extends BaseController
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->where('transaction_journals.description', 'LIKE', '%' . e($journal->description) . '%') ->where('transaction_journals.description', 'LIKE', '%' . e($journal->description) . '%')
->get(['transactions.*']); ->get(['transactions.*']);
/** @var Transaction $transaction */ if ($counters->count() == 0) {
foreach($counters as $transaction) {
echo 'Found possible counter: #'.$transaction->transaction_journal_id.': '.$transaction->transactionJournal->description.'<br>';
}
if($counters->count() == 0) {
return $journal; return $journal;
} }
} }
} }
echo '<br>';
} }
); );
exit;
return View::make('reports.unbalanced', compact('start', 'end', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon', 'withdrawals','deposits')); return View::make('reports.unbalanced', compact('start', 'end', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon', 'withdrawals', 'deposits'));
} }
/** /**
@ -276,7 +275,8 @@ class ReportController extends BaseController
// draw some charts etc. // draw some charts etc.
return View::make('reports.year', compact('summary'))->with('title', 'Reports')->with('mainTitleIcon', 'fa-line-chart')->with('subTitle', $year)->with( return View::make('reports.year', compact('summary', 'date'))->with('title', 'Reports')->with('mainTitleIcon', 'fa-line-chart')->with('subTitle', $year)
->with(
'subTitleIcon', 'fa-bar-chart' 'subTitleIcon', 'fa-bar-chart'
)->with('year', $year); )->with('year', $year);
} }

View File

@ -2,6 +2,7 @@
use FireflyIII\Exception\FireflyException; use FireflyIII\Exception\FireflyException;
use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag; use Illuminate\Support\MessageBag;
/** /**
@ -286,10 +287,27 @@ class TransactionController extends BaseController
break; break;
} }
return View::make('transactions.index', compact('subTitle', 'subTitleIcon', 'journals'))->with('what', $what); return View::make('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'journals'));
} }
public function relate(TransactionJournal $journal)
{
$groups = $journal->transactiongroups()->get();
$members = new Collection;
/** @var TransactionGroup $group */
foreach ($groups as $group) {
/** @var TransactionJournal $jrnl */
foreach ($group->transactionjournals()->get() as $jrnl) {
if ($jrnl->id != $journal->id) {
$members->push($jrnl);
}
}
}
return View::make('transactions.relate', compact('journal', 'members'));
}
/** /**
* @param TransactionJournal $journal * @param TransactionJournal $journal
* *
@ -309,9 +327,18 @@ class TransactionController extends BaseController
$t->after = $t->before + $t->amount; $t->after = $t->before + $t->amount;
} }
); );
$members = new Collection;
/** @var TransactionGroup $group */
foreach($journal->transactiongroups()->get() as $group) {
/** @var TransactionJournal $jrnl */
foreach($group->transactionjournals()->get() as $jrnl) {
if($jrnl->id != $journal->id) {
$members->push($jrnl);
}
}
}
return View::make('transactions.show', compact('journal', 'members'))->with(
return View::make('transactions.show')->with('journal', $journal)->with(
'subTitle', $journal->transactionType->type . ' "' . $journal->description . '"' 'subTitle', $journal->transactionType->type . ' "' . $journal->description . '"'
); );
} }

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
class CacheTable extends Migration
{
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('cache');
}
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(
'cache', function ($table) {
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
}
);
}
}

View File

@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class Transactiongroups extends Migration
{
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('transaction_groups');
}
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(
'transaction_groups', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->integer('user_id')->unsigned();
$table->enum('relation', ['balance']);
// connect reminders to users
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
}
);
}
}

View File

@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class Transactiongroupsjoin extends Migration
{
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schema::drop('transaction_group_transaction_journal');
}
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create(
'transaction_group_transaction_journal', function (Blueprint $table) {
$table->increments('id');
$table->integer('transaction_group_id')->unsigned();
$table->integer('transaction_journal_id')->unsigned();
$table->foreign('transaction_group_id','tr_grp_id')->references('id')->on('transaction_groups')->onDelete('cascade');
$table->foreign('transaction_journal_id','tr_trj_id')->references('id')->on('transaction_journals')->onDelete('cascade');
$table->unique(['transaction_group_id','transaction_journal_id'],'tt_joined');
});
}
}

View File

@ -1,4 +1,5 @@
<?php <?php
use Carbon\Carbon;
use FireflyIII\Shared\SingleTableInheritanceEntity; use FireflyIII\Shared\SingleTableInheritanceEntity;

View File

@ -0,0 +1,38 @@
<?php
use LaravelBook\Ardent\Ardent;
class TransactionGroup extends Ardent
{
public static $rules = [
'relation' => 'required|in:balance'
];
/**
* @return array
*/
public function getDates()
{
return ['created_at', 'updated_at'];
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function transactionjournals()
{
return $this->belongsToMany('TransactionJournal');
}
/**
* User
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('User');
}
}

View File

@ -71,7 +71,6 @@ class TransactionJournal extends Ardent
'date' => 'required|date', 'date' => 'required|date',
'completed' => 'required|between:0,1']; 'completed' => 'required|between:0,1'];
/** /**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/ */
@ -278,4 +277,9 @@ class TransactionJournal extends Ardent
return $this->belongsTo('User'); return $this->belongsTo('User');
} }
public function transactiongroups()
{
return $this->belongsToMany('TransactionGroup');
}
} }

View File

@ -0,0 +1,7 @@
<?php
use Carbon\Carbon;
use LaravelBook\Ardent\Ardent;
class TransactionRelation extends Ardent {
}

View File

@ -255,6 +255,7 @@ Route::group(
Route::get('/transaction/edit/{tj}', ['uses' => 'TransactionController@edit', 'as' => 'transactions.edit']); Route::get('/transaction/edit/{tj}', ['uses' => 'TransactionController@edit', 'as' => 'transactions.edit']);
Route::get('/transaction/delete/{tj}', ['uses' => 'TransactionController@delete', 'as' => 'transactions.delete']); Route::get('/transaction/delete/{tj}', ['uses' => 'TransactionController@delete', 'as' => 'transactions.delete']);
Route::get('/transaction/show/{tj}', ['uses' => 'TransactionController@show', 'as' => 'transactions.show']); Route::get('/transaction/show/{tj}', ['uses' => 'TransactionController@show', 'as' => 'transactions.show']);
Route::get('/transaction/relate/{tj}', ['uses' => 'TransactionController@relate', 'as' => 'transactions.relate']);
// user controller // user controller
Route::get('/logout', ['uses' => 'UserController@logout', 'as' => 'logout']); Route::get('/logout', ['uses' => 'UserController@logout', 'as' => 'logout']);

View File

@ -0,0 +1,18 @@
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">Relate "{{{$journal->description}}}" to other transactions</h4>
</div>
<div class="modal-body">
<h5>Search results</h5>
<h5>Related transactions</h5>
@include('list.journals-tiny',['transactions' => $members])
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>

View File

@ -57,8 +57,34 @@
@include('list.piggybank-events',['events' => $journal->piggybankevents,'showPiggybank' => true]) @include('list.piggybank-events',['events' => $journal->piggybankevents,'showPiggybank' => true])
</div> </div>
</div> </div>
@endif @endif
<div class="panel panel-default">
<div class="panel-heading">
Related transactions
</div>
@if($members->count() == 0)
<div class="panel-body">
<p>
<em>No related transactions</em>
</p>
</div>
@else
<table class="table">
@foreach($members as $jrnl)
<tr>
<td><input type="checkbox" checked="checked" data-id="{{$jrnl->id}}" class="relate-checkbox" /></td>
<td><a href="#">{{{$jrnl->description}}}</a></td>
<td>{{mf($jrnl->getAmount())}}</td>
</tr>
@endforeach
</table>
@endif
<div class="panel-footer">
<p>
<a href="#" id="relateTransaction" data-id="{{$journal->id}}" class="btn btn-default"><i data-id="{{$journal->id}}" class="fa fa-compress"></i> Relate to another transaction</a>
</p>
</div>
</div>
</div> </div>
<div class="col-lg-6 col-md-6 col-sm-12"> <div class="col-lg-6 col-md-6 col-sm-12">
@ -97,8 +123,13 @@
</div> </div>
</div> </div>
</div> </div>
<!-- modal to relate transactions to each other -->
<div class="modal fade" id="relationModal">
</div>
@stop @stop
@section('scripts') @section('scripts')
{{HTML::script('assets/javascript/firefly/transactions.js')}}
@stop @stop

View File

@ -18,4 +18,15 @@ $(document).ready(function () {
if(typeof googleTablePaged != 'undefined') { if(typeof googleTablePaged != 'undefined') {
googleTablePaged('table/transactions/' + what,'transaction-table'); googleTablePaged('table/transactions/' + what,'transaction-table');
} }
if($('#relateTransaction').length == 1) {
$('#relateTransaction').click(relateTransaction);
}
}); });
function relateTransaction(e) {
var target = $(e.target);
var ID = target.data('id');
$('#relationModal').empty().load('transaction/relate/' + ID).modal('show');
return false;
}