Added the ability to manually add or remove money from piggy banks (issue #6) [skip ci]

This commit is contained in:
James Cole
2014-08-17 08:45:22 +02:00
parent d645a38aec
commit e4f04583a3
10 changed files with 245 additions and 32 deletions

View File

@@ -1,6 +1,6 @@
<?php
use Carbon\Carbon;
use Firefly\Exception\FireflyException;
use Firefly\Storage\Account\AccountRepositoryInterface as ARI;
use Firefly\Storage\Piggybank\PiggybankRepositoryInterface as PRI;
@@ -24,6 +24,20 @@ class PiggybankController extends BaseController
$this->_accounts = $accounts;
}
/**
* @param Piggybank $piggyBank
*/
public function addMoney(Piggybank $piggyBank)
{
$what = 'add';
$maxAdd = $this->_repository->leftOnAccount($piggyBank->account);
$maxRemove = null;
return View::make('piggybanks.modifyAmount')->with('what', $what)->with('maxAdd', $maxAdd)->with(
'maxRemove', $maxRemove
)->with('piggybank', $piggyBank);
}
/**
* @return $this
*/
@@ -46,7 +60,6 @@ class PiggybankController extends BaseController
return View::make('piggybanks.create-repeated')->with('accounts', $accounts)->with('periods', $periods);
}
/**
* @param Piggybank $piggyBank
*
@@ -101,11 +114,57 @@ class PiggybankController extends BaseController
$countNonRepeating = $this->_repository->countNonrepeating();
$piggybanks = $this->_repository->get();
return View::make('piggybanks.index')->with('piggybanks', $piggybanks)
->with('countRepeating', $countRepeating)
->with('countNonRepeating', $countNonRepeating);
}
/**
* @param Piggybank $piggyBank
*/
public function modMoney(Piggybank $piggyBank)
{
var_dump(Input::all());
$amount = floatval(Input::get('amount'));
switch (Input::get('what')) {
default:
throw new FireflyException('No such action');
break;
case 'add':
$maxAdd = $this->_repository->leftOnAccount($piggyBank->account);
if ($amount <= min($maxAdd, $piggyBank->targetamount)) {
Session::flash('success','Amount updated!');
$this->_repository->modifyAmount($piggyBank, $amount);
} else {
Session::flash('warning','Could not!');
}
break;
case 'remove':
$maxRemove = $piggyBank->currentRelevantRep()->currentamount;
if($amount <= $maxRemove) {
$this->_repository->modifyAmount($piggyBank, ($amount * -1));
}
break;
}
return Redirect::route('piggybanks.index');
}
/**
* @param Piggybank $piggyBank
*/
public function removeMoney(Piggybank $piggyBank)
{
$what = 'remove';
$maxAdd = $this->_repository->leftOnAccount($piggyBank->account);
$maxRemove = $piggyBank->currentRelevantRep()->currentamount;
return View::make('piggybanks.modifyAmount')->with('what', $what)->with('maxAdd', $maxAdd)->with(
'maxRemove', $maxRemove
)->with('piggybank', $piggyBank);
}
/**
*
*/

View File

@@ -69,7 +69,51 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
*/
public function get()
{
return \Auth::user()->piggybanks()->with(['account', 'piggybankrepetitions'])->get();
$piggies = \Auth::user()->piggybanks()->with(['account', 'piggybankrepetitions'])->get();
foreach($piggies as $pig) {
$pig->leftInAccount = $this->leftOnAccount($pig->account);
}
return $piggies;
}
/**
* @param \Account $account
*
* @return mixed|void
*/
public function leftOnAccount(\Account $account)
{
$balance = $account->balance();
/** @var \Piggybank $p */
foreach ($account->piggybanks()->get() as $p) {
$balance -= $p->currentRelevantRep()->currentamount;
}
return $balance;
}
/**
* @param \Piggybank $piggyBank
* @param $amount
*
* @return bool|mixed
*/
public function modifyAmount(\Piggybank $piggyBank, $amount)
{
$rep = $piggyBank->currentRelevantRep();
\Log::debug('Amount before: ' . $rep->currentamount);
$rep->currentamount += $amount;
\Log::debug('Amount after: ' . $rep->currentamount);
\Log::debug('validates: ' . $rep->validate());
\Log::debug(print_r($rep->toArray(),true));
$rep->save();
return true;
}
/**
@@ -182,18 +226,4 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
}
/**
* @param \Piggybank $piggyBank
* @param $amount
*
* @return mixed|void
*/
public function updateAmount(\Piggybank $piggyBank, $amount)
{
$piggyBank->amount = floatval($amount);
if ($piggyBank->validate()) {
$piggyBank->save();
}
}
}

