mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2024-12-27 01:11:37 -06:00
Work on piggy banks [skip ci]
This commit is contained in:
parent
50cfcb8905
commit
706d853b04
26
app/assets/javascripts/firefly/piggybanks.js
Normal file
26
app/assets/javascripts/firefly/piggybanks.js
Normal file
@ -0,0 +1,26 @@
|
||||
$(function () {
|
||||
|
||||
$('input[type="range"]').on('input',inputAmount);
|
||||
$('input[type="range"]').on('change',changeAmount);
|
||||
|
||||
});
|
||||
|
||||
function inputAmount(e) {
|
||||
var target = $(e.target);
|
||||
var piggyBankId = target.attr('name').substring(6);
|
||||
var value = target.val();
|
||||
|
||||
valueFormatted = '€ ' + (Math.round(value * 100) / 100).toFixed(2);;
|
||||
|
||||
console.log(piggyBankId + ': ' + value);
|
||||
|
||||
var valueId = 'piggy_'+piggyBankId+'_amount';
|
||||
$('#' + valueId).text(valueFormatted);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function changeAmount(e) {
|
||||
console.log('Change!');
|
||||
}
|
13
app/assets/javascripts/piggybanks.js
Normal file
13
app/assets/javascripts/piggybanks.js
Normal file
@ -0,0 +1,13 @@
|
||||
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||
// listed below.
|
||||
//
|
||||
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||
// can be referenced here using a relative path.
|
||||
//
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear in whatever order it
|
||||
// gets included (e.g. say you have require_tree . then the code will appear after all the directories
|
||||
// but before any files alphabetically greater than 'application.js'
|
||||
//
|
||||
// The available directives right now are require, require_directory, and require_tree
|
||||
//
|
||||
//= require firefly/piggybanks
|
@ -1,7 +1,30 @@
|
||||
<?php
|
||||
class PiggybankController extends BaseController {
|
||||
|
||||
use Firefly\Storage\Account\AccountRepositoryInterface as ARI;
|
||||
use Firefly\Storage\Piggybank\PiggybankRepositoryInterface as PRI;
|
||||
|
||||
/**
|
||||
* Class PiggybankController
|
||||
*/
|
||||
class PiggybankController extends BaseController
|
||||
{
|
||||
|
||||
protected $_repository;
|
||||
protected $_accounts;
|
||||
|
||||
public function __construct(PRI $repository, ARI $accounts)
|
||||
{
|
||||
$this->_repository = $repository;
|
||||
$this->_accounts = $accounts;
|
||||
View::share('menu', 'home');
|
||||
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$accounts = $this->_accounts->getActiveDefaultAsSelectList();
|
||||
|
||||
return View::make('piggybanks.create')->with('accounts', $accounts);
|
||||
}
|
||||
|
||||
public function delete()
|
||||
@ -18,6 +41,25 @@ class PiggybankController extends BaseController {
|
||||
|
||||
public function index()
|
||||
{
|
||||
$count = $this->_repository->count();
|
||||
$piggybanks = $this->_repository->get();
|
||||
$accounts = [];
|
||||
// get accounts:
|
||||
foreach($piggybanks as $piggyBank) {
|
||||
$account = $piggyBank->account;
|
||||
$id = $account->id;
|
||||
if(!isset($accounts[$id])) {
|
||||
$account->balance = $account->balance();
|
||||
$account->left = $account->balance;
|
||||
} else {
|
||||
$account->left -= $piggyBank->amount;
|
||||
}
|
||||
$accounts[$id] = $account;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return View::make('piggybanks.index')->with('count', $count)->with('accounts',$accounts)->with('piggybanks',$piggybanks);
|
||||
}
|
||||
|
||||
public function show()
|
||||
@ -26,6 +68,15 @@ class PiggybankController extends BaseController {
|
||||
|
||||
public function store()
|
||||
{
|
||||
$piggyBank = $this->_repository->store(Input::all());
|
||||
if(!$piggyBank->id) {
|
||||
Session::flash('error','Could not save piggy bank: ' . $piggyBank->errors()->first());
|
||||
return Redirect::route('piggybanks.create')->withInput();
|
||||
} else {
|
||||
Session::flash('success','New piggy bank created!');
|
||||
return Redirect::route('piggybanks.index');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function update()
|
||||
|
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Storage\Piggybank;
|
||||
|
||||
|
||||
/**
|
||||
* Class EloquentLimitRepository
|
||||
*
|
||||
* @package Firefly\Storage\Limit
|
||||
*/
|
||||
class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
{
|
||||
|
||||
|
||||
public function count()
|
||||
{
|
||||
return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where(
|
||||
'accounts.user_id', \Auth::user()->id
|
||||
)->count();
|
||||
}
|
||||
|
||||
public function find($piggyBankId)
|
||||
{
|
||||
return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where(
|
||||
'accounts.user_id', \Auth::user()->id
|
||||
)->where('piggybanks.id', $piggyBankId)->first('piggybanks.*');
|
||||
}
|
||||
|
||||
public function get()
|
||||
{
|
||||
return \Piggybank::with('account')->leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where(
|
||||
'accounts.user_id', \Auth::user()->id
|
||||
)->get(['piggybanks.*']);
|
||||
}
|
||||
|
||||
public function store($data)
|
||||
{
|
||||
var_dump($data);
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$account = isset($data['account_id']) ? $accounts->find($data['account_id']) : null;
|
||||
|
||||
|
||||
$piggyBank = new \Piggybank;
|
||||
$piggyBank->account()->associate($account);
|
||||
$piggyBank->targetdate
|
||||
= isset($data['targetdate']) && strlen($data['targetdate']) > 0 ? $data['targetdate'] : null;
|
||||
$piggyBank->name = isset($data['name']) ? $data['name'] : null;
|
||||
$piggyBank->amount = 0;
|
||||
$piggyBank->target = floatval($data['target']);
|
||||
$piggyBank->order = 1;
|
||||
if ($piggyBank->validate()) {
|
||||
$piggyBank->save();
|
||||
}
|
||||
|
||||
return $piggyBank;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Storage\Piggybank;
|
||||
|
||||
|
||||
/**
|
||||
* Interface LimitRepositoryInterface
|
||||
*
|
||||
* @package Firefly\Storage\Limit
|
||||
*/
|
||||
interface PiggybankRepositoryInterface
|
||||
{
|
||||
|
||||
public function find($piggyBankId);
|
||||
public function count();
|
||||
public function store($data);
|
||||
public function get();
|
||||
}
|
@ -26,6 +26,11 @@ class StorageServiceProvider extends ServiceProvider
|
||||
'Firefly\Storage\Transaction\EloquentTransactionRepository'
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\Piggybank\PiggybankRepositoryInterface',
|
||||
'Firefly\Storage\Piggybank\EloquentPiggybankRepository'
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
21
app/models/Piggybank.php
Normal file
21
app/models/Piggybank.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
use LaravelBook\Ardent\Ardent as Ardent;
|
||||
|
||||
class Piggybank extends Ardent
|
||||
{
|
||||
public static $rules
|
||||
= [
|
||||
'name' => 'required|between:1,255',
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'targetdate' => 'date',
|
||||
'amount' => 'required|min:0',
|
||||
'target' => 'required|min:1',
|
||||
'order' => 'required:min:1',
|
||||
];
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('Account');
|
||||
}
|
||||
|
||||
}
|
@ -72,6 +72,10 @@ class User extends Ardent implements UserInterface, RemindableInterface
|
||||
return $this->hasMany('Account');
|
||||
}
|
||||
|
||||
public function piggybanks() {
|
||||
return $this->hasMany('Piggybank');
|
||||
}
|
||||
|
||||
public function preferences()
|
||||
{
|
||||
return $this->hasMany('Preference');
|
||||
|
@ -64,6 +64,10 @@ Route::group(['before' => 'auth'], function () {
|
||||
Route::get('/categories/edit/{category}',['uses' => 'CategoryController@edit','as' => 'categories.edit']);
|
||||
Route::get('/categories/delete/{category}',['uses' => 'CategoryController@delete','as' => 'categories.delete']);
|
||||
|
||||
// piggy bank controller
|
||||
Route::get('/piggybanks',['uses' => 'PiggybankController@index','as' => 'piggybanks.index']);
|
||||
Route::get('/piggybanks/create', ['uses' => 'PiggybankController@create','as' => 'piggybanks.create']);
|
||||
|
||||
|
||||
// preferences controller
|
||||
Route::get('/preferences', ['uses' => 'PreferencesController@index', 'as' => 'preferences']);
|
||||
@ -90,6 +94,7 @@ Route::group(['before' => 'auth'], function () {
|
||||
Route::get('/budgets/edit/{budget}',['uses' => 'BudgetController@edit', 'as' => 'budgets.edit']);
|
||||
Route::get('/budgets/delete/{budget}',['uses' => 'BudgetController@delete', 'as' => 'budgets.delete']);
|
||||
|
||||
|
||||
// limit controller:
|
||||
Route::get('/budgets/limits/create/{budget?}',['uses' => 'LimitController@create','as' => 'budgets.limits.create']);
|
||||
Route::get('/budgets/limits/delete/{limit}',['uses' => 'LimitController@delete','as' => 'budgets.limits.delete']);
|
||||
@ -130,6 +135,11 @@ Route::group(['before' => 'csrf|auth'], function () {
|
||||
// migration controller
|
||||
Route::post('/migrate', ['uses' => 'MigrationController@postIndex']);
|
||||
|
||||
// piggy bank controller
|
||||
Route::post('/piggybanks/store',['uses' => 'PiggybankController@store','as' => 'piggybanks.store']);
|
||||
|
||||
|
||||
|
||||
// preferences controller
|
||||
Route::post('/preferences', ['uses' => 'PreferencesController@postIndex']);
|
||||
|
||||
|
@ -29,7 +29,7 @@ $r = Route::current()->getName();
|
||||
<li><a href="{{route('transactions.index')}}"><span class="glyphicon glyphicon-list-alt"></span> Transactions</a></li>
|
||||
|
||||
<li class="divider"></li>
|
||||
<li><a href="#"><span class="glyphicon glyphicon-save"></span> Piggy banks</a></li>
|
||||
<li><a href="{{route('piggybanks.index')}}"><span class="glyphicon glyphicon-save"></span> Piggy banks</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
116
app/views/piggybanks/create.blade.php
Normal file
116
app/views/piggybanks/create.blade.php
Normal file
@ -0,0 +1,116 @@
|
||||
@extends('layouts.default')
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<h1>Firefly
|
||||
<small>Create a new piggy bank</small>
|
||||
</h1>
|
||||
<p class="lead">Create piggy banks to make saving money easier</p>
|
||||
<p class="text-info">
|
||||
Saving money is <em>hard</em>. Piggy banks allow you to group money
|
||||
from an account together. If you also set a target (and a target date) you
|
||||
can save towards your goals.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{Form::open(['class' => 'form-horizontal','url' => route('piggybanks.store')])}}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12 col-sm-6">
|
||||
<h4>Mandatory fields</h4>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-sm-4 control-label">Name</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" name="name" class="form-control" id="name" value="{{Input::old('name')}}" placeholder="Name">
|
||||
@if($errors->has('name'))
|
||||
<p class="text-danger">{{$errors->first('name')}}</p>
|
||||
@else
|
||||
<span class="help-block">For example: new bike, new camera</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{{ Form::label('target', 'Target amount', ['class' => 'col-sm-4 control-label'])}}
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">€</span>
|
||||
{{Form::input('number','target', Input::old('target'), ['step' => 'any', 'min' => '1', 'class' => 'form-control'])}}
|
||||
</div>
|
||||
|
||||
@if($errors->has('target'))
|
||||
<p class="text-danger">{{$errors->first('target')}}</p>
|
||||
@else
|
||||
<span class="help-block">How much money do you need to save?</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="account_id" class="col-sm-4 control-label">
|
||||
Saving account
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
{{Form::select('account_id',$accounts,Input::old('account_id') ?: Input::get('account'),['class' => 'form-control'])}}
|
||||
@if($errors->has('account_id'))
|
||||
<p class="text-danger">{{$errors->first('account_id')}}</p>
|
||||
@else
|
||||
<span class="help-block">Indicate on which account you've got your savings.</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-12 col-sm-6">
|
||||
<h4>Optional fields</h4>
|
||||
|
||||
<div class="form-group">
|
||||
{{ Form::label('targetdate', 'Target date', ['class' => 'col-sm-4 control-label'])}}
|
||||
<div class="col-sm-8">
|
||||
{{ Form::input('date','targetdate', Input::old('targetdate') ?: '', ['class'
|
||||
=> 'form-control']) }}
|
||||
@if($errors->has('targetdate'))
|
||||
<p class="text-danger">{{$errors->first('targetdate')}}</p>
|
||||
@else
|
||||
<span class="help-block">
|
||||
If you want to, set a target date. This will inform you how much money you should save to
|
||||
get to the target amount.
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12 col-sm-6">
|
||||
|
||||
<!-- add another after this one? -->
|
||||
<div class="form-group">
|
||||
<label for="create" class="col-sm-4 control-label"> </label>
|
||||
<div class="col-sm-8">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
{{Form::checkbox('create',1,Input::old('create') == '1')}}
|
||||
Create another (return to this form)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-4 col-sm-8">
|
||||
<button type="submit" class="btn btn-default btn-success">Create the piggy bank</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{Form::close()}}
|
||||
|
||||
|
||||
@stop
|
70
app/views/piggybanks/index.blade.php
Normal file
70
app/views/piggybanks/index.blade.php
Normal file
@ -0,0 +1,70 @@
|
||||
@extends('layouts.default')
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<h1>Firefly
|
||||
<small>Piggy banks</small>
|
||||
</h1>
|
||||
<p class="lead">Set targets and save money</p>
|
||||
<p class="text-info">
|
||||
Saving money is <em>hard</em>. Piggy banks allow you to group money
|
||||
from an account together. If you also set a target (and a target date) you
|
||||
can save towards your goals.
|
||||
</p>
|
||||
@if($count == 0)
|
||||
<p>
|
||||
<a href="{{route('piggybanks.create')}}" class="btn btn-success">Create new piggy bank</a>
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($count > 0)
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<h4>Accounts used for piggy banks</h4>
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Account</th>
|
||||
<th>Current balance</th>
|
||||
<th>Left for (other) piggy banks</th>
|
||||
</tr>
|
||||
@foreach($accounts as $account)
|
||||
<tr>
|
||||
<td>{{{$account->name}}}</td>
|
||||
<td>{{mf($account->balance())}}</td>
|
||||
<td>{{mf($account->left)}}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-6 col-sm-12">
|
||||
<h3>Piggy banks</h3>
|
||||
|
||||
@foreach($piggybanks as $piggybank)
|
||||
<h4>{{{$piggybank->name}}} <small>{{mf($piggybank->target)}}</small></h4>
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<td style="width:10%;"><span id="piggy_{{$piggybank->id}}_amount">{{mf($piggybank->amount,false)}}</span></td>
|
||||
<td><input type="range" name="piggy_{{$piggybank->id}}" min="1" max="{{$piggybank->target}}" step="any" value="{{$piggybank->amount}}" /></td>
|
||||
<td>Y</td>
|
||||
</tr>
|
||||
</table>
|
||||
@endforeach
|
||||
|
||||
|
||||
<p>
|
||||
<a href="{{route('piggybanks.create')}}" class="btn btn-success">Create new piggy bank</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endif
|
||||
@stop
|
||||
@section('scripts')
|
||||
<?php echo javascript_include_tag('piggybanks'); ?>
|
||||
@stop
|
Loading…
Reference in New Issue
Block a user