From fc5c339e2745c4f3e2e40c65a778bcdba41d4486 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 27 Feb 2015 11:02:08 +0100 Subject: [PATCH] Repeated expenses. --- app/Http/Controllers/AccountController.php | 2 - .../Controllers/RepeatedExpenseController.php | 199 ++++++++++++++++++ app/Http/Requests/PiggyBankFormRequest.php | 34 +-- app/Http/routes.php | 27 ++- app/Models/PiggyBank.php | 2 +- .../PiggyBank/PiggyBankRepository.php | 97 +++++++-- .../PiggyBankRepositoryInterface.php | 22 ++ app/Repositories/PiggyBank/PiggybankPart.php | 181 ++++++++++++++++ app/Support/Navigation.php | 44 ++++ app/Support/Steam.php | 20 ++ .../views/repeatedExpense/create.blade.php | 58 +++++ .../views/repeatedExpense/delete.blade.php | 37 ++++ .../views/repeatedExpense/edit.blade.php | 58 +++++ .../views/repeatedExpense/index.blade.php | 69 ++++++ .../views/repeatedExpense/show.blade.php | 61 ++++++ 15 files changed, 877 insertions(+), 34 deletions(-) create mode 100644 app/Http/Controllers/RepeatedExpenseController.php create mode 100644 app/Repositories/PiggyBank/PiggybankPart.php create mode 100644 resources/views/repeatedExpense/create.blade.php create mode 100644 resources/views/repeatedExpense/delete.blade.php create mode 100644 resources/views/repeatedExpense/edit.blade.php create mode 100644 resources/views/repeatedExpense/index.blade.php create mode 100644 resources/views/repeatedExpense/show.blade.php diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 3e1a48ea88..c3a79b49ca 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -39,8 +39,6 @@ class AccountController extends Controller $subTitleIcon = Config::get('firefly.subTitlesByIdentifier.' . $what); $subTitle = 'Create a new ' . e($what) . ' account'; - //\FireflyIII\Forms\Tags::ffAmount('12'); - return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle')); } diff --git a/app/Http/Controllers/RepeatedExpenseController.php b/app/Http/Controllers/RepeatedExpenseController.php new file mode 100644 index 0000000000..7813844479 --- /dev/null +++ b/app/Http/Controllers/RepeatedExpenseController.php @@ -0,0 +1,199 @@ +accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*'])); + + return View::make('repeatedExpense.create', compact('accounts', 'periods'))->with('subTitle', 'Create new repeated expense')->with( + 'subTitleIcon', 'fa-plus' + ); + } + + /** + * @param PiggyBank $repeatedExpense + * + * @return $this + */ + public function delete(PiggyBank $repeatedExpense) + { + $subTitle = 'Delete "' . e($repeatedExpense->name) . '"'; + + return View::make('repeatedExpense.delete', compact('repeatedExpense', 'subTitle')); + } + + /** + * @param PiggyBank $repeatedExpense + * + * @return \Illuminate\Http\RedirectResponse + */ + public function destroy(PiggyBank $repeatedExpense) + { + + Session::flash('success', 'Repeated expense "' . e($repeatedExpense->name) . '" deleted.'); + + $repeatedExpense->delete(); + + return Redirect::route('repeated.index'); + } + + /** + * @param PiggyBank $repeatedExpense + * + * @return $this + */ + public function edit(PiggyBank $repeatedExpense) + { + + $periods = Config::get('firefly.piggy_bank_periods'); + $accounts = ExpandedForm::makeSelectList(Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*'])); + $subTitle = 'Edit repeated expense "' . e($repeatedExpense->name) . '"'; + $subTitleIcon = 'fa-pencil'; + + /* + * Flash some data to fill the form. + */ + $preFilled = ['name' => $repeatedExpense->name, + 'account_id' => $repeatedExpense->account_id, + 'targetamount' => $repeatedExpense->targetamount, + 'reminder_skip' => $repeatedExpense->reminder_skip, + 'rep_every' => $repeatedExpense->rep_every, + 'rep_times' => $repeatedExpense->rep_times, + 'targetdate' => $repeatedExpense->targetdate->format('Y-m-d'), + 'reminder' => $repeatedExpense->reminder, + 'remind_me' => intval($repeatedExpense->remind_me) == 1 || !is_null($repeatedExpense->reminder) ? true : false + ]; + Session::flash('preFilled', $preFilled); + + return View::make('repeatedExpense.edit', compact('subTitle', 'subTitleIcon', 'repeatedExpense', 'accounts', 'periods', 'preFilled')); + } + + /** + * @return \Illuminate\View\View + */ + public function index() + { + + $subTitle = 'Overview'; + + $expenses = Auth::user()->piggyBanks()->where('repeats', 1)->get(); + $expenses->each( + function (PiggyBank $piggyBank) { + $piggyBank->currentRelevantRep(); + } + ); + + return View::make('repeatedExpense.index', compact('expenses', 'subTitle')); + } + + /** + * @param PiggyBank $repeatedExpense + * + * @return \Illuminate\View\View + */ + public function show(PiggyBank $repeatedExpense, PiggyBankRepositoryInterface $repository) + { + $subTitle = $repeatedExpense->name; + $today = Carbon::now(); + $repetitions = $repeatedExpense->piggyBankRepetitions()->get(); + + $repetitions->each( + function (PiggyBankRepetition $repetition) use ($repository) { + $repetition->bars = $repository->calculateParts($repetition); + } + ); + + return View::make('repeatedExpense.show', compact('repetitions', 'repeatedExpense', 'today', 'subTitle')); + } + + /** + * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. + */ + public function store(PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository) + { + + $piggyBankData = [ + 'repeats' => true, + 'name' => $request->get('name'), + 'startdate' => new Carbon, + 'account_id' => intval($request->get('account_id')), + 'targetamount' => floatval($request->get('targetamount')), + 'targetdate' => new Carbon($request->get('targetdate')), + 'reminder' => $request->get('reminder'), + 'skip' => intval($request->get('skip')), + 'rep_every' => intval($request->get('rep_every')), + 'rep_times' => intval($request->get('rep_times')), + ]; + + $piggyBank = $repository->store($piggyBankData); + + Session::flash('success', 'Stored repeated expense "' . e($piggyBank->name) . '".'); + + return Redirect::route('repeated.index'); + } + + /** + * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. + * + * @param PiggyBank $repeatedExpense + * + * @return $this + */ + public function update(PiggyBank $repeatedExpense, PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository) + { + $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, + 'rep_length' => $request->get('rep_length'), + 'rep_every' => intval($request->get('rep_every')), + 'rep_times' => intval($request->get('rep_times')), + 'remind_me' => intval($request->get('remind_me')) == 1 ? true : false , + 'reminder' => $request->get('reminder'), + ]; + + + $piggyBank = $repository->update($repeatedExpense, $piggyBankData); + + Session::flash('success', 'Updated repeated expense "' . e($piggyBank->name) . '".'); + + return Redirect::route('repeated.index'); + + } + +} diff --git a/app/Http/Requests/PiggyBankFormRequest.php b/app/Http/Requests/PiggyBankFormRequest.php index f50a0ef00b..74fc66efdb 100644 --- a/app/Http/Requests/PiggyBankFormRequest.php +++ b/app/Http/Requests/PiggyBankFormRequest.php @@ -28,25 +28,31 @@ class PiggyBankFormRequest extends Request public function rules() { - $nameRule = 'required|between:1,255|uniqueForUser:piggy_banks,name'; + $nameRule = 'required|between:1,255|uniqueForUser:piggy_banks,name'; + $targetDateRule = 'date'; if (intval(Input::get('id'))) { $nameRule = 'required|between:1,255'; } + if (intval(Input::get('repeats')) == 1) { + $targetDateRule = 'required|date|after:' . date('Y-m-d'); + } + $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', + 'repeats' => 'required|boolean', + 'name' => $nameRule, + 'account_id' => 'required|belongsToUser:accounts', + 'targetamount' => 'required|min:0.01', + 'amount_currency_id' => 'exists:transaction_currencies,id', + 'startdate' => 'date', + 'targetdate' => $targetDateRule, + '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', ]; diff --git a/app/Http/routes.php b/app/Http/routes.php index 8cac9b0be4..39577154d1 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -27,6 +27,20 @@ Route::bind( } ); +Route::bind( + 'repeatedExpense', 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', 1)->first(['piggy_banks.*']); + } + + return null; +} +); + Route::bind( 'tjSecond', function ($value, $route) { if (Auth::check()) { @@ -263,11 +277,14 @@ Route::group( /** * Repeated Expenses Controller */ - Route::get('/repeatedexpenses', ['uses' => 'RepeatedExpenseController@index', 'as' => 'repeated.index']); - //Route::get('/repeatedexpenses/create', ['uses' => 'RepeatedExpenseController@create', 'as' => 'repeated.create']); - //Route::get('/repeatedexpenses/edit/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@edit', 'as' => 'repeated.edit']); - //Route::get('/repeatedexpenses/delete/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@delete', 'as' => 'repeated.delete']); - //Route::get('/repeatedexpenses/show/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@show', 'as' => 'repeated.show']); + Route::get('/repeated-expenses', ['uses' => 'RepeatedExpenseController@index', 'as' => 'repeated.index']); + Route::get('/repeated-expenses/create', ['uses' => 'RepeatedExpenseController@create', 'as' => 'repeated.create']); + Route::get('/repeated-expenses/edit/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@edit', 'as' => 'repeated.edit']); + Route::get('/repeated-expenses/delete/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@delete', 'as' => 'repeated.delete']); + Route::get('/repeated-expenses/show/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@show', 'as' => 'repeated.show']); + Route::post('/repeated-expense/store', ['uses' => 'RepeatedExpenseController@store', 'as' => 'repeated.store']); + Route::post('/repeated-expense/update/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@update', 'as' => 'repeated.update']); + Route::post('/repeated-expense/destroy/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@destroy', 'as' => 'repeated.destroy']); /** * Report Controller diff --git a/app/Models/PiggyBank.php b/app/Models/PiggyBank.php index d3fe2e1316..305a8eb076 100644 --- a/app/Models/PiggyBank.php +++ b/app/Models/PiggyBank.php @@ -14,7 +14,7 @@ class PiggyBank extends Model { use SoftDeletes; - protected $fillable = ['repeats', 'name', 'account_id', 'targetamount','startdate', 'targetdate', 'reminder',]; + protected $fillable = ['repeats', 'name', 'account_id','rep_every', 'rep_times', 'reminder_skip', 'targetamount', 'startdate', 'targetdate', 'reminder',]; /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo diff --git a/app/Repositories/PiggyBank/PiggyBankRepository.php b/app/Repositories/PiggyBank/PiggyBankRepository.php index f304e178e9..a7eaf8f265 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepository.php +++ b/app/Repositories/PiggyBank/PiggyBankRepository.php @@ -3,6 +3,9 @@ namespace FireflyIII\Repositories\PiggyBank; use FireflyIII\Models\PiggyBank; +use FireflyIII\Models\PiggyBankRepetition; +use Illuminate\Support\Collection; +use Navigation; /** * Class PiggyBankRepository @@ -20,18 +23,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface 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'], - ] - ); + $piggyBank = PiggyBank::create($data); return $piggyBank; } @@ -44,13 +36,94 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface */ public function update(PiggyBank $piggyBank, array $data) { + /** + 'rep_length' => $request->get('rep_length'), + 'rep_every' => intval($request->get('rep_every')), + 'rep_times' => intval($request->get('rep_times')), + 'remind_me' => intval($request->get('remind_me')) == 1 ? true : false , + 'reminder' => $request->get('reminder'), + */ $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->rep_length = isset($data['rep_length']) ? $data['rep_length'] : null; + $piggyBank->rep_every =isset($data['rep_every']) ? $data['rep_every'] : null; + $piggyBank->rep_times = isset($data['rep_times']) ? $data['rep_times'] : null; + $piggyBank->remind_me = isset($data['remind_me']) ? $data['remind_me'] : null; + $piggyBank->save(); return $piggyBank; } + + /** + * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. + * + * Based on the piggy bank, the reminder-setting and + * other variables this method tries to divide the piggy bank into equal parts. Each is + * accommodated by a reminder (if everything goes to plan). + * + * @param PiggyBankRepetition $repetition + * + * @return Collection + */ + public function calculateParts(PiggyBankRepetition $repetition) + { + /** @var PiggyBank $piggyBank */ + $piggyBank = $repetition->piggyBank()->first(); + $bars = new Collection; + $currentStart = clone $repetition->startdate; + + if (is_null($piggyBank->reminder)) { + $entry = ['repetition' => $repetition, 'amountPerBar' => floatval($piggyBank->targetamount), + 'currentAmount' => floatval($repetition->currentamount), 'cumulativeAmount' => floatval($piggyBank->targetamount), + 'startDate' => clone $repetition->startdate, 'targetDate' => clone $repetition->targetdate]; + $bars->push($this->createPiggyBankPart($entry)); + + return $bars; + } + + while ($currentStart < $repetition->targetdate) { + $currentTarget = Navigation::endOfX($currentStart, $piggyBank->reminder, $repetition->targetdate); + $entry = ['repetition' => $repetition, 'amountPerBar' => null, 'currentAmount' => floatval($repetition->currentamount), + 'cumulativeAmount' => null, 'startDate' => $currentStart, 'targetDate' => $currentTarget]; + $bars->push($this->createPiggyBankPart($entry)); + $currentStart = clone $currentTarget; + $currentStart->addDay(); + + } + $amountPerBar = floatval($piggyBank->targetamount) / $bars->count(); + $cumulative = $amountPerBar; + /** @var PiggyBankPart $bar */ + foreach ($bars as $index => $bar) { + $bar->setAmountPerBar($amountPerBar); + $bar->setCumulativeAmount($cumulative); + if ($bars->count() - 1 == $index) { + $bar->setCumulativeAmount($piggyBank->targetamount); + } + $cumulative += $amountPerBar; + } + + return $bars; + } + + /** + * @param array $data + * + * @return PiggyBankPart + */ + public function createPiggyBankPart(array $data) + { + $part = new PiggyBankPart; + $part->setRepetition($data['repetition']); + $part->setAmountPerBar($data['amountPerBar']); + $part->setCurrentamount($data['currentAmount']); + $part->setCumulativeAmount($data['cumulativeAmount']); + $part->setStartdate($data['startDate']); + $part->setTargetdate($data['targetDate']); + + return $part; + } } \ No newline at end of file diff --git a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php index 333a2e993f..a06ed505be 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php +++ b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php @@ -3,6 +3,8 @@ namespace FireflyIII\Repositories\PiggyBank; use FireflyIII\Models\PiggyBank; +use FireflyIII\Models\PiggyBankRepetition; +use Illuminate\Support\Collection; /** * Interface PiggyBankRepositoryInterface @@ -26,4 +28,24 @@ interface PiggyBankRepositoryInterface { * @return PiggyBank */ public function update(PiggyBank $piggyBank, array $data); + + /** + * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. + * + * Based on the piggy bank, the reminder-setting and + * other variables this method tries to divide the piggy bank into equal parts. Each is + * accommodated by a reminder (if everything goes to plan). + * + * @param PiggyBankRepetition $repetition + * + * @return Collection + */ + public function calculateParts(PiggyBankRepetition $repetition); + + /** + * @param array $data + * + * @return PiggyBankPart + */ + public function createPiggyBankPart(array $data); } \ No newline at end of file diff --git a/app/Repositories/PiggyBank/PiggybankPart.php b/app/Repositories/PiggyBank/PiggybankPart.php new file mode 100644 index 0000000000..9bbbad807c --- /dev/null +++ b/app/Repositories/PiggyBank/PiggybankPart.php @@ -0,0 +1,181 @@ +reminder)) { + $this->reminder = $this->repetition->piggyBank->reminders()->where('startdate', $this->getStartdate()->format('Y-m-d'))->where( + 'enddate', $this->getTargetdate()->format('Y-m-d') + )->first(); + } + + return $this->reminder; + } + + /** + * @param Reminder $reminder + */ + public function setReminder($reminder) + { + $this->reminder = $reminder; + } + + /** + * @return Carbon + */ + public function getStartdate() + { + return $this->startdate; + } + + /** + * @param Carbon $startdate + */ + public function setStartdate($startdate) + { + $this->startdate = $startdate; + } + + /** + * @return Carbon + */ + public function getTargetdate() + { + return $this->targetdate; + } + + /** + * @param Carbon $targetdate + */ + public function setTargetdate($targetdate) + { + $this->targetdate = $targetdate; + } + + /** + * @return PiggyBankRepetition + */ + public function getRepetition() + { + return $this->repetition; + } + + /** + * @param PiggyBankRepetition $repetition + */ + public function setRepetition($repetition) + { + $this->repetition = $repetition; + } + + /** + * @return bool + */ + public function hasReminder() + { + return !is_null($this->reminder); + } + + /** + * @return float|int + */ + public function percentage() + { + if ($this->getCurrentamount() < $this->getCumulativeAmount()) { + $pct = 0; + // calculate halfway point? + if ($this->getCumulativeAmount() - $this->getCurrentamount() < $this->getAmountPerBar()) { + $left = $this->getCurrentamount() % $this->getAmountPerBar(); + $pct = round($left / $this->getAmountPerBar() * 100); + } + + return $pct; + } else { + return 100; + } + } + + /** + * @return float + */ + public function getCurrentamount() + { + return $this->currentamount; + } + + /** + * @param float $currentamount + */ + public function setCurrentamount($currentamount) + { + $this->currentamount = $currentamount; + } + + /** + * @return float + */ + public function getCumulativeAmount() + { + return $this->cumulativeAmount; + } + + /** + * @param float $cumulativeAmount + */ + public function setCumulativeAmount($cumulativeAmount) + { + $this->cumulativeAmount = $cumulativeAmount; + } + + /** + * @return float + */ + public function getAmountPerBar() + { + return $this->amountPerBar; + } + + /** + * @param float $amountPerBar + */ + public function setAmountPerBar($amountPerBar) + { + $this->amountPerBar = $amountPerBar; + } + + +} diff --git a/app/Support/Navigation.php b/app/Support/Navigation.php index 4bdec6aa1a..786ffa39cf 100644 --- a/app/Support/Navigation.php +++ b/app/Support/Navigation.php @@ -103,6 +103,50 @@ class Navigation return $currentEnd; } + /** + * + * @param Carbon $theCurrentEnd + * @param $repeatFreq + * @param Carbon $maxDate + * + * @return Carbon + */ + public function endOfX(Carbon $theCurrentEnd, $repeatFreq, Carbon $maxDate) + { + $functionMap = [ + 'daily' => 'endOfDay', + 'week' => 'endOfWeek', + 'weekly' => 'endOfWeek', + 'month' => 'endOfMonth', + 'monthly' => 'endOfMonth', + 'quarter' => 'lastOfQuarter', + 'quarterly' => 'lastOfQuarter', + 'year' => 'endOfYear', + 'yearly' => 'endOfYear', + ]; + $specials = ['mont', 'monthly']; + + $currentEnd = clone $theCurrentEnd; + + if (isset($functionMap[$repeatFreq])) { + $function = $functionMap[$repeatFreq]; + $currentEnd->$function(); + + } + if (isset($specials[$repeatFreq])) { + $month = intval($theCurrentEnd->format('m')); + $currentEnd->endOfYear(); + if ($month <= 6) { + $currentEnd->subMonths(6); + } + } + if ($currentEnd > $maxDate) { + return clone $maxDate; + } + + return $currentEnd; + } + /** * @param $range * @param Carbon $date diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 750ac26777..8a42a2d865 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -4,6 +4,8 @@ namespace FireflyIII\Support; use Carbon\Carbon; use FireflyIII\Models\Account; +use FireflyIII\Models\PiggyBank; +use FireflyIII\Models\PiggyBankRepetition; use Illuminate\Support\Collection; /** @@ -161,4 +163,22 @@ class Steam return $array; } + /** + * @param PiggyBank $piggyBank + * @param PiggyBankRepetition $repetition + * + * @return int + */ + public function percentage(PiggyBank $piggyBank, PiggyBankRepetition $repetition) + { + $pct = $repetition->currentamount / $piggyBank->targetamount * 100; + if ($pct > 100) { + // @codeCoverageIgnoreStart + return 100; + // @codeCoverageIgnoreEnd + } else { + return floor($pct); + } + } + } \ No newline at end of file diff --git a/resources/views/repeatedExpense/create.blade.php b/resources/views/repeatedExpense/create.blade.php new file mode 100644 index 0000000000..9e1dcfe5e7 --- /dev/null +++ b/resources/views/repeatedExpense/create.blade.php @@ -0,0 +1,58 @@ +@extends('layouts.default') +@section('content') +{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName()) !!} +{!! Form::open(['class' => 'form-horizontal','id' => 'store','url' => route('repeated.store')]) !!} + + + +
+
+
+
+ Mandatory fields +
+
+ + {!! ExpandedForm::text('name') !!} + {!! ExpandedForm::select('account_id',$accounts,null,['label' => 'Save on account']) !!} + {!! ExpandedForm::amount('targetamount') !!} + {!! ExpandedForm::date('targetdate',null,['label' => 'First target date']) !!} + {!! ExpandedForm::select('rep_length',$periods,'month',['label' => 'Repeats every']) !!} + {!! ExpandedForm::integer('rep_every',0,['label' => 'Skip period']) !!} + {!! ExpandedForm::integer('rep_times',0,['label' => 'Repeat times']) !!} +
+
+