View File

@@ -45,6 +45,23 @@ interface PiggybankRepositoryInterface
*/
public function get();
/**
* Will tell you how much money is left on this account.
*
* @param \Account $account
*
* @return mixed
*/
public function leftOnAccount(\Account $account);
/**
* @param \Piggybank $piggyBank
* @param $amount
*
* @return mixed
*/
public function modifyAmount(\Piggybank $piggyBank, $amount);
/**
* @param $data
*
@@ -60,12 +77,5 @@ interface PiggybankRepositoryInterface
*/
public function update(\Piggybank $piggy, $data);
/**
* @param \Piggybank $piggyBank
* @param $amount
*
* @return mixed
*/
public function updateAmount(\Piggybank $piggyBank, $amount);
}

View File

@@ -52,12 +52,15 @@ class EloquentPiggybankTrigger
$reps = $piggy->piggybankrepetitions()->get();
/** @var \PiggybankRepetition $rep */
foreach ($reps as $rep) {
$sum = \Transaction::where('piggybank_id', $piggy->id)->leftJoin(
if ($rep->currentamount == 0) {
$sum = \Transaction::where('piggybank_id', $piggy->id)->leftJoin(
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
)->where('transaction_journals.date', '>=', $rep->startdate->format('Y-m-d'))->where(
'transaction_journals.date', '<=', $rep->targetdate->format('Y-m-d')
)->sum('transactions.amount');
$rep->currentamount = floatval($sum);
'transaction_journals.date', '<=', $rep->targetdate->format('Y-m-d')
)->sum('transactions.amount');
$rep->currentamount = floatval($sum);
}
$rep->save();

View File

@@ -92,6 +92,14 @@ class Account extends Ardent
return $this->hasMany('Transaction');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function piggybanks()
{
return $this->hasMany('Piggybank');
}
/**
* @param \Carbon\Carbon $date
*

View File

@@ -177,6 +177,8 @@ class Piggybank extends Ardent
/**
* Grabs the PiggyBankRepetition that's currently relevant / active
*
* @returns \PiggybankRepetition
*/
public function currentRelevantRep() {
return $this->piggybankrepetitions()

View File

@@ -137,6 +137,10 @@ Route::group(['before' => 'auth'], function () {
Route::get('/piggybanks',['uses' => 'PiggybankController@index','as' => 'piggybanks.index']);
Route::get('/piggybanks/create/piggybank', ['uses' => 'PiggybankController@createPiggybank','as' => 'piggybanks.create.piggybank']);
Route::get('/piggybanks/create/repeated', ['uses' => 'PiggybankController@createRepeated','as' => 'piggybanks.create.repeated']);
Route::get('/piggybanks/addMoney/{piggybank}', ['uses' => 'PiggybankController@addMoney','as' => 'piggybanks.amount.add']);
Route::get('/piggybanks/removeMoney/{piggybank}', ['uses' => 'PiggybankController@removeMoney','as' => 'piggybanks.amount.remove']);
Route::get('/piggybanks/show/{piggybank}', ['uses' => 'PiggybankController@show','as' => 'piggybanks.show']);
Route::get('/piggybanks/edit/{piggybank}', ['uses' => 'PiggybankController@edit','as' => 'piggybanks.edit']);
Route::get('/piggybanks/delete/{piggybank}', ['uses' => 'PiggybankController@delete','as' => 'piggybanks.delete']);
@@ -204,6 +208,8 @@ Route::group(['before' => 'csrf|auth'], function () {
Route::post('/piggybanks/store/repeated',['uses' => 'PiggybankController@storeRepeated','as' => 'piggybanks.store.repeated']);
Route::post('/piggybanks/update/{piggybank}', ['uses' => 'PiggybankController@update','as' => 'piggybanks.update']);
Route::post('/piggybanks/destroy/{piggybank}', ['uses' => 'PiggybankController@destroy','as' => 'piggybanks.destroy']);
Route::post('/piggybanks/mod/{piggybank}', ['uses' => 'PiggybankController@modMoney','as' => 'piggybanks.modMoney']);
// preferences controller
Route::post('/preferences', ['uses' => 'PreferencesController@postIndex']);

View File

@@ -66,9 +66,17 @@
@endif
</p>
<div class="btn-group-xs btn-group">
<div class="btn-group-sm btn-group">
<a href="{{route('piggybanks.edit',$piggyBank->id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
@if($piggyBank->leftInAccount > 0)
<a data-toggle="modal" href="{{route('piggybanks.amount.add',$piggyBank->id)}}" data-target="#modal" class="btn btn-default"><span class="glyphicon glyphicon-plus-sign"></span> Add money</a>
@endif
@if($piggyBank->currentRelevantRep()->currentamount > 0)
<a data-toggle="modal" href="{{route('piggybanks.amount.remove',$piggyBank->id)}}" data-target="#modal" class="btn btn-default"><span class="glyphicon glyphicon-minus-sign"></span> Remove money</a>
@endif
<a href="{{route('piggybanks.delete',$piggyBank->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
</div>
</td>
</tr>
@@ -114,9 +122,16 @@
</p>
<div class="btn-group-xs btn-group">
<a href="{{route('piggybanks.edit',$repeated->id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
<a href="{{route('piggybanks.delete',$repeated->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
<div class="btn-group btn-group-sm">
<a href="{{route('piggybanks.edit',$piggyBank->id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
@if($piggyBank->leftInAccount > 0)
<a data-toggle="modal" href="{{route('piggybanks.amount.add',$piggyBank->id)}}" data-target="#modal" class="btn btn-default"><span class="glyphicon glyphicon-plus-sign"></span> Add money</a>
@endif
@if($piggyBank->currentRelevantRep()->currentamount > 0)
<a data-toggle="modal" href="{{route('piggybanks.amount.remove',$piggyBank->id)}}" data-target="#modal" class="btn btn-default"><span class="glyphicon glyphicon-minus-sign"></span> Remove money</a>
@endif
<a href="{{route('piggybanks.delete',$piggyBank->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
</div>
</td></tr>
@endif
@@ -125,6 +140,18 @@
@endif
</div>
</div>
<!-- MODAL -->
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
@stop
@section('scripts')
<?php echo javascript_include_tag('piggybanks'); ?>

View File

@@ -0,0 +1,62 @@
<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">
@if($what == 'add')
Add money to "{{{$piggybank->name}}}"
@else
Remove money from "{{{$piggybank->name}}}"
@endif
</h4>
</div>
<form style="display: inline;" action="{{route('piggybanks.modMoney',$piggybank->id)}}" method="POST">
<input type="hidden" name="what" value="{{$what}}" />
{{Form::token()}}
<div class="modal-body">
<p class="text-info">
@if($what == 'add')
Usually you would add money to this
@if($piggybank->repeated == 1)
repeated expense
@else
piggy bank
@endif
by transferring it from one of your accounts to "{{{$piggybank->account->name}}}". However,
since there is still {{mf($maxAdd)}} on that account not locked in any piggy bank or repeated expense,
you can also add it manually.
@else
If you need the money in this
@if($piggybank->repeated == 1)
repeated expense
@else
piggy bank
@endif
for something else, you can opt to remove it using this form. Since there is {{mf($maxRemove)}} in this
@if($piggybank->repeated == 1)
repeated expense
@else
piggy bank
@endif
that is the maximum amount of money you can remove using this form.
@endif
</p>
<div class="form-group">
<label for="amount">Amount to {{$what}}</label>
<div class="input-group">
<div class="input-group-addon">&euro;</div>
@if($what == 'add')
<input type="number" step="any" max="{{min($maxAdd,$piggybank->targetamount)}}" min="0.01" class="form-control" id="amount" name="amount">
@else
<input type="number" step="any" max="{{$maxRemove}}" min="0.01" class="form-control" id="amount" name="amount">
@endif
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-primary" value="Submit" name="submit" />
</div>
</form>

View File

@@ -5,6 +5,12 @@
<h1>Firefly
<small>Piggy bank "{{{$piggyBank->name}}}"</small>
</h1>
<p>
<a href="{{route('accounts.show',$piggyBank->account_id)}}">{{{$piggyBank->account->name}}}</a> has
a balance of {{mf($piggyBank->account->balance())}}.
Of that {{mf($piggyBank->account->balance())}}, you have {{mf(0)}} not yet locked up in other piggy banks.
You can add {{mf(max(0,1))}} to this piggy bank.
</p>
</div>
</div>
<div class="row">