mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Piggy banks
This commit is contained in:
parent
f2eae2fc98
commit
c0f96aa948
@ -1,23 +1,30 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use View;
|
||||
use Amount;
|
||||
use Auth;
|
||||
use Illuminate\Support\Collection;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\PiggyBankFormRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use Steam;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class PiggyBankController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class PiggyBankController extends Controller {
|
||||
class PiggyBankController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
@ -28,6 +35,102 @@ class PiggyBankController extends Controller {
|
||||
View::share('mainTitleIcon', 'fa-sort-amount-asc');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add money to piggy bank
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function add(PiggyBank $piggyBank, AccountRepositoryInterface $repository)
|
||||
{
|
||||
$leftOnAccount = $repository->leftOnAccount($piggyBank->account);
|
||||
$savedSoFar = $piggyBank->currentRelevantRep()->currentamount;
|
||||
$leftToSave = $piggyBank->targetamount - $savedSoFar;
|
||||
$maxAmount = min($leftOnAccount, $leftToSave);
|
||||
|
||||
|
||||
\Log::debug('Now going to view for piggy bank #' . $piggyBank->id . ' (' . $piggyBank->name . ')');
|
||||
|
||||
return View::make('piggy-banks.add', compact('piggyBank', 'maxAmount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = ExpandedForm::makeSelectList(Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']));
|
||||
$subTitle = 'Create new piggy bank';
|
||||
$subTitleIcon = 'fa-plus';
|
||||
|
||||
return View::make('piggy-banks.create', compact('accounts', 'periods', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function delete(PiggyBank $piggyBank)
|
||||
{
|
||||
$subTitle = 'Delete "' . e($piggyBank->name) . '"';
|
||||
|
||||
return View::make('piggy_banks.delete', compact('piggyBank', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(PiggyBank $piggyBank)
|
||||
{
|
||||
|
||||
Session::flash('success', 'Piggy bank "' . e($piggyBank->name) . '" deleted.');
|
||||
$this->_repository->destroy($piggyBank);
|
||||
|
||||
return Redirect::route('piggy_banks.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function edit(PiggyBank $piggyBank)
|
||||
{
|
||||
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = ExpandedForm::makeSelectList(Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']));
|
||||
$subTitle = 'Edit piggy bank "' . e($piggyBank->name) . '"';
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
|
||||
/*
|
||||
* Flash some data to fill the form.
|
||||
*/
|
||||
if (is_null($piggyBank->targetdate) || $piggyBank->targetdate == '') {
|
||||
$targetDate = null;
|
||||
} else {
|
||||
$targetDate = new Carbon($piggyBank->targetdate);
|
||||
$targetDate = $targetDate->format('Y-m-d');
|
||||
}
|
||||
$preFilled = ['name' => $piggyBank->name,
|
||||
'account_id' => $piggyBank->account_id,
|
||||
'targetamount' => $piggyBank->targetamount,
|
||||
'targetdate' => $targetDate,
|
||||
'reminder' => $piggyBank->reminder,
|
||||
'remind_me' => intval($piggyBank->remind_me) == 1 || !is_null($piggyBank->reminder) ? true : false
|
||||
];
|
||||
Session::flash('preFilled', $preFilled);
|
||||
|
||||
return View::make('piggy-banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'accounts', 'periods', 'preFilled'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
@ -35,7 +138,7 @@ class PiggyBankController extends Controller {
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
{
|
||||
/** @var Collection $piggyBanks */
|
||||
$piggyBanks = Auth::user()->piggyBanks()->where('repeats',0)->get();
|
||||
$piggyBanks = Auth::user()->piggyBanks()->where('repeats', 0)->get();
|
||||
|
||||
$accounts = [];
|
||||
/** @var PiggyBank $piggyBank */
|
||||
@ -68,5 +171,149 @@ class PiggyBankController extends Controller {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* POST add money to piggy bank
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postAdd(PiggyBank $piggyBank, PiggyBankRepositoryInterface $repository, AccountRepositoryInterface $accounts)
|
||||
{
|
||||
$amount = round(floatval(Input::get('amount')), 2);
|
||||
$leftOnAccount = $accounts->leftOnAccount($piggyBank->account);
|
||||
$savedSoFar = $piggyBank->currentRelevantRep()->currentamount;
|
||||
$leftToSave = $piggyBank->targetamount - $savedSoFar;
|
||||
$maxAmount = round(min($leftOnAccount, $leftToSave), 2);
|
||||
|
||||
if ($amount <= $maxAmount) {
|
||||
$repetition = $piggyBank->currentRelevantRep();
|
||||
$repetition->currentamount += $amount;
|
||||
$repetition->save();
|
||||
|
||||
/*
|
||||
* Create event!
|
||||
*/
|
||||
//Event::fire('piggy_bank.addMoney', [$piggyBank, $amount]); // new and used.
|
||||
|
||||
Session::flash('success', 'Added ' . Amount::format($amount, false) . ' to "' . e($piggyBank->name) . '".');
|
||||
} else {
|
||||
Session::flash('error', 'Could not add ' . Amount::format($amount, false) . ' to "' . e($piggyBank->name) . '".');
|
||||
}
|
||||
|
||||
return Redirect::route('piggy-banks.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postRemove(PiggyBank $piggyBank)
|
||||
{
|
||||
$amount = floatval(Input::get('amount'));
|
||||
|
||||
$savedSoFar = $piggyBank->currentRelevantRep()->currentamount;
|
||||
|
||||
if ($amount <= $savedSoFar) {
|
||||
$repetition = $piggyBank->currentRelevantRep();
|
||||
$repetition->currentamount -= $amount;
|
||||
$repetition->save();
|
||||
|
||||
/*
|
||||
* Create event!
|
||||
*/
|
||||
//Event::fire('piggy_bank.removeMoney', [$piggyBank, $amount]); // new and used.
|
||||
|
||||
Session::flash('success', 'Removed ' . Amount::format($amount, false) . ' from "' . e($piggyBank->name) . '".');
|
||||
} else {
|
||||
Session::flash('error', 'Could not remove ' . Amount::format($amount, false) . ' from "' . e($piggyBank->name) . '".');
|
||||
}
|
||||
|
||||
return Redirect::route('piggy-banks.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @SuppressWarnings("Unused")
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function remove(PiggyBank $piggyBank)
|
||||
{
|
||||
return View::make('piggy-banks.remove', compact('piggyBank'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function show(PiggyBank $piggyBank)
|
||||
{
|
||||
|
||||
$events = $piggyBank->piggyBankEvents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->get();
|
||||
|
||||
/*
|
||||
* Number of reminders:
|
||||
*/
|
||||
|
||||
$subTitle = e($piggyBank->name);
|
||||
|
||||
return View::make('piggy-banks.show', compact('piggyBank', 'events', 'subTitle'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function store(PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository)
|
||||
{
|
||||
$piggyBankData = [
|
||||
'repeats' => false,
|
||||
'name' => $request->get('name'),
|
||||
'startdate' => new Carbon,
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'targetamount' => floatval($request->get('targetamount')),
|
||||
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
||||
'reminder' => $request->get('reminder'),
|
||||
];
|
||||
|
||||
$piggyBank = $repository->store($piggyBankData);
|
||||
|
||||
Session::flash('success', 'Stored piggy bank "' . e($piggyBank->name) . '".');
|
||||
|
||||
return Redirect::route('piggy-banks.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function update(PiggyBank $piggyBank, PiggyBankRepositoryInterface $repository, PiggyBankFormRequest $request)
|
||||
{
|
||||
$piggyBankData = [
|
||||
'repeats' => false,
|
||||
'name' => $request->get('name'),
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'targetamount' => floatval($request->get('targetamount')),
|
||||
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
||||
'reminder' => $request->get('reminder'),
|
||||
];
|
||||
|
||||
$piggyBank = $repository->update($piggyBank, $piggyBankData);
|
||||
|
||||
Session::flash('success', 'Updated piggy bank "' . e($piggyBank->name) . '".');
|
||||
|
||||
return Redirect::route('piggy-banks.index');
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
55
app/Http/Requests/PiggyBankFormRequest.php
Normal file
55
app/Http/Requests/PiggyBankFormRequest.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class PiggyBankFormRequest
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class PiggyBankFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$nameRule = 'required|between:1,255|uniqueForUser:piggy_banks,name';
|
||||
if (intval(Input::get('id'))) {
|
||||
$nameRule = 'required|between:1,255';
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'account_id' => 'required|belongsToUser:accounts',
|
||||
'name' => $nameRule,
|
||||
'targetamount' => 'required|min:0.01',
|
||||
'startdate' => 'date',
|
||||
'targetdate' => 'date',
|
||||
'repeats' => 'required|boolean',
|
||||
'rep_length' => 'in:day,week,quarter,month,year',
|
||||
'rep_every' => 'integer|min:0|max:31',
|
||||
'rep_times' => 'integer|min:0|max:99',
|
||||
'reminder' => 'in:day,week,quarter,month,year',
|
||||
'reminder_skip' => 'integer|min:0|max:99',
|
||||
'remind_me' => 'boolean',
|
||||
'order' => 'integer|min:1',
|
||||
|
||||
];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
|
||||
|
||||
// models
|
||||
@ -65,6 +66,20 @@ Route::bind(
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'piggyBank', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return PiggyBank::
|
||||
where('piggy_banks.id', $value)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
|
||||
->where('accounts.user_id', Auth::user()->id)
|
||||
->where('repeats', 0)->first(['piggy_banks.*']);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'category', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
@ -169,6 +184,7 @@ Route::group(
|
||||
Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']);
|
||||
Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']);
|
||||
Route::get('/chart/bills/{bill}', ['uses' => 'GoogleChartController@billOverview']);
|
||||
Route::get('/chart/piggy-history/{piggyBank}', ['uses' => 'GoogleChartController@piggyBankHistory']);
|
||||
|
||||
/**
|
||||
* Help Controller
|
||||
@ -193,6 +209,11 @@ Route::group(
|
||||
Route::get('/piggy-banks/edit/{piggyBank}', ['uses' => 'PiggyBankController@edit', 'as' => 'piggy-banks.edit']);
|
||||
Route::get('/piggy-banks/delete/{piggyBank}', ['uses' => 'PiggyBankController@delete', 'as' => 'piggy-banks.delete']);
|
||||
Route::get('/piggy-banks/show/{piggyBank}', ['uses' => 'PiggyBankController@show', 'as' => 'piggy-banks.show']);
|
||||
Route::post('/piggy-banks/store', ['uses' => 'PiggyBankController@store', 'as' => 'piggy-banks.store']);
|
||||
Route::post('/piggy-banks/update/{piggyBank}', ['uses' => 'PiggyBankController@update', 'as' => 'piggy-banks.update']);
|
||||
Route::post('/piggy-banks/destroy/{piggyBank}', ['uses' => 'PiggyBankController@destroy', 'as' => 'piggy-banks.destroy']);
|
||||
Route::post('/piggy-banks/add/{piggyBank}', ['uses' => 'PiggyBankController@postAdd', 'as' => 'piggy-banks.add']); # add money
|
||||
Route::post('/piggy-banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@postRemove', 'as' => 'piggy-banks.remove']); # remove money.
|
||||
|
||||
/**
|
||||
* Preferences Controller
|
||||
|
@ -14,6 +14,8 @@ class PiggyBank extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = ['repeats', 'name', 'account_id', 'targetamount','startdate', 'targetdate', 'reminder',];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
@ -22,38 +24,6 @@ class PiggyBank extends Model
|
||||
return $this->belongsTo('FireflyIII\Models\Account');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at', 'deleted_at', 'startdate', 'targetdate'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function piggyBankEvents()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\PiggyBankEvent');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function piggyBankRepetitions()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\PiggyBankRepetition');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||
*/
|
||||
public function reminders()
|
||||
{
|
||||
return $this->morphMany('FireflyIII\Models\Reminder', 'remindersable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the PiggyBankRepetition that's currently relevant / active
|
||||
*
|
||||
@ -70,7 +40,7 @@ class PiggyBank extends Model
|
||||
|
||||
return $rep;
|
||||
} else {
|
||||
$query = $this->piggyBankRepetitions()->where(
|
||||
$query = $this->piggyBankRepetitions()->where(
|
||||
function (EloquentBuilder $q) {
|
||||
|
||||
$q->where(
|
||||
@ -100,7 +70,7 @@ class PiggyBank extends Model
|
||||
|
||||
}
|
||||
)->orderBy('startdate', 'ASC');
|
||||
$result = $query->first(['piggy_bank_repetitions.*']);
|
||||
$result = $query->first(['piggy_bank_repetitions.*']);
|
||||
$this->currentRep = $result;
|
||||
|
||||
return $result;
|
||||
@ -108,4 +78,36 @@ class PiggyBank extends Model
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function piggyBankRepetitions()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\PiggyBankRepetition');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at', 'deleted_at', 'startdate', 'targetdate'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function piggyBankEvents()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\PiggyBankEvent');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||
*/
|
||||
public function reminders()
|
||||
{
|
||||
return $this->morphMany('FireflyIII\Models\Reminder', 'remindersable');
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Support\Facades\Navigation;
|
||||
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
|
||||
use Illuminate\Database\QueryException;
|
||||
@ -66,6 +68,15 @@ class EventServiceProvider extends ServiceProvider
|
||||
}
|
||||
);
|
||||
|
||||
PiggyBank::created(function(PiggyBank $piggyBank) {
|
||||
$repetition = new PiggyBankRepetition;
|
||||
$repetition->piggyBank()->associate($piggyBank);
|
||||
$repetition->startdate = $piggyBank->startdate;
|
||||
$repetition->targetdate = $piggyBank->targetdate;
|
||||
$repetition->currentamount = 0;
|
||||
$repetition->save();
|
||||
});
|
||||
|
||||
BudgetLimit::saved(
|
||||
function (BudgetLimit $budgetLimit) {
|
||||
|
||||
|
@ -61,6 +61,7 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
$this->app->bind('FireflyIII\Repositories\Category\CategoryRepositoryInterface', 'FireflyIII\Repositories\Category\CategoryRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Journal\JournalRepositoryInterface', 'FireflyIII\Repositories\Journal\JournalRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Bill\BillRepositoryInterface', 'FireflyIII\Repositories\Bill\BillRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface', 'FireflyIII\Repositories\PiggyBank\PiggyBankRepository');
|
||||
|
||||
$this->app->bind('FireflyIII\Helpers\Report\ReportHelperInterface', 'FireflyIII\Helpers\Report\ReportHelper');
|
||||
$this->app->bind('FireflyIII\Helpers\Report\ReportQueryInterface', 'FireflyIII\Helpers\Report\ReportQuery');
|
||||
|
56
app/Repositories/PiggyBank/PiggyBankRepository.php
Normal file
56
app/Repositories/PiggyBank/PiggyBankRepository.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\PiggyBank;
|
||||
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
|
||||
/**
|
||||
* Class PiggyBankRepository
|
||||
*
|
||||
* @package FireflyIII\Repositories\PiggyBank
|
||||
*/
|
||||
class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
|
||||
$piggyBank = PiggyBank::create(
|
||||
[
|
||||
|
||||
'repeats' => $data['repeats'],
|
||||
'name' => $data['name'],
|
||||
'account_id' => $data['account_id'],
|
||||
'targetamount' => $data['targetamount'],
|
||||
'startdate' => $data['startdate'],
|
||||
'targetdate' => $data['targetdate'],
|
||||
'reminder' => $data['reminder'],
|
||||
]
|
||||
);
|
||||
|
||||
return $piggyBank;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $account
|
||||
* @param array $data
|
||||
*
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function update(PiggyBank $piggyBank, array $data)
|
||||
{
|
||||
|
||||
$piggyBank->name = $data['name'];
|
||||
$piggyBank->account_id = intval($data['account_id']);
|
||||
$piggyBank->targetamount = floatval($data['targetamount']);
|
||||
$piggyBank->targetdate = $data['targetdate'];
|
||||
$piggyBank->reminder = $data['reminder'];
|
||||
$piggyBank->save();
|
||||
return $piggyBank;
|
||||
}
|
||||
}
|
29
app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php
Normal file
29
app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\PiggyBank;
|
||||
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
|
||||
/**
|
||||
* Interface PiggyBankRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\PiggyBank
|
||||
*/
|
||||
interface PiggyBankRepositoryInterface {
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function store(array $data);
|
||||
|
||||
/**
|
||||
* @param PiggyBank $account
|
||||
* @param array $data
|
||||
*
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function update(PiggyBank $piggyBank, array $data);
|
||||
}
|
33
resources/views/list/piggy-bank-events.blade.php
Normal file
33
resources/views/list/piggy-bank-events.blade.php
Normal file
@ -0,0 +1,33 @@
|
||||
<table class="table table-bordered table-striped">
|
||||
<tr>
|
||||
@if(isset($showPiggyBank) && $showPiggyBank === true)
|
||||
<th>Piggy bank</th>
|
||||
@endif
|
||||
<th>Date</th>
|
||||
<th>Amount</th>
|
||||
</tr>
|
||||
@foreach($events as $event)
|
||||
<tr>
|
||||
@if(isset($showPiggyBank) && $showPiggyBank === true)
|
||||
<td>
|
||||
<a href="{{route('piggyBanks.show',$event->piggyBank_id)}}">{{{$event->piggyBank->name}}}</a>
|
||||
</td>
|
||||
@endif
|
||||
<td>
|
||||
@if(!is_null($event->transaction_journal_id))
|
||||
<a href="{{route('transactions.show',$event->transaction_journal_id)}}" title="{{{$event->transactionJournal->description}}}">{{$event->date->format('j F Y')}}</a>
|
||||
@else
|
||||
{{$event->date->format('j F Y')}}
|
||||
@endif
|
||||
</td>
|
||||
|
||||
<td>
|
||||
@if($event->amount < 0)
|
||||
<span class="text-danger">Removed {{Amount::format($event->amount*-1,false)}}</span>
|
||||
@else
|
||||
<span class="text-success">Added {{Amount::format($event->amount,false)}}</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
@ -1,5 +1,5 @@
|
||||
<form style="display: inline;" id="add" action="{{route('piggy-banks.add',$piggyBank->id)}}" method="POST">
|
||||
{{Form::token()}}
|
||||
{!! Form::token() !!}
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
The maximum amount you can add is {{Amount::format($maxAmount)}}
|
||||
The maximum amount you can add is {!! Amount::format($maxAmount) !!}
|
||||
</p>
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">€</div>
|
||||
|
@ -1,7 +1,9 @@
|
||||
@extends('layouts.default')
|
||||
@section('content')
|
||||
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName()) }}
|
||||
{{Form::open(['class' => 'form-horizontal','id' => 'store','url' => route('piggy-banks.store')])}}
|
||||
{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName()) !!}
|
||||
{!! Form::open(['class' => 'form-horizontal','id' => 'store','url' => route('piggy-banks.store')]) !!}
|
||||
|
||||
<input type="hidden" name="repeats" value="0" />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12 col-sm-6">
|
||||
@ -10,9 +12,10 @@
|
||||
<i class="fa fa-fw fa-exclamation"></i> Mandatory fields
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{Form::ffText('name')}}
|
||||
{{Form::ffSelect('account_id',$accounts,null,['label' => 'Save on account'])}}
|
||||
{{Form::ffAmount('targetamount')}}
|
||||
|
||||
{!! ExpandedForm::text('name') !!}
|
||||
{!! ExpandedForm::select('account_id',$accounts,null,['label' => 'Save on account']) !!}
|
||||
{!! ExpandedForm::amount('targetamount') !!}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@ -29,9 +32,9 @@
|
||||
<i class="fa fa-smile-o"></i> Optional fields
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{Form::ffDate('targetdate')}}
|
||||
{{Form::ffCheckbox('remind_me','1',false,['label' => 'Remind me'])}}
|
||||
{{Form::ffSelect('reminder',$periods,'month',['label' => 'Remind every'])}}
|
||||
{!! ExpandedForm::date('targetdate') !!}
|
||||
{!! ExpandedForm::checkbox('remind_me','1',false,['label' => 'Remind me']) !!}
|
||||
{!! ExpandedForm::select('reminder',$periods,'month',['label' => 'Remind every']) !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -41,54 +44,12 @@
|
||||
<i class="fa fa-bolt"></i> Options
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{Form::ffOptionsList('create','piggy bank')}}
|
||||
{!! ExpandedForm::optionsList('create','piggy bank') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{--
|
||||
|
||||
<h4>Mandatory fields</h4>
|
||||
|
||||
<h4>Optional fields</h4>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
{{ Form::label('reminder', 'Remind you every', ['class' => 'col-sm-4 control-label'])}}
|
||||
<div class="col-sm-8">
|
||||
<input type="number" step="1" min="1" value="{{Input::old('reminder_skip') ?: 1}}" style="width:50px;display:inline;" max="100" name="reminder_skip" class="form-control" />
|
||||
|
||||
<select class="form-control" name="reminder" style="width:150px;display: inline">
|
||||
<option value="none" label="do not remind me">do not remind me</option>
|
||||
@foreach($periods as $period)
|
||||
<option value="{{$period}}" label="{{$period}}">{{$period}}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@if($errors->has('reminder'))
|
||||
<p class="text-danger">{{$errors->first('reminder')}}</p>
|
||||
@else
|
||||
<span class="help-block">Enter a number and a period and Firefly will remind you to add money
|
||||
to this piggy bank every now and then.</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12 col-sm-6">
|
||||
|
||||
<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()}}
|
||||
{!! Form::close() !!}
|
||||
@stop
|
||||
|
@ -1,7 +1,10 @@
|
||||
@extends('layouts.default')
|
||||
@section('content')
|
||||
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $piggyBank) }}
|
||||
{{Form::model($piggyBank, ['class' => 'form-horizontal','id' => 'update','url' => route('piggy-banks.update',$piggyBank->id)])}}
|
||||
{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $piggyBank) !!}
|
||||
{!! Form::model($piggyBank, ['class' => 'form-horizontal','id' => 'update','url' => route('piggy-banks.update',$piggyBank->id)]) !!}
|
||||
|
||||
<input type="hidden" name="repeats" value="0" />
|
||||
<input type="hidden" name="id" value="{{$piggyBank->id}}" />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12 col-sm-6">
|
||||
@ -10,9 +13,13 @@
|
||||
<i class="fa fa-fw fa-exclamation"></i> Mandatory fields
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{Form::ffText('name')}}
|
||||
{{Form::ffSelect('account_id',$accounts,null,['label' => 'Save on account'])}}
|
||||
{{Form::ffAmount('targetamount')}}
|
||||
@foreach($errors->all() as $err)
|
||||
{{$err}}
|
||||
@endforeach
|
||||
|
||||
{!! ExpandedForm::text('name') !!}
|
||||
{!! ExpandedForm::select('account_id',$accounts,null,['label' => 'Save on account']) !!}
|
||||
{!! ExpandedForm::amount('targetamount') !!}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@ -29,9 +36,9 @@
|
||||
<i class="fa fa-smile-o"></i> Optional fields
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{Form::ffDate('targetdate')}}
|
||||
{{Form::ffCheckbox('remind_me','1',$preFilled['remind_me'],['label' => 'Remind me'])}}
|
||||
{{Form::ffSelect('reminder',$periods,$preFilled['reminder'],['label' => 'Remind every'])}}
|
||||
{!! ExpandedForm::date('targetdate') !!}
|
||||
{!! ExpandedForm::checkbox('remind_me','1',$preFilled['remind_me'],['label' => 'Remind me']) !!}
|
||||
{!! ExpandedForm::select('reminder',$periods,$preFilled['reminder'],['label' => 'Remind every']) !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -41,54 +48,12 @@
|
||||
<i class="fa fa-bolt"></i> Options
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{Form::ffOptionsList('update','piggy bank')}}
|
||||
{!! ExpandedForm::optionsList('update','piggy bank') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{--
|
||||
|
||||
<h4>Mandatory fields</h4>
|
||||
|
||||
<h4>Optional fields</h4>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
{{ Form::label('reminder', 'Remind you every', ['class' => 'col-sm-4 control-label'])}}
|
||||
<div class="col-sm-8">
|
||||
<input type="number" step="1" min="1" value="{{Input::old('reminder_skip') ?: 1}}" style="width:50px;display:inline;" max="100" name="reminder_skip" class="form-control" />
|
||||
|
||||
<select class="form-control" name="reminder" style="width:150px;display: inline">
|
||||
<option value="none" label="do not remind me">do not remind me</option>
|
||||
@foreach($periods as $period)
|
||||
<option value="{{$period}}" label="{{$period}}">{{$period}}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@if($errors->has('reminder'))
|
||||
<p class="text-danger">{{$errors->first('reminder')}}</p>
|
||||
@else
|
||||
<span class="help-block">Enter a number and a period and Firefly will remind you to add money
|
||||
to this piggy bank every now and then.</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12 col-sm-6">
|
||||
|
||||
<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()}}
|
||||
{!! Form::close() !!}
|
||||
@stop
|
||||
|
@ -1,5 +1,5 @@
|
||||
<form style="display: inline;" id="remove" action="{{route('piggy-banks.remove',$piggyBank->id)}}" method="POST">
|
||||
{{Form::token()}}
|
||||
{!! Form::token() !!}
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
The maximum amount you can remove is {{Amount::format($piggyBank->currentRelevantRep()->currentamount)}}
|
||||
The maximum amount you can remove is {!! Amount::format($piggyBank->currentRelevantRep()->currentamount) !!}
|
||||
</p>
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">€</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
@extends('layouts.default')
|
||||
@section('content')
|
||||
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $piggyBank) }}
|
||||
{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $piggyBank) !!}
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-md-8 col-sm-6">
|
||||
<div class="panel panel-default">
|
||||
@ -40,15 +40,15 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Target amount</td>
|
||||
<td>{{Amount::format($piggyBank->targetamount)}}</td>
|
||||
<td>{!! Amount::format($piggyBank->targetamount) !!}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Saved so far</td>
|
||||
<td>{{Amount::format($piggyBank->currentRelevantRep()->currentamount)}}</td>
|
||||
<td>{!! Amount::format($piggyBank->currentRelevantRep()->currentamount) !!}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Left to save</td>
|
||||
<td>{{Amount::format($piggyBank->targetamount-$piggyBank->currentRelevantRep()->currentamount)}}</td>
|
||||
<td>{!! Amount::format($piggyBank->targetamount-$piggyBank->currentRelevantRep()->currentamount) !!}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Start date</td>
|
||||
@ -114,12 +114,13 @@
|
||||
|
||||
@section('scripts')
|
||||
<script type="text/javascript">
|
||||
var piggyBankID = {{{$piggyBank->id}}};
|
||||
var currencyCode = '{{Amount::getCurrencyCode()}}';
|
||||
var piggyBankID = {{{$piggyBank->id}}};
|
||||
</script>
|
||||
|
||||
<!-- load the libraries and scripts necessary for Google Charts: -->
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
||||
{{HTML::script('assets/javascript/firefly/gcharts.options.js')}}
|
||||
{{HTML::script('assets/javascript/firefly/gcharts.js')}}
|
||||
{{HTML::script('assets/javascript/firefly/piggy-banks.js')}}
|
||||
<script type="text/javascript" src="js/gcharts.options.js"></script>
|
||||
<script type="text/javascript" src="js/gcharts.js"></script>
|
||||
<script type="text/javascript" src="js/piggy-banks.js"></script>
|
||||
@stop
|
||||
|
Loading…
Reference in New Issue
Block a user