+ +

+
+
+ +
+
+ Optional fields +
+
+ + {!! ExpandedForm::checkbox('remind_me','1',false,['label' => 'Remind me']) !!} + {!! ExpandedForm::select('reminder',$periods,'month',['label' => 'Remind every']) !!} +
+
+ + +
+
+ Options +
+
+ {!! ExpandedForm::optionsList('create','repeated expense') !!} +
+
+ +
+
+ +{!! Form::close() !!} +@stop diff --git a/resources/views/repeatedExpense/delete.blade.php b/resources/views/repeatedExpense/delete.blade.php new file mode 100644 index 0000000000..6a51c73c98 --- /dev/null +++ b/resources/views/repeatedExpense/delete.blade.php @@ -0,0 +1,37 @@ +@extends('layouts.default') +@section('content') +{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $repeatedExpense) !!} +{!! Form::open(['class' => 'form-horizontal','id' => 'destroy','url' => route('repeated.destroy',$repeatedExpense->id)]) !!} +
+
+
+
+ Delete repeated expense "{{{$repeatedExpense->name}}}" +
+
+

+ Are you sure? +

+ +

+ + Cancel +

+
+
+
+
+ +
+
+
+
+ +
+
+
+
+ + +{!! Form::close() !!} +@stop diff --git a/resources/views/repeatedExpense/edit.blade.php b/resources/views/repeatedExpense/edit.blade.php new file mode 100644 index 0000000000..bdec62776c --- /dev/null +++ b/resources/views/repeatedExpense/edit.blade.php @@ -0,0 +1,58 @@ +@extends('layouts.default') +@section('content') +{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $repeatedExpense) !!} +{!! Form::model($repeatedExpense, ['class' => 'form-horizontal','id' => 'update','url' => route('repeated.update',$repeatedExpense->id)]) !!} + + + + +
+
+
+
+ Mandatory fields +
+
+ {!! ExpandedForm::text('name') !!} + {!! ExpandedForm::select('account_id',$accounts,null,['label' => 'Save on account']) !!} + {!! ExpandedForm::amount('targetamount') !!} + {!! ExpandedForm::date('targetdate',null,['label' => 'First target date']) !!} + {!! ExpandedForm::select('rep_length',$periods,null,['label' => 'Repeats every']) !!} + {!! ExpandedForm::integer('rep_every',null,['label' => 'Skip period']) !!} + {!! ExpandedForm::integer('rep_times',null,['label' => 'Repeat times']) !!} + +
+
+

+ +

+
+
+ +
+
+ Optional fields +
+
+ {!! ExpandedForm::checkbox('remind_me','1',$preFilled['remind_me'],['label' => 'Remind me']) !!} + {!! ExpandedForm::select('reminder',$periods,$preFilled['reminder'],['label' => 'Remind every']) !!} +
+
+ + +
+
+ Options +
+
+ {!! ExpandedForm::optionsList('update','piggy bank') !!} +
+
+ +
+
+ +{!! Form::close() !!} +@stop diff --git a/resources/views/repeatedExpense/index.blade.php b/resources/views/repeatedExpense/index.blade.php new file mode 100644 index 0000000000..3daed772a8 --- /dev/null +++ b/resources/views/repeatedExpense/index.blade.php @@ -0,0 +1,69 @@ +@extends('layouts.default') +@section('content') +{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName()) !!} +
+ +
+ +@foreach($expenses as $entry) +
+
+
+
+ {{{$entry->name}}} + ({!! Amount::format($entry->targetamount) !!}) + + +
+
+ + +
+
+
+
+
+
+ @if(Steam::percentage($entry,$entry->currentRep) > 30) + {{Amount::format($entry->currentRep->currentamount,false)}} + @endif +
+ @if(Steam::percentage($entry,$entry->currentRep) <= 30) +  {{Amount::format($entry->currentRep->currentamount,false)}} + @endif +
+
+ +
+
+
+ @endforeach + +
+ +
+ + + + +@stop +@section('scripts') +@stop diff --git a/resources/views/repeatedExpense/show.blade.php b/resources/views/repeatedExpense/show.blade.php new file mode 100644 index 0000000000..6baec34d1a --- /dev/null +++ b/resources/views/repeatedExpense/show.blade.php @@ -0,0 +1,61 @@ +@extends('layouts.default') +@section('content') +{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $repeatedExpense) !!} +
+
+ @foreach($repetitions as $rep) + bars->count()) == 0 ? 1 : floor(12 / $rep->bars->count()); + ?> + + +
+
+ Repetition from {{$rep->startdate->format('j F Y')}} to {{$rep->targetdate->format('j F Y')}} +
+
+

+ Target amount: {!! Amount::format($repeatedExpense->targetamount) !!}. Currently saved: {!! Amount::format($rep->currentamount) !!}. +

+
+ @foreach($rep->bars as $bar) +
+
+ +
+ @if($bar->percentage() > 50 && $bar->percentage() == 100) + @if($bar->hasReminder() && $bar->getReminder()->active == 1) + + @endif + @if($bar->hasReminder() && $bar->getReminder()->active == 0 && $bar->getReminder()->notnow == 0) + + @endif + @if($bar->hasReminder() && $bar->getReminder()->active == 0 && $bar->getReminder()->notnow == 1) + + @endif + @endif + @if($bar->percentage() > 50 && $bar->percentage() < 100) + {{Amount::format($rep->currentamount,false)}} + @endif +
+
+
+

+ {{$bar->getStartDate()->format('j F Y')}} — {{$bar->getTargetDate()->format('j F Y')}} +

+ +
+ @endforeach +
+
+
+ @endforeach +
+
+@stop