diff --git a/README.md b/README.md index fcf63de63b..de078763b9 100644 --- a/README.md +++ b/README.md @@ -41,15 +41,14 @@ Firefly III will feature: - Firefly will not encrypt the content of the (MySQL) tables. Old versions of Firefly had this capability but it sucks when searching, sorting and organizing entries. ## Current state -I barely have the basics up and running and test coverage is doing very good. I have some good ideas about user configuration and preferences which was a huge pain in the butt with the previous Firefly. +I have the basics up and running and test coverage is doing very well. -Current problems include proper time-based navigation (how and when to switch to the next month, previous week, etc) and the best -way to display your current financial state, which is something that still needs thinking. +Current issues are the consistent look-and-feel of forms and likewise, the consistent inner workings of most of Firefly. +Example: every "create"-action tends to be slightly different from the rest. Also is the fact that not all lists +and forms are equally well thought of; some are not looking very well or miss feedback. +Most forms will not allow you to enter invalid data because the database cracks, not because it's actually checked. -The problem is that most peoples finances are very flexible and Firefly can be pretty static. For example, did you spend all your money? Or -do you have money left? Good question: when your rent is due at the 1st of the month Firefly might think you've spent way too much. But -marking it as some kind of "bill" will make Firefly ignore it, but it might make Firefly forget that you've got bills coming! So there's -a lot to do, and a lot to fix. +A lot of views have CSRF vulnerabilities. -If you have an idea, [let me know](https://github.com/JC5/firefly-iii/issues/new)! +Questions, ideas or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)! diff --git a/app/assets/javascripts/firefly/piggybanks-create.js b/app/assets/javascripts/firefly/piggybanks-create.js new file mode 100644 index 0000000000..fbf5fb2588 --- /dev/null +++ b/app/assets/javascripts/firefly/piggybanks-create.js @@ -0,0 +1,25 @@ +$(function () { + +updatePiggyFields(); +$('input[name="repeats"]').on('change',updatePiggyFields); + +}); + +function updatePiggyFields() { + //var val = $('input[name="repeats"]').checked; + + console.log('Repeating elements: ' + $('.repeat-piggy').length); + console.log('Non-repeating elements: ' + $('.no-repeat-piggy').length); + + if($('input[name="repeats"]').prop( "checked" )) { + // checked, repeats! + console.log('repeats!'); + $('.repeat-piggy').show(); + $('.no-repeat-piggy').hide(); + } else { + console.log('no repeats!'); + // unchecked, does not repeat! + $('.no-repeat-piggy').show(); + $('.repeat-piggy').hide(); + } +} \ No newline at end of file diff --git a/app/assets/javascripts/firefly/piggybanks.js b/app/assets/javascripts/firefly/piggybanks.js index 56f02c9fbf..07e141ef40 100644 --- a/app/assets/javascripts/firefly/piggybanks.js +++ b/app/assets/javascripts/firefly/piggybanks.js @@ -1,124 +1,4 @@ $(function () { - $('input[type="range"]').on('input', inputRange); - $('input[type="range"]').on('change', updateAmount); - $('input[type="number"]').on('input',inputNumber); -}); - -/** - * Update some fields to reflect drag changes. - * @param e - * @returns {boolean} - */ -function inputRange(e) { - var target = $(e.target); - var piggyBankId = target.attr('name').substring(6); - var accountId = target.data('account'); - var amount = parseFloat(target.val()); - - - -// - // new percentage for amount in piggy bank, formatted. - var pctId = 'piggy_' + piggyBankId + '_pct'; - percentage = Math.round((amount / parseFloat(target.attr('max'))) * 100) + '%'; //Math.round((value / parseFloat(target.attr('total'))) * 100) + '%'; - $('#' + pctId).text(percentage); - - // new value for number input: - var valueId = 'piggy_' + piggyBankId + '_amount'; - $('#' + valueId).val(amount.toFixed(2)); - - leftInAccounts(accountId); - - return true; -} - -function inputNumber(e) { - var target = $(e.target); - var amount = parseFloat(target.val()); - var piggyBankId = target.data('piggy'); - var accountId = target.data('account'); - - - // update amount in range input: - target.val(amount); - $('input[name="piggy_'+piggyBankId+'"]').val(amount); - console.log('SERVER: ' + amount); - $.post('piggybanks/updateAmount/' + piggyBankId, {amount: amount}); - - leftInAccounts(accountId); -} - - -function updateAmount(e) { - - // update amount on server: - var target = $(e.target); - var piggyBankId = target.attr('name').substring(6); - var accountId = target.data('account'); - var amount = target.val(); - console.log('SERVER: ' + amount); - $.post('piggybanks/updateAmount/' + piggyBankId, {amount: amount}); - - -} - -function leftInAccounts(accountId) { - // get the total: - var total = parseFloat($('#account_'+accountId+'_total').data('raw')); - - // sub all piggy banks: - var inPiggies = 0; - $('input[type="range"]').each(function(i,v) { - var p = $(v); - if(parseInt(p.data('account')) == accountId) { - inPiggies += parseFloat(p.val()); - } - }); - var left = total - inPiggies; - - // set amount left: - leftFormatted = '€ ' + left.toFixed(2); - $('#account_'+accountId+'_left').text(leftFormatted); - - // return amount left: - return left; - - -} - -function updateAccounts(id) { -// -// var spent = 0; -// $.each($('input[type="range"]'), function (i, v) { -// var current = $(v); -// var accountId = parseInt(current.data('account')); -// if (accountId == id) { -// spent += parseFloat(current.val()); -// } -//// var value = parseFloat(current.val()); -//// var accountId = parseInt(current.data('account')); -//// -//// // only when we're working on this account we update "spent" -//// if(accountId == id) { -//// spent = spent[accountId] == undefined ? value : spent[accountId] + value; -//// //var leftNow = accountLeft[accountId] - value; -//// } -// }); -// console.log('Spent for account ' + id + ': ' + spent); -// var left = accountLeft[id] - spent; -// var leftFormatted = '€ ' + (Math.round((left) * 100) / 100).toFixed(2); -// var entryId = 'account_' + id + '_left'; -// $('#' + entryId).text(leftFormatted); -// if(left < 0) { -// return false; -// } -// return true; -//// -//// // now we update the amount in the list of accounts: -//// var left = accountLeft[id] - spent; -//// var leftFormatted = - - -} \ No newline at end of file +}); \ No newline at end of file diff --git a/app/assets/javascripts/piggybanks-create.js b/app/assets/javascripts/piggybanks-create.js new file mode 100644 index 0000000000..3b1d52a921 --- /dev/null +++ b/app/assets/javascripts/piggybanks-create.js @@ -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-create diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index d773185f71..fda3861eb9 100644 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -20,7 +20,6 @@ class AccountController extends \BaseController { $this->_accounts = $accounts; $this->_repository = $repository; - View::share('menu', 'accounts'); } /** diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php index 555911b453..4bac75d220 100644 --- a/app/controllers/BudgetController.php +++ b/app/controllers/BudgetController.php @@ -21,7 +21,6 @@ class BudgetController extends BaseController { $this->_budgets = $budgets; $this->_repository = $repository; - View::share('menu', 'budgets'); } /** diff --git a/app/controllers/CategoryController.php b/app/controllers/CategoryController.php index 9ed9f81917..49a9f2bbc4 100644 --- a/app/controllers/CategoryController.php +++ b/app/controllers/CategoryController.php @@ -19,7 +19,6 @@ class CategoryController extends BaseController { $this->_repository = $repository; $this->_category = $category; - View::share('menu', 'categories'); } /** diff --git a/app/controllers/HomeController.php b/app/controllers/HomeController.php index d1226a950d..3f783b6f65 100644 --- a/app/controllers/HomeController.php +++ b/app/controllers/HomeController.php @@ -26,9 +26,6 @@ class HomeController extends BaseController $this->_preferences = $preferences; $this->_journal = $journal; $this->_budgets = $budgets; - View::share('menu', 'home'); - - } /** diff --git a/app/controllers/LimitController.php b/app/controllers/LimitController.php index af8daa9559..e722a0d57f 100644 --- a/app/controllers/LimitController.php +++ b/app/controllers/LimitController.php @@ -20,8 +20,6 @@ class LimitController extends BaseController { $this->_budgets = $budgets; $this->_limits = $limits; - View::share('menu', 'budgets'); - } /** diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php index e47370cd1e..fad626f33d 100644 --- a/app/controllers/PiggybankController.php +++ b/app/controllers/PiggybankController.php @@ -20,8 +20,6 @@ class PiggybankController extends BaseController { $this->_repository = $repository; $this->_accounts = $accounts; - View::share('menu', 'home'); - } /** @@ -80,17 +78,7 @@ class PiggybankController extends BaseController // get accounts: foreach ($piggybanks as $piggyBank) { $account = $piggyBank->account; - $piggyBank->pct = round(($piggyBank->amount / $piggyBank->target) * 100, 0) . '%'; $id = $account->id; - if (!isset($accounts[$id])) { - $account->balance = $account->balance(); - $account->left = $account->balance - $piggyBank->amount; - $account->total = $piggyBank->target; - } else { - $account->left -= $piggyBank->amount; - $account->total += $piggyBank->target; - - } $accounts[$id] = $account; } @@ -105,7 +93,7 @@ class PiggybankController extends BaseController */ public function show(Piggybank $piggyBank) { - return View::make('piggybanks.show')->with('piggyBank',$piggyBank); + return View::make('piggybanks.show')->with('piggyBank', $piggyBank); } /** diff --git a/app/controllers/PreferencesController.php b/app/controllers/PreferencesController.php index bf9c6f0e93..19443cb6d1 100644 --- a/app/controllers/PreferencesController.php +++ b/app/controllers/PreferencesController.php @@ -20,7 +20,6 @@ class PreferencesController extends BaseController $this->_accounts = $accounts; $this->_preferences = $preferences; - View::share('menu', 'home'); } /** diff --git a/app/controllers/ProfileController.php b/app/controllers/ProfileController.php index 84faea187a..2ae0db6295 100644 --- a/app/controllers/ProfileController.php +++ b/app/controllers/ProfileController.php @@ -14,7 +14,6 @@ class ProfileController extends BaseController public function __construct(URI $user) { $this->user = $user; - View::share('menu', 'home'); } /** diff --git a/app/controllers/RecurringController.php b/app/controllers/RecurringController.php index 4acf73e8f3..46be9a5b6a 100644 --- a/app/controllers/RecurringController.php +++ b/app/controllers/RecurringController.php @@ -15,7 +15,6 @@ class RecurringController extends BaseController public function __construct(RTR $repository) { $this->_repository = $repository; - View::share('menu', 'home'); } /** diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index 0cf1d96cca..82ffbd2ccd 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -17,7 +17,6 @@ class TransactionController extends BaseController public function __construct(TJRI $repository) { $this->_repository = $repository; - View::share('menu', 'home'); } /** diff --git a/app/controllers/UserController.php b/app/controllers/UserController.php index 844b7fd20d..c0e91cec41 100644 --- a/app/controllers/UserController.php +++ b/app/controllers/UserController.php @@ -45,13 +45,13 @@ class UserController extends BaseController 'email' => Input::get('email'), 'password' => Input::get('password') ]; - if (Auth::attempt($data, $rememberMe)) { + $result = Auth::attempt($data, $rememberMe); + if ($result) { Session::flash('success', 'Logged in!'); - return Redirect::route('index'); } - Session::flash('error', 'No good!'); + Session::flash('error', 'No good!'); return View::make('user.login'); } diff --git a/app/database/migrations/2014_07_05_100651_create_piggybanks_table.php b/app/database/migrations/2014_07_05_100651_create_piggybanks_table.php index 125d15a86b..1f2b5d1828 100644 --- a/app/database/migrations/2014_07_05_100651_create_piggybanks_table.php +++ b/app/database/migrations/2014_07_05_100651_create_piggybanks_table.php @@ -23,10 +23,14 @@ class CreatePiggybanksTable extends Migration $table->increments('id'); $table->timestamps(); $table->integer('account_id')->unsigned(); - $table->date('targetdate')->nullable(); $table->string('name', 100); - $table->decimal('amount', 10, 2); - $table->decimal('target', 10, 2)->nullable(); + $table->decimal('targetamount', 10, 2); + $table->date('targetdate')->nullable(); + $table->date('startdate')->nullable(); + $table->boolean('repeats'); + $table->enum('rep_length', ['day', 'week', 'month', 'year'])->nullable(); + $table->smallInteger('rep_times')->unsigned(); + $table->enum('reminder', ['day', 'week', 'month', 'year'])->nullable(); $table->integer('order')->unsigned(); // connect account to piggybank. diff --git a/app/database/migrations/2014_08_12_173919_create_piggy_instance.php b/app/database/migrations/2014_08_12_173919_create_piggy_instance.php new file mode 100644 index 0000000000..761a380b73 --- /dev/null +++ b/app/database/migrations/2014_08_12_173919_create_piggy_instance.php @@ -0,0 +1,41 @@ +increments('id'); + $table->timestamps(); + $table->integer('piggybank_id')->unsigned(); + $table->date('targetdate')->nullable(); + $table->date('startdate')->nullable(); + $table->decimal('currentamount',10,2); + + // connect instance to piggybank. + $table->foreign('piggybank_id') + ->references('id')->on('piggybanks') + ->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('piggybank_repetitions'); + } + +} diff --git a/app/database/seeds/DefaultUserSeeder.php b/app/database/seeds/DefaultUserSeeder.php index 7ff50fb7d9..dc7a102cbf 100644 --- a/app/database/seeds/DefaultUserSeeder.php +++ b/app/database/seeds/DefaultUserSeeder.php @@ -12,7 +12,7 @@ class DefaultUserSeeder extends Seeder User::create( [ 'email' => 's@nder.be', - 'password' => Hash::make('sander'), + 'password' => 'sander', 'reset' => null, 'remember_token' => null, 'migrated' => 0 diff --git a/app/lib/Firefly/Helper/Form/FormHelper.php b/app/lib/Firefly/Helper/Form/FormHelper.php index 76aed33d48..f6b94837c0 100644 --- a/app/lib/Firefly/Helper/Form/FormHelper.php +++ b/app/lib/Firefly/Helper/Form/FormHelper.php @@ -9,6 +9,7 @@ namespace Firefly\Helper\Form; */ class FormHelper { + /** * @param null $value * diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php index 454c781e93..370d5eb1e8 100644 --- a/app/models/Piggybank.php +++ b/app/models/Piggybank.php @@ -24,17 +24,33 @@ use LaravelBook\Ardent\Ardent as Ardent; * @method static \Illuminate\Database\Query\Builder|\Piggybank whereAmount($value) * @method static \Illuminate\Database\Query\Builder|\Piggybank whereTarget($value) * @method static \Illuminate\Database\Query\Builder|\Piggybank whereOrder($value) + * @property float $targetamount + * @property string $startdate + * @property boolean $repeats + * @property string $rep_length + * @property integer $rep_times + * @property string $reminder + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereTargetamount($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereStartdate($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepeats($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepLength($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereRepTimes($value) + * @method static \Illuminate\Database\Query\Builder|\Piggybank whereReminder($value) */ 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', + 'account_id' => 'required|exists:accounts,id', + 'name' => 'required|between:1,255', + 'targetamount' => 'required|min:0', + 'targetdate' => 'date', + 'startdate' => 'date', + 'repeats' => 'required|between:0,1', + 'rep_length' => 'in:day,week,month,year', + 'rep_times' => 'required|min:0|max:100', + 'reminder' => 'in:day,week,month,year', + 'order' => 'required:min:1', ]; /** @@ -44,14 +60,19 @@ class Piggybank extends Ardent { $start = new Carbon; $start->endOfMonth(); + $today = new Carbon; return [ - 'name' => 'string', 'account_id' => 'factory|Account', - 'targetdate' => $start, - 'amount' => 0, - 'target' => 100, - 'order' => 1 + 'name' => 'string', + 'targetamount' => 'required|min:0', + 'targetdate' => $start, + 'startdate' => $today, + 'repeats' => 0, + 'rep_length' => null, + 'rep_times' => 0, + 'reminder' => null, + 'order' => 1, ]; } @@ -63,6 +84,10 @@ class Piggybank extends Ardent return $this->belongsTo('Account'); } + public function piggybankrepetitions() { + return $this->hasMany('PiggybankRepetition'); + } + /** * @return array */ diff --git a/app/models/PiggybankRepetition.php b/app/models/PiggybankRepetition.php new file mode 100644 index 0000000000..f26acac862 --- /dev/null +++ b/app/models/PiggybankRepetition.php @@ -0,0 +1,50 @@ + 'required|exists:piggybanks,id', + 'targetdate' => 'date', + 'startdate' => 'date', + 'currentamount' => 'required|numeric' + ]; + + /** + * @return array + */ + public static function factory() + { + $date = new Carbon; + + return [ + 'piggybank_id' => 'factory|Piggybank', + 'targetdate' => $date, + 'startdate' => $date, + 'currentamount' => 200 + ]; + } + + /** + * @return array + */ + public function getDates() + { + return ['created_at', 'updated_at', 'targetdate', 'startdate']; + } + + /** + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function piggybank() + { + return $this->belongsTo('Piggybank'); + } + +} \ No newline at end of file diff --git a/app/models/TransactionCurrency.php b/app/models/TransactionCurrency.php index 165773c36f..698b8361f7 100644 --- a/app/models/TransactionCurrency.php +++ b/app/models/TransactionCurrency.php @@ -13,6 +13,7 @@ * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereCreatedAt($value) * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereUpdatedAt($value) * @method static \Illuminate\Database\Query\Builder|\TransactionCurrency whereCode($value) + * @property-read \Illuminate\Database\Eloquent\Collection|\TransactionJournal[] $transactionjournals */ class TransactionCurrency extends Eloquent { diff --git a/app/models/TransactionJournal.php b/app/models/TransactionJournal.php index 3a2f0e73c5..52f9c99654 100644 --- a/app/models/TransactionJournal.php +++ b/app/models/TransactionJournal.php @@ -71,6 +71,10 @@ use LaravelBook\Ardent\Ardent; * 'Budget[] $budgets * @property-read \Illuminate\Database\Eloquent\Collection|\ * 'Category[] $categories + * @property-read \Illuminate\Database\Eloquent\Collection|\ + * 'Budget[] $budgets + * @property-read \Illuminate\Database\Eloquent\Collection|\ + * 'Category[] $categories */ class TransactionJournal extends Ardent { diff --git a/app/views/accounts/index.blade.php b/app/views/accounts/index.blade.php index 2b662071b1..bea833be0b 100644 --- a/app/views/accounts/index.blade.php +++ b/app/views/accounts/index.blade.php @@ -13,6 +13,9 @@ bank accounts are representated as accounts (naturally), but the stores you buy stuff at are also represented as accounts. Likewise, if you have a job, your salary is drawn from their account.
++
+ +