diff --git a/README.md b/README.md
index 35ed614ab1..d44acfefd3 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,6 @@ Everything is organised:
- Clear views that should show you how you're doing;
- Easy navigation through your records;
- Browse back and forth to see previous months or even years;
-- Lots of help text in case you don't get it;
- Lots of charts because we all love them.
## Changes
@@ -36,6 +35,7 @@ Everything is organised:
Firefly III will feature, but does not feature yet:
- Financial reporting showing you how well you are doing;
+- Lots of help text in case you don't get it;
- More control over other resources outside of personal finance
- Accounts shared with a partner (household accounts)
- Debts
@@ -51,6 +51,10 @@ Some stuff has been removed:
- The nesting of budgets, categories and beneficiaries is removed because it was pretty pointless.
- 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.
+## Screenshots
+
+
+
## Current state
I have the basics up and running. Test coverage is currently non-existent.
diff --git a/app/config/app.php b/app/config/app.php
index 66190ce4e2..b997979dd7 100644
--- a/app/config/app.php
+++ b/app/config/app.php
@@ -43,7 +43,7 @@ return [
'Firefly\Helper\HelperServiceProvider',
'Firefly\Validation\ValidationServiceProvider',
'DaveJamesMiller\Breadcrumbs\ServiceProvider',
- 'TwigBridge\ServiceProvider'
+ 'Grumpydictator\Gchart\GchartServiceProvider',
],
'manifest' => storage_path() . '/meta',
'aliases' => [
diff --git a/app/config/firefly.php b/app/config/firefly.php
index 61ccb7820e..bd7db200f6 100644
--- a/app/config/firefly.php
+++ b/app/config/firefly.php
@@ -2,10 +2,14 @@
use Carbon\Carbon;
return [
- 'index_periods' => ['1D', '1W', '1M', '3M', '6M','1Y', 'custom'],
- 'budget_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
- 'piggybank_periods' => ['day', 'week', 'month', 'year'],
- 'periods_to_text' => [
+ 'index_periods' => ['1D', '1W', '1M', '3M', '6M', '1Y', 'custom'],
+ 'budget_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'],
+ 'piggybank_periods' => [
+ 'week' => 'Week',
+ 'month' => 'Month',
+ 'year' => 'Year'
+ ],
+ 'periods_to_text' => [
'weekly' => 'A week',
'monthly' => 'A month',
'quarterly' => 'A quarter',
@@ -13,7 +17,7 @@ return [
'yearly' => 'A year',
],
- 'range_to_text' => [
+ 'range_to_text' => [
'1D' => 'day',
'1W' => 'week',
'1M' => 'month',
@@ -21,15 +25,15 @@ return [
'6M' => 'half year',
'custom' => '(custom)'
],
- 'range_to_name' => [
- '1D' => 'one day',
- '1W' => 'one week',
- '1M' => 'one month',
- '3M' => 'three months',
- '6M' => 'six months',
- '1Y' => 'one year',
+ 'range_to_name' => [
+ '1D' => 'one day',
+ '1W' => 'one week',
+ '1M' => 'one month',
+ '3M' => 'three months',
+ '6M' => 'six months',
+ '1Y' => 'one year',
],
- 'range_to_repeat_freq' => [
+ 'range_to_repeat_freq' => [
'1D' => 'weekly',
'1W' => 'weekly',
'1M' => 'monthly',
diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php
index 2ddcd82e42..ba394611ae 100644
--- a/app/controllers/AccountController.php
+++ b/app/controllers/AccountController.php
@@ -1,31 +1,116 @@
_accounts = $accounts;
- $this->_repository = $repository;
View::share('mainTitleIcon', 'fa-credit-card');
View::share('title', 'Accounts');
}
+ /**
+ * @param string $what
+ *
+ * @return View
+ * @throws FireflyException
+ */
+ public function index($what = 'default')
+ {
+ switch ($what) {
+ default:
+ throw new FireflyException('Cannot handle account type "' . e($what) . '".');
+ break;
+ case 'asset':
+ View::share('subTitleIcon', 'fa-money');
+ View::share('subTitle', 'Asset accounts');
+ break;
+ case 'expense':
+ View::share('subTitleIcon', 'fa-shopping-cart');
+ View::share('subTitle', 'Expense accounts');
+ break;
+ case 'revenue':
+ View::share('subTitleIcon', 'fa-download');
+ View::share('subTitle', 'Revenue accounts');
+ break;
+ }
+ return View::make('accounts.index')->with('what', $what);
+ }
+
+
+ /**
+ * @param string $what
+ *
+ * @return \Illuminate\Http\JsonResponse
+ * @throws FireflyException
+ */
+ public function json($what = 'default')
+ {
+ /** @var \FireflyIII\Database\Account $acct */
+ $acct = App::make('FireflyIII\Database\Account');
+
+ /** @var \FireflyIII\Shared\Json\Json $json */
+ $json = App::make('FireflyIII\Shared\Json\Json');
+
+ $parameters = $json->dataTableParameters();
+
+ switch ($what) {
+ default:
+ throw new FireflyException('Cannot handle account type "' . e($what) . '".');
+ break;
+ case 'asset':
+ $accounts = $acct->getAssetAccounts($parameters);
+ $count = $acct->countAssetAccounts();
+ break;
+ case 'expense':
+ $accounts = $acct->getExpenseAccounts($parameters);
+ $count = $acct->countExpenseAccounts();
+ break;
+ case 'revenue':
+ $accounts = $acct->getRevenueAccounts($parameters);
+ $count = $acct->countRevenueAccounts();
+ break;
+ }
+
+ /*
+ * Output the set compatible with data tables:
+ */
+ $return = [
+ 'draw' => intval(Input::get('draw')),
+ 'recordsTotal' => $count,
+ 'recordsFiltered' => $accounts->count(),
+ 'data' => [],
+ ];
+
+ /*
+ * Loop the accounts:
+ */
+ /** @var \Account $account */
+ foreach ($accounts as $account) {
+ $entry = [
+ 'name' => ['name' => $account->name, 'url' => route('accounts.show', $account->id)],
+ 'balance' => $account->balance(),
+ 'id' => [
+ 'edit' => route('accounts.edit', $account->id),
+ 'delete' => route('accounts.delete', $account->id),
+ ]
+ ];
+ $return['data'][] = $entry;
+ }
+
+
+ return Response::jsoN($return);
+ }
+
/**
* @return \Illuminate\View\View
*/
@@ -43,52 +128,7 @@ class AccountController extends \BaseController
break;
}
-
- return View::make('accounts.create')->with('subTitle', 'Create a new ' . $what . ' account')->with(
- 'what', $what
- );
- }
-
- /**
- * @return $this
- */
- public function asset()
- {
- View::share('subTitleIcon', 'fa-money');
-
- $accounts = $this->_repository->getOfTypes(['Asset account', 'Default account']);
-
- return View::make('accounts.asset')->with('subTitle', 'Asset accounts')->with(
- 'accounts', $accounts
- );
- }
-
- /**
- * @return $this
- */
- public function expense()
- {
- View::share('subTitleIcon', 'fa-shopping-cart');
-
- $accounts = $this->_repository->getOfTypes(['Expense account', 'Beneficiary account']);
-
- return View::make('accounts.expense')->with('subTitle', 'Expense accounts')->with(
- 'accounts', $accounts
- );
- }
-
- /**
- * @return $this
- */
- public function revenue()
- {
- View::share('subTitleIcon', 'fa-download');
-
- $accounts = $this->_repository->getOfTypes(['Revenue account']);
-
- return View::make('accounts.revenue')->with('subTitle', 'Revenue accounts')->with(
- 'accounts', $accounts
- );
+ return View::make('accounts.create')->with('subTitle', 'Create a new ' . $what . ' account')->with('what', $what);
}
/**
@@ -99,9 +139,9 @@ class AccountController extends \BaseController
public function delete(Account $account)
{
return View::make('accounts.delete')->with('account', $account)
- ->with(
- 'subTitle', 'Delete ' . strtolower($account->accountType->type) . ' "' . $account->name . '"'
- );
+ ->with(
+ 'subTitle', 'Delete ' . strtolower($account->accountType->type) . ' "' . $account->name . '"'
+ );
}
/**
@@ -111,20 +151,67 @@ class AccountController extends \BaseController
*/
public function destroy(Account $account)
{
+
$type = $account->accountType->type;
- $this->_repository->destroy($account);
+
+ /** @var \FireflyIII\Database\Account $acct */
+ $acct = App::make('FireflyIII\Database\Account');
+
+ /** @var \FireflyIII\Database\TransactionJournal $jrnls */
+ $jrnls = App::make('FireflyIII\Database\TransactionJournal');
+
+ /*
+ * Find the "initial balance account", should it exist:
+ */
+ $initialBalance = $acct->findInitialBalanceAccount($account);
+
+ /*
+ * Get all the transaction journals that are part of this/these account(s):
+ */
+ $journals = [];
+ if ($initialBalance) {
+ $transactions = $initialBalance->transactions()->get();
+ /** @var \Transaction $transaction */
+ foreach ($transactions as $transaction) {
+ $journals[] = $transaction->transaction_journal_id;
+ }
+ }
+ /** @var \Transaction $transaction */
+ foreach ($account->transactions() as $transaction) {
+ $journals[] = $transaction->transaction_journal_id;
+ }
+
+ $journals = array_unique($journals);
+
+ /*
+ * Delete the journals. Should get rid of the transactions as well.
+ */
+ foreach ($journals as $id) {
+ $journal = $jrnls->find($id);
+ $journal->delete();
+ }
+
+ /*
+ * Delete it
+ */
+ if ($initialBalance) {
+ $acct->destroy($initialBalance);
+ }
+
+ $acct->destroy($account);
+
Session::flash('success', 'The account was deleted.');
switch ($type) {
case 'Asset account':
case 'Default account':
- return Redirect::route('accounts.asset');
+ return Redirect::route('accounts.index', 'asset');
break;
case 'Expense account':
case 'Beneficiary account':
- return Redirect::route('accounts.expense');
+ return Redirect::route('accounts.index', 'expense');
break;
case 'Revenue account':
- return Redirect::route('accounts.revenue');
+ return Redirect::route('accounts.index', 'revenue');
break;
}
@@ -153,18 +240,23 @@ class AccountController extends \BaseController
break;
}
- $openingBalance = $this->_accounts->openingBalanceTransaction($account);
- return View::make('accounts.edit')->with('account', $account)->with('openingBalance', $openingBalance)
+ /** @var \FireflyIII\Database\Account $acct */
+ $acct = App::make('FireflyIII\Database\Account');
- ->with('subTitle', 'Edit ' . strtolower($account->accountType->type) . ' "' . $account->name . '"');
- }
+ $openingBalance = $acct->openingBalanceTransaction($account);
+ Session::forget('prefilled');
+ if (!is_null($openingBalance)) {
+ $prefilled['openingbalancedate'] = $openingBalance->date->format('Y-m-d');
+ $prefilled['openingbalance'] = floatval($openingBalance->transactions()->where('account_id', $account->id)->first()->amount);
+ Session::flash('prefilled', $prefilled);
+ }
- /**
- * @return $this
- */
- public function index()
- {
- return View::make('error')->with('message', 'This view has been disabled');
+
+ return View::make('accounts.edit')->with('account', $account)->with('openingBalance', $openingBalance)->with(
+ 'subTitle', 'Edit ' . strtolower(
+ $account->accountType->type
+ ) . ' "' . $account->name . '"'
+ );
}
/**
@@ -189,86 +281,116 @@ class AccountController extends \BaseController
}
- $data = $this->_accounts->show($account, 40);
-
- return View::make('accounts.show')->with('account', $account)->with('show', $data)->with(
- 'subTitle',
- 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"'
- );
+ //$data = $this->_accounts->show($account, 40);
+ return View::make('accounts.show')
+ ->with('account', $account)
+ ->with('subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"');
}
/**
* @return $this|\Illuminate\Http\RedirectResponse
+ * @throws FireflyException
*/
public function store()
{
$data = Input::all();
$data['what'] = isset($data['what']) && $data['what'] != '' ? $data['what'] : 'asset';
+ /** @var \FireflyIII\Database\Account $acct */
+ $acct = App::make('FireflyIII\Database\Account');
-
- switch ($data['what']) {
+ switch ($data['post_submit_action']) {
default:
- case 'asset':
- $data['account_type'] = 'Asset account';
- break;
- case 'expense':
- $data['account_type'] = 'Expense account';
- break;
- case 'revenue':
- $data['account_type'] = 'Revenue account';
+ throw new FireflyException('Cannot handle post_submit_action "' . e($data['post_submit_action']) . '"');
break;
+ case 'create_another':
+ case 'store':
+ $messages = $acct->validate($data);
+ /** @var MessageBag $messages ['errors'] */
+ if ($messages['errors']->count() > 0) {
+ Session::flash('warnings', $messages['warnings']);
+ Session::flash('successes', $messages['successes']);
+ Session::flash('error', 'Could not save account: ' . $messages['errors']->first());
+ return Redirect::route('accounts.create', $data['what'])->withInput()->withErrors($messages['errors']);
+ }
+ // store!
+ $acct->store($data);
+ Session::flash('success', 'New account stored!');
- }
- $account = $this->_repository->store($data);
-
- if ($account->validate()) {
- // saved! return to wherever.
- Session::flash('success', 'Account "' . $account->name . '" created!');
- if (intval(Input::get('create')) === 1) {
+ if ($data['post_submit_action'] == 'create_another') {
+ return Redirect::route('accounts.create', $data['what']);
+ } else {
+ return Redirect::route('accounts.index', $data['what']);
+ }
+ break;
+ case 'validate_only':
+ $messageBags = $acct->validate($data);
+ Session::flash('warnings', $messageBags['warnings']);
+ Session::flash('successes', $messageBags['successes']);
+ Session::flash('errors', $messageBags['errors']);
return Redirect::route('accounts.create', $data['what'])->withInput();
- } else {
-
- return Redirect::route('accounts.' . e($data['what']));
- }
- } else {
- // did not save, return with error:
- Session::flash('error', 'Could not save the new account: ' . $account->errors()->first());
-
- return Redirect::route('accounts.create', $data['what'])->withErrors($account->errors())->withInput();
-
+ break;
}
}
/**
* @param Account $account
*
- * @return $this|\Illuminate\Http\RedirectResponse
+ * @return $this
+ * @throws FireflyException
*/
public function update(Account $account)
{
- /** @var \Account $account */
- $account = $this->_repository->update($account, Input::all());
- if ($account->validate()) {
- Session::flash('success', 'Account "' . $account->name . '" updated.');
- switch ($account->accountType->type) {
- case 'Asset account':
- case 'Default account':
- return Redirect::route('accounts.asset');
- break;
- case 'Expense account':
- case 'Beneficiary account':
- return Redirect::route('accounts.expense');
- break;
- case 'Revenue account':
- return Redirect::route('accounts.revenue');
- break;
- }
- } else {
- Session::flash('error', 'Could not update account: ' . $account->errors()->first());
+ /** @var \FireflyIII\Database\Account $acct */
+ $acct = App::make('FireflyIII\Database\Account');
+ $data = Input::except('_token');
- return Redirect::route('accounts.edit', $account->id)->withInput()->withErrors($account->errors());
+ switch ($account->accountType->type) {
+ default:
+ throw new FireflyException('Cannot handle account type "' . e($account->accountType->type) . '"');
+ break;
+ case 'Default account':
+ $data['what'] = 'asset';
+ break;
+ case 'Beneficiary account':
+ $data['what'] = 'expense';
+ break;
+ case 'Revenue account':
+ $data['what'] = 'revenue';
+ break;
+ }
+
+ switch (Input::get('post_submit_action')) {
+ default:
+ throw new FireflyException('Cannot handle post_submit_action "' . e(Input::get('post_submit_action')) . '"');
+ break;
+ case 'create_another':
+ case 'update':
+ $messages = $acct->validate($data);
+ /** @var MessageBag $messages ['errors'] */
+ if ($messages['errors']->count() > 0) {
+ Session::flash('warnings', $messages['warnings']);
+ Session::flash('successes', $messages['successes']);
+ Session::flash('error', 'Could not save account: ' . $messages['errors']->first());
+ return Redirect::route('accounts.edit', $account->id)->withInput()->withErrors($messages['errors']);
+ }
+ // store!
+ $acct->update($account, $data);
+ Session::flash('success', 'Account updated!');
+
+ if ($data['post_submit_action'] == 'create_another') {
+ return Redirect::route('accounts.edit', $account->id);
+ } else {
+ return Redirect::route('accounts.index',$data['what']);
+ }
+ case 'validate_only':
+ $messageBags = $acct->validate($data);
+ Session::flash('warnings', $messageBags['warnings']);
+ Session::flash('successes', $messageBags['successes']);
+ Session::flash('errors', $messageBags['errors']);
+ return Redirect::route('accounts.edit', $account->id)->withInput();
+ break;
}
}
diff --git a/app/controllers/BudgetController.php b/app/controllers/BudgetController.php
index 6ed90c18f5..78f7dc2dd8 100644
--- a/app/controllers/BudgetController.php
+++ b/app/controllers/BudgetController.php
@@ -4,72 +4,175 @@ use Carbon\Carbon;
use Firefly\Exception\FireflyException;
use Firefly\Helper\Controllers\BudgetInterface as BI;
use Firefly\Storage\Budget\BudgetRepositoryInterface as BRI;
+use FireflyIII\Exception\NotImplementedException;
+use Illuminate\Support\MessageBag;
+
/**
* Class BudgetController
- *
- * @SuppressWarnings(PHPMD.CamelCasePropertyName)
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- *
*/
class BudgetController extends BaseController
{
- protected $_budgets;
- protected $_repository;
- /**
- * @param BI $budgets
- * @param BRI $repository
- */
- public function __construct(BI $budgets, BRI $repository)
+ public function __construct()
{
- $this->_budgets = $budgets;
- $this->_repository = $repository;
View::share('title', 'Budgets');
View::share('mainTitleIcon', 'fa-tasks');
}
- public function nobudget($view = 'session') {
- switch($view) {
- default:
- throw new FireflyException('Cannot show transactions without a budget for view "'.$view.'".');
- break;
- case 'session':
- $start = Session::get('start');
- $end = Session::get('end');
- break;
- }
+ /**
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function postUpdateIncome()
+ {
+ /** @var \Firefly\Helper\Preferences\PreferencesHelperInterface $preferences */
+ $preferences = App::make('Firefly\Helper\Preferences\PreferencesHelperInterface');
+ $date = Session::get('start');
- // Add expenses that have no budget:
- $set = \Auth::user()->transactionjournals()->whereNotIn(
- 'transaction_journals.id', function ($query) use ($start, $end) {
- $query->select('transaction_journals.id')->from('transaction_journals')
- ->leftJoin(
- 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=',
- 'transaction_journals.id'
- )
- ->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')
- ->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
- ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
- ->where('components.class', 'Budget');
- }
- )->before($end)->after($start)->get();
-
- return View::make('budgets.nobudget')
- ->with('view', $view)
- ->with('transactions',$set)
- ->with('subTitle', 'Transactions without a budget');
+ $value = intval(Input::get('amount'));
+ $preferences->set('budgetIncomeTotal' . $date->format('FY'), $value);
+ return Redirect::route('budgets.index');
}
/**
- * @return $this|\Illuminate\View\View
+ * Update the amount for a budget's limitrepetition and/or create it.
+ *
+ * @param Budget $budget
+ */
+ public function amount(Budget $budget)
+ {
+ $amount = intval(Input::get('amount'));
+ $date = Session::get('start');
+ /** @var \Limit $limit */
+ $limit = $budget->limits()->where('startdate', $date->format('Y-m-d'))->first();
+ if (!$limit) {
+ // create one!
+ $limit = new Limit;
+ $limit->budget()->associate($budget);
+ $limit->startdate = $date;
+ $limit->amount = $amount;
+ $limit->repeat_freq = 'monthly';
+ $limit->repeats = 0;
+ $limit->save();
+ Event::fire('limits.store', [$limit]);
+
+ } else {
+ if ($amount > 0) {
+ $limit->amount = $amount;
+ $limit->save();
+ Event::fire('limits.update', [$limit]);
+ } else {
+ $limit->delete();
+ }
+ }
+ // try to find the limit repetition for this limit:
+ $repetition = $limit->limitrepetitions()->first();
+ if ($repetition) {
+ return Response::json(['name' => $budget->name, 'repetition' => $repetition->id]);
+ } else {
+ return Response::json(['name' => $budget->name, 'repetition' => null]);
+ }
+
+ }
+
+ public function index()
+ {
+
+ /** @var \Firefly\Helper\Preferences\PreferencesHelperInterface $preferences */
+ $preferences = App::make('Firefly\Helper\Preferences\PreferencesHelperInterface');
+ $date = Session::get('start');
+
+ /** @var \FireflyIII\Database\Budget $repos */
+ $repos = App::make('FireflyIII\Database\Budget');
+ $budgets = $repos->get();
+
+ // get the limits for the current month.
+ $date = \Session::get('start');
+ $spent = 0;
+ /** @var \Budget $budget */
+ foreach ($budgets as $budget) {
+
+ $budget->spent = $repos->spentInMonth($budget, $date);
+ $spent += $budget->spent;
+ $budget->pct = 0;
+ $budget->limit = 0;
+
+ /** @var \Limit $limit */
+ foreach ($budget->limits as $limit) {
+ /** @var \LimitRepetition $repetition */
+ foreach ($limit->limitrepetitions as $repetition) {
+ if ($repetition->startdate == $date) {
+ $budget->currentRep = $repetition;
+ $budget->limit = floatval($repetition->amount);
+ if ($budget->limit > $budget->spent) {
+ // not overspent:
+ $budget->pct = 30;
+ } else {
+ $budget->pct = 50;
+ }
+
+ }
+ }
+ }
+ }
+
+ $budgetAmount = $preferences->get('budgetIncomeTotal' . $date->format('FY'), 1000);
+ $amount = floatval($budgetAmount->data);
+ $overspent = $spent > $amount;
+ if($overspent) {
+ // overspent on total amount
+ $spentPCT = ceil($amount / $spent * 100);
+ } else {
+ // not overspent on total amount.
+ $spentPCT = ceil($spent / $amount * 100);
+ }
+
+ return View::make('budgets.index', compact('budgets','spent','spentPCT','overspent'))->with('budgetAmount', $budgetAmount);
+ }
+
+ /**
+ * @return $this
+ */
+ public function updateIncome()
+ {
+ $date = Session::get('start');
+ /** @var \Firefly\Helper\Preferences\PreferencesHelperInterface $preferences */
+ $preferences = App::make('Firefly\Helper\Preferences\PreferencesHelperInterface');
+ $budgetAmount = $preferences->get('budgetIncomeTotal' . $date->format('FY'), 1000);
+ return View::make('budgets.income')->with('amount', $budgetAmount)->with('date', $date);
+ }
+
+ /**
+ * @param Budget $budget
+ * @param LimitRepetition $repetition
+ *
+ * @return \Illuminate\View\View
+ */
+ public function show(Budget $budget, LimitRepetition $repetition = null)
+ {
+ if (!is_null($repetition) && $repetition->limit->budget->id != $budget->id) {
+ App::abort(500);
+ }
+
+ if (is_null($repetition)) {
+ // get all other repetitions:
+ $limits = $budget->limits()->orderBy('startdate', 'DESC')->get();
+
+ } else {
+ // get nothing? i dunno
+ $limits = [$repetition->limit];
+ }
+
+ return View::make('budgets.show', compact('limits', 'budget', 'repetition'));
+ }
+
+ /**
+ * @return $this
*/
public function create()
{
- $periods = \Config::get('firefly.periods_to_text');
-
- return View::make('budgets.create')->with('periods', $periods)->with('subTitle', 'Create a new budget');
+ return View::make('budgets.create')->with('subTitle', 'Create a new budget');
}
/**
@@ -79,27 +182,17 @@ class BudgetController extends BaseController
*/
public function delete(Budget $budget)
{
- return View::make('budgets.delete')->with('budget', $budget)
- ->with('subTitle', 'Delete budget "' . $budget->name . '"');
+ return View::make('budgets.delete')->with('budget', $budget)->with('subTitle', 'Delete budget "' . $budget->name . '"');
}
- /**
- * @param Budget $budget
- *
- * @return \Illuminate\Http\RedirectResponse
- */
public function destroy(Budget $budget)
{
+ /** @var \FireflyIII\Database\Budget $repos */
+ $repos = App::make('FireflyIII\Database\Budget');
// remove budget
- Event::fire('budgets.destroy', [$budget]); // just before deletion.
- $this->_repository->destroy($budget);
+ $repos->destroy($budget);
Session::flash('success', 'The budget was deleted.');
-
- // redirect:
- if (Input::get('from') == 'date') {
- return Redirect::route('budgets.index');
- }
- return Redirect::route('budgets.index.budget');
+ return Redirect::route('budgets.index');
}
@@ -110,142 +203,96 @@ class BudgetController extends BaseController
*/
public function edit(Budget $budget)
{
- return View::make('budgets.edit')->with('budget', $budget)
- ->with('subTitle', 'Edit budget "' . $budget->name . '"');
+ Session::flash('prefilled', ['name' => $budget->name]);
+ return View::make('budgets.edit')->with('budget', $budget)->with('subTitle', 'Edit budget "' . $budget->name . '"');
}
- /**
- * @return $this|\Illuminate\View\View
- */
- public function indexByBudget()
- {
- View::share('subTitleIcon', 'fa-folder-open');
-
- $budgets = $this->_repository->get();
-
- return View::make('budgets.indexByBudget')->with('budgets', $budgets)->with('today', new Carbon)
- ->with('subTitle', 'Grouped by budget');
-
- }
-
- /**
- * @return $this
- */
- public function indexByDate()
- {
- View::share('subTitleIcon', 'fa-calendar');
-
- // get a list of dates by getting all repetitions:
- $set = $this->_repository->get();
- $budgets = $this->_budgets->organizeByDate($set);
-
- return View::make('budgets.indexByDate')->with('budgets', $budgets)
- ->with('subTitle', 'Grouped by date');
-
-
- }
-
- /**
- * Three use cases for this view:
- *
- * - Show everything.
- * - Show a specific repetition.
- * - Show everything shows NO repetition.
- *
- * @param Budget $budget
- * @param LimitRepetition $repetition
- *
- * @return int
- */
- public function show(Budget $budget, \LimitRepetition $repetition = null)
- {
- $useSessionDates = Input::get('useSession') == 'true' ? true : false;
- $view = null;
- $title = null;
- \Log::debug('Is envelope true? ' . (Input::get('noenvelope') == 'true'));
- switch (true) {
- case (!is_null($repetition)):
- $data = $this->_budgets->organizeRepetition($repetition);
- $view = 1;
- $title = $budget->name . ', ' . $repetition->periodShow() . ', ' . mf(
- $repetition->limit->amount,
- false
- );
- break;
- case (Input::get('noenvelope') == 'true'):
- $data = $this->_budgets->outsideRepetitions($budget);
- $view = 2;
- $title = $budget->name . ', transactions outside an envelope';
- break;
- default:
- $data = $this->_budgets->organizeRepetitions($budget, $useSessionDates);
- $view = $useSessionDates ? 3 : 4;
- $title = $useSessionDates ? $budget->name . ' in session period' : $budget->name;
- break;
- }
-
- return View::make('budgets.show')
- ->with('budget', $budget)
- ->with('repetitions', $data)
- ->with('view', $view)
- ->with('highlight', Input::get('highlight'))
- ->with('useSessionDates', $useSessionDates)
- ->with('subTitle', 'Overview for ' . $title);
- }
-
/**
* @return \Illuminate\Http\RedirectResponse
*/
public function store()
{
+ /** @var \FireflyIII\Database\Budget $repos */
+ $repos = App::make('FireflyIII\Database\Budget');
+ $data = Input::except('_token');
- $budget = $this->_repository->store(Input::all());
- if ($budget->validate()) {
- Event::fire('budgets.store', [$budget]);
- Session::flash('success', 'Budget created!');
+ switch ($data['post_submit_action']) {
+ default:
+ throw new FireflyException('Cannot handle post_submit_action "' . e($data['post_submit_action']) . '"');
+ break;
+ case 'create_another':
+ case 'store':
+ $messages = $repos->validate($data);
+ /** @var MessageBag $messages ['errors'] */
+ if ($messages['errors']->count() > 0) {
+ Session::flash('warnings', $messages['warnings']);
+ Session::flash('successes', $messages['successes']);
+ Session::flash('error', 'Could not save budget: ' . $messages['errors']->first());
+ return Redirect::route('budgets.create')->withInput()->withErrors($messages['errors']);
+ }
+ // store!
+ $repos->store($data);
+ Session::flash('success', 'New budget stored!');
- if (Input::get('create') == '1') {
- return Redirect::route('budgets.create', ['from' => Input::get('from')]);
- }
-
- if (Input::get('from') == 'date') {
- return Redirect::route('budgets.index');
- } else {
- return Redirect::route('budgets.index.budget');
- }
- } else {
- Session::flash('error', 'Could not save the new budget');
-
- return Redirect::route('budgets.create')->withInput()->withErrors($budget->errors());
+ if ($data['post_submit_action'] == 'create_another') {
+ return Redirect::route('budgets.create');
+ } else {
+ return Redirect::route('budgets.index');
+ }
+ break;
+ case 'validate_only':
+ $messageBags = $repos->validate($data);
+ Session::flash('warnings', $messageBags['warnings']);
+ Session::flash('successes', $messageBags['successes']);
+ Session::flash('errors', $messageBags['errors']);
+ return Redirect::route('budgets.create')->withInput();
+ break;
}
-
}
/**
* @param Budget $budget
*
- * @return $this|\Illuminate\Http\RedirectResponse
+ * @throws FireflyException
*/
public function update(Budget $budget)
{
- $budget = $this->_repository->update($budget, Input::all());
- if ($budget->validate()) {
- Event::fire('budgets.update', [$budget]);
- Session::flash('success', 'Budget "' . $budget->name . '" updated.');
- if (Input::get('from') == 'date') {
- return Redirect::route('budgets.index');
- } else {
- return Redirect::route('budgets.index.budget');
- }
- } else {
- Session::flash('error', 'Could not update budget: ' . $budget->errors()->first());
+ /** @var \FireflyIII\Database\Budget $repos */
+ $repos = App::make('FireflyIII\Database\Budget');
+ $data = Input::except('_token');
- return Redirect::route('budgets.edit', $budget->id)->withInput()->withErrors($budget->errors());
+ switch (Input::get('post_submit_action')) {
+ default:
+ throw new FireflyException('Cannot handle post_submit_action "' . e(Input::get('post_submit_action')) . '"');
+ break;
+ case 'create_another':
+ case 'update':
+ $messages = $repos->validate($data);
+ /** @var MessageBag $messages ['errors'] */
+ if ($messages['errors']->count() > 0) {
+ Session::flash('warnings', $messages['warnings']);
+ Session::flash('successes', $messages['successes']);
+ Session::flash('error', 'Could not save budget: ' . $messages['errors']->first());
+ return Redirect::route('budgets.edit', $budget->id)->withInput()->withErrors($messages['errors']);
+ }
+ // store!
+ $repos->update($budget, $data);
+ Session::flash('success', 'Budget updated!');
+
+ if ($data['post_submit_action'] == 'create_another') {
+ return Redirect::route('budgets.edit', $budget->id);
+ } else {
+ return Redirect::route('budgets.index');
+ }
+ case 'validate_only':
+ $messageBags = $repos->validate($data);
+ Session::flash('warnings', $messageBags['warnings']);
+ Session::flash('successes', $messageBags['successes']);
+ Session::flash('errors', $messageBags['errors']);
+ return Redirect::route('budgets.edit', $budget->id)->withInput();
+ break;
}
-
}
-
-
-}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php
new file mode 100644
index 0000000000..daeedcfddd
--- /dev/null
+++ b/app/controllers/GoogleChartController.php
@@ -0,0 +1,600 @@
+addColumn('Day of the month', 'date');
+
+ /** @var \FireflyIII\Shared\Preferences\Preferences $preferences */
+ $preferences = App::make('FireflyIII\Shared\Preferences\Preferences');
+ $pref = $preferences->get('frontpageAccounts');
+
+ /** @var \FireflyIII\Database\Account $acct */
+ $acct = App::make('FireflyIII\Database\Account');
+ $accounts = $acct->getByIds($pref->data);
+
+
+ /*
+ * Add a column for each account.
+ */
+ /** @var Account $account */
+ foreach ($accounts as $account) {
+ $chart->addColumn('Balance for ' . $account->name, 'number');
+ }
+ /*
+ * Loop the date, then loop the accounts, then add balance.
+ */
+ $start = Session::get('start');
+ $end = Session::get('end');
+ $current = clone $start;
+
+ while ($end >= $current) {
+ $row = [clone $current];
+
+ foreach ($accounts as $account) {
+ //if ($current > Carbon::now()) {
+ // $row[] = 0;
+ //} else {
+ $row[] = $account->balance($current);
+ //}
+
+ }
+
+ $chart->addRowArray($row);
+ $current->addDay();
+ }
+
+ $chart->generate();
+ return Response::json($chart->getData());
+
+ }
+
+ /**
+ * @param $year
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function yearInExp($year)
+ {
+ try {
+ $start = new Carbon('01-01-' . $year);
+ } catch (Exception $e) {
+ App::abort(500);
+ }
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('Month', 'date');
+ $chart->addColumn('Income', 'number');
+ $chart->addColumn('Expenses', 'number');
+
+ /** @var \FireflyIII\Database\TransactionJournal $tj */
+ $tj = App::make('FireflyIII\Database\TransactionJournal');
+
+ $end = clone $start;
+ $end->endOfYear();
+ while ($start < $end) {
+
+ // total income:
+ $income = $tj->getSumOfIncomesByMonth($start);
+ $expense = $tj->getSumOfExpensesByMonth($start);
+
+ $chart->addRow(clone $start, $income, $expense);
+ $start->addMonth();
+ }
+
+
+ $chart->generate();
+ return Response::json($chart->getData());
+
+ }
+
+ /**
+ * @param $year
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function yearInExpSum($year)
+ {
+ try {
+ $start = new Carbon('01-01-' . $year);
+ } catch (Exception $e) {
+ App::abort(500);
+ }
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('Summary', 'string');
+ $chart->addColumn('Income', 'number');
+ $chart->addColumn('Expenses', 'number');
+
+ /** @var \FireflyIII\Database\TransactionJournal $tj */
+ $tj = App::make('FireflyIII\Database\TransactionJournal');
+
+ $end = clone $start;
+ $end->endOfYear();
+ $income = 0;
+ $expense = 0;
+ $count = 0;
+ while ($start < $end) {
+
+ // total income:
+ $income += $tj->getSumOfIncomesByMonth($start);
+ $expense += $tj->getSumOfExpensesByMonth($start);
+ $count++;
+
+ $start->addMonth();
+ }
+ $chart->addRow('Sum', $income, $expense);
+ $count = $count > 0 ? $count : 1;
+ $chart->addRow('Average', ($income / $count), ($expense / $count));
+
+
+ $chart->generate();
+ return Response::json($chart->getData());
+
+ }
+
+
+ /**
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function budgetsReportChart($year)
+ {
+
+ try {
+ $start = new Carbon('01-01-' . $year);
+ } catch (Exception $e) {
+ App::abort(500);
+ }
+
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+
+ /** @var \FireflyIII\Database\Budget $bdt */
+ $bdt = App::make('FireflyIII\Database\Budget');
+ $budgets = $bdt->get();
+
+ $chart->addColumn('Month', 'date');
+ /** @var \Budget $budget */
+ foreach ($budgets as $budget) {
+ $chart->addColumn($budget->name, 'number');
+ }
+ $chart->addColumn('No budget','number');
+
+ /*
+ * Loop budgets this year.
+ */
+ $end = clone $start;
+ $end->endOfYear();
+ while ($start <= $end) {
+ $row = [clone $start];
+
+ foreach($budgets as $budget) {
+ $row[] = $bdt->spentInMonth($budget, $start);
+ }
+
+ /*
+ * Without a budget:
+ */
+ $endOfMonth = clone $start;
+ $endOfMonth->endOfMonth();
+ $set = $bdt->transactionsWithoutBudgetInDateRange($start, $endOfMonth);
+ $row[] = floatval($set->sum('amount')) * -1;
+
+ $chart->addRowArray($row);
+ $start->addMonth();
+ }
+
+
+ $chart->generate();
+ return Response::json($chart->getData());
+ }
+
+ public function budgetsAndSpending(Budget $budget, $year) {
+ try {
+ $start = new Carbon('01-01-' . $year);
+ } catch (Exception $e) {
+ App::abort(500);
+ }
+
+ /** @var \FireflyIII\Database\Budget $bdt */
+ $bdt = App::make('FireflyIII\Database\Budget');
+
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('Month', 'date');
+ $chart->addColumn('Budgeted', 'number');
+ $chart->addColumn('Spent', 'number');
+
+ $end = clone $start;
+ $end->endOfYear();
+ while($start <= $end) {
+
+ $spent = $bdt->spentInMonth($budget, $start);
+ $repetition = $bdt->repetitionOnStartingOnDate($budget, $start);
+ if($repetition) {
+ $budgeted = floatval($repetition->amount);
+ } else {
+ $budgeted = 0;
+ }
+
+ $chart->addRow(clone $start, $budgeted, $spent);
+
+ $start->addMonth();
+ }
+
+
+
+ $chart->generate();
+ return Response::json($chart->getData());
+
+
+ }
+
+ /**
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function allBudgetsHomeChart()
+ {
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('Budget', 'string');
+ $chart->addColumn('Budgeted', 'number');
+ $chart->addColumn('Spent', 'number');
+
+ /** @var \FireflyIII\Database\Budget $bdt */
+ $bdt = App::make('FireflyIII\Database\Budget');
+ $budgets = $bdt->get();
+
+ /*
+ * Loop budgets:
+ */
+ /** @var Budget $budget */
+ foreach ($budgets as $budget) {
+
+ /*
+ * Is there a repetition starting on this particular date? We can use that.
+ */
+ /** @var \LimitRepetition $repetition */
+ $repetition = $bdt->repetitionOnStartingOnDate($budget, Session::get('start'));
+
+ /*
+ * If there is, use it. Otherwise, forget it.
+ */
+ if (is_null($repetition)) {
+ // use the session start and end for our search query
+ $searchStart = Session::get('start');
+ $searchEnd = Session::get('end');
+ // the limit is zero:
+ $limit = 0;
+
+ } else {
+ // use the limit's start and end for our search query
+ $searchStart = $repetition->startdate;
+ $searchEnd = $repetition->enddate;
+ // the limit is the repetitions limit:
+ $limit = floatval($repetition->amount);
+ }
+
+ /*
+ * No matter the result of the search for the repetition, get all the transactions associated
+ * with the budget, and sum up the expenses made.
+ */
+ $expenses = floatval($budget->transactionjournals()->before($searchEnd)->after($searchStart)->lessThan(0)->sum('amount')) * -1;
+ if ($expenses > 0) {
+ $chart->addRow($budget->name, $limit, $expenses);
+ }
+ }
+
+ /*
+ * Finally, get all transactions WITHOUT a budget and add those as well.
+ * (yes this method is oddly specific).
+ */
+ $noBudgetSet = $bdt->transactionsWithoutBudgetInDateRange(Session::get('start'), Session::get('end'));
+ $sum = $noBudgetSet->sum('amount') * -1;
+ $chart->addRow('No budget', 0, $sum);
+
+
+ $chart->generate();
+ return Response::json($chart->getData());
+ }
+
+ /**
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function allCategoriesHomeChart()
+ {
+ $data = [];
+
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('Category', 'string');
+ $chart->addColumn('Spent', 'number');
+
+ /** @var \FireflyIII\Database\TransactionJournal $tj */
+ $tj = App::make('FireflyIII\Database\TransactionJournal');
+
+ /*
+ * Get the journals:
+ */
+ $journals = $tj->getInDateRange(Session::get('start'), Session::get('end'));
+
+ /** @var \TransactionJournal $journal */
+ foreach ($journals as $journal) {
+ if ($journal->transactionType->type == 'Withdrawal') {
+ $amount = $journal->getAmount();
+ $category = $journal->categories()->first();
+ if (!is_null($category)) {
+ if (isset($data[$category->name])) {
+ $data[$category->name] += $amount;
+ } else {
+ $data[$category->name] = $amount;
+ }
+ }
+ }
+ }
+ arsort($data);
+ foreach ($data as $key => $entry) {
+ $chart->addRow($key, $entry);
+ }
+
+
+ $chart->generate();
+ return Response::json($chart->getData());
+
+ }
+
+ /**
+ * @return \Illuminate\Http\JsonResponse
+ * @throws \Firefly\Exception\FireflyException
+ */
+ public function recurringTransactionsOverview()
+ {
+
+ /*
+ * Set of paid transaction journals.
+ * Set of unpaid recurring transactions.
+ */
+ $paid = [
+ 'items' => [],
+ 'amount' => 0
+ ];
+ $unpaid = [
+ 'items' => [],
+ 'amount' => 0
+ ];
+
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('Name', 'string');
+ $chart->addColumn('Amount', 'number');
+
+ /** @var \FireflyIII\Database\Recurring $rcr */
+ $rcr = App::make('FireflyIII\Database\Recurring');
+
+ /** @var \FireflyIII\Shared\Toolkit\Date $dateKit */
+ $dateKit = App::make('FireflyIII\Shared\Toolkit\Date');
+
+ $recurring = $rcr->get();
+
+ /** @var \RecurringTransaction $entry */
+ foreach ($recurring as $entry) {
+ /*
+ * Start another loop starting at the $date.
+ */
+ $start = clone $entry->date;
+ $end = Carbon::now();
+
+ /*
+ * The jump we make depends on the $repeat_freq
+ */
+ $current = clone $start;
+
+ while ($current <= $end) {
+ /*
+ * Get end of period for $current:
+ */
+ $currentEnd = clone $current;
+ $dateKit->endOfPeriod($currentEnd, $entry->repeat_freq);
+
+ /*
+ * In the current session range?
+ */
+ if (\Session::get('end') >= $current and $currentEnd >= \Session::get('start')) {
+ /*
+ * Lets see if we've already spent money on this recurring transaction (it hath recurred).
+ */
+ /** @var TransactionJournal $set */
+ $journal = $rcr->getJournalForRecurringInRange($entry, $current, $currentEnd);
+
+ if (is_null($journal)) {
+ $unpaid['items'][] = $entry->name;
+ $unpaid['amount'] += (($entry->amount_max + $entry->amount_min) / 2);
+ } else {
+ $amount = $journal->getAmount();
+ $paid['items'][] = $journal->description;
+ $paid['amount'] += $amount;
+ }
+ }
+
+ /*
+ * Add some time for the next loop!
+ */
+ $dateKit->addPeriod($current, $entry->repeat_freq, intval($entry->skip));
+
+ }
+
+ }
+ /** @var \RecurringTransaction $entry */
+ $chart->addRow('Unpaid: ' . join(', ', $unpaid['items']), $unpaid['amount']);
+ $chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']);
+
+ $chart->generate();
+ return Response::json($chart->getData());
+
+ }
+
+ /**
+ * @param Account $account
+ */
+ public function accountBalanceChart(Account $account)
+ {
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('Day of month', 'date');
+ $chart->addColumn('Balance for ' . $account->name, 'number');
+
+ /*
+ * Loop the date, then loop the accounts, then add balance.
+ */
+ $start = Session::get('start');
+ $end = Session::get('end');
+ $current = clone $start;
+
+ while ($end >= $current) {
+ $row = [clone $current];
+ if ($current > Carbon::now()) {
+ $row[] = null;
+ } else {
+ $row[] = $account->balance($current);
+ }
+
+ $chart->addRowArray($row);
+ $current->addDay();
+ }
+
+
+ $chart->generate();
+ return Response::json($chart->getData());
+ }
+
+ /**
+ * @param Account $account
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function accountSankeyOutChart(Account $account)
+ {
+ // collect all relevant entries.
+ $set = [];
+
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('From', 'string');
+ $chart->addColumn('To', 'string', 'domain');
+ $chart->addColumn('Weight', 'number');
+
+ $transactions = $account->transactions()->with(
+ ['transactionjournal', 'transactionjournal.transactions', 'transactionjournal.budgets', 'transactionjournal.transactiontype',
+ 'transactionjournal.categories']
+ )->before(Session::get('end'))->after(
+ Session::get('start')
+ )->get();
+
+ /** @var Transaction $transaction */
+ foreach ($transactions as $transaction) {
+ $amount = floatval($transaction->amount);
+ $type = $transaction->transactionJournal->transactionType->type;
+
+ if ($amount < 0 && $type != 'Transfer') {
+
+ // from account to a budget (if present).
+ $budgetName = isset($transaction->transactionJournal->budgets[0]) ? $transaction->transactionJournal->budgets[0]->name : '(no budget)';
+ $set[] = [$account->name, $budgetName, $amount * -1];
+
+ // from budget to category.
+ $categoryName = isset($transaction->transactionJournal->categories[0]) ? ' ' . $transaction->transactionJournal->categories[0]->name
+ : '(no cat)';
+ $set[] = [$budgetName, $categoryName, $amount * -1];
+ }
+ }
+ // loop the set, group everything together:
+ $grouped = [];
+ foreach ($set as $entry) {
+ $key = $entry[0] . $entry[1];
+ if (isset($grouped[$key])) {
+ $grouped[$key][2] += $entry[2];
+ } else {
+ $grouped[$key] = $entry;
+ }
+ }
+
+ // add rows to the chart:
+ foreach ($grouped as $entry) {
+ $chart->addRow($entry[0], $entry[1], $entry[2]);
+ }
+
+ $chart->generate();
+ return Response::json($chart->getData());
+
+ }
+
+ /**
+ * @param Account $account
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function accountSankeyInChart(Account $account)
+ {
+ // collect all relevant entries.
+ $set = [];
+
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('From', 'string');
+ $chart->addColumn('To', 'string', 'domain');
+ $chart->addColumn('Weight', 'number');
+
+ $transactions = $account->transactions()->with(
+ ['transactionjournal', 'transactionjournal.transactions' => function ($q) {
+ $q->where('amount', '<', 0);
+ }, 'transactionjournal.budgets', 'transactionjournal.transactiontype', 'transactionjournal.categories']
+ )->before(Session::get('end'))->after(
+ Session::get('start')
+ )->get();
+
+ /** @var Transaction $transaction */
+ foreach ($transactions as $transaction) {
+ $amount = floatval($transaction->amount);
+ $type = $transaction->transactionJournal->transactionType->type;
+
+ if ($amount > 0 && $type != 'Transfer') {
+
+ $otherAccount = $transaction->transactionJournal->transactions[0]->account->name;
+ $categoryName = isset($transaction->transactionJournal->categories[0]) ? $transaction->transactionJournal->categories[0]->name
+ : '(no cat)';
+ $set[] = [$otherAccount, $categoryName, $amount];
+ $set[] = [$categoryName, $account->name, $amount];
+ }
+ }
+ // loop the set, group everything together:
+ $grouped = [];
+ foreach ($set as $entry) {
+ $key = $entry[0] . $entry[1];
+ if (isset($grouped[$key])) {
+ $grouped[$key][2] += $entry[2];
+ } else {
+ $grouped[$key] = $entry;
+ }
+ }
+
+ // add rows to the chart:
+ foreach ($grouped as $entry) {
+ $chart->addRow($entry[0], $entry[1], $entry[2]);
+ }
+
+ $chart->generate();
+ return Response::json($chart->getData());
+
+ }
+}
\ No newline at end of file
diff --git a/app/controllers/GoogleTableController.php b/app/controllers/GoogleTableController.php
new file mode 100644
index 0000000000..8f51270363
--- /dev/null
+++ b/app/controllers/GoogleTableController.php
@@ -0,0 +1,240 @@
+getAssetAccounts();
+ break;
+ case 'expense':
+ $list = $acct->getExpenseAccounts();
+ break;
+ case 'revenue':
+ $list = $acct->getRevenueAccounts();
+ break;
+ }
+
+
+ $chart = App::make('gchart');
+ $chart->addColumn('ID', 'number');
+ $chart->addColumn('ID_Edit', 'string');
+ $chart->addColumn('ID_Delete', 'string');
+ $chart->addColumn('Name_URL', 'string');
+ $chart->addColumn('Name', 'string');
+ $chart->addColumn('Balance', 'number');
+
+ /** @var \Account $entry */
+ foreach ($list as $entry) {
+ $edit = route('accounts.edit', $entry->id);
+ $delete = route('accounts.delete', $entry->id);
+ $show = route('accounts.show', $entry->id);
+ $chart->addRow($entry->id, $edit, $delete, $show, $entry->name, $entry->balance());
+ }
+
+ $chart->generate();
+ return Response::json($chart->getData());
+
+
+ }
+
+ /**
+ * @param Budget $budget
+ * @param LimitRepetition $repetition
+ */
+ public function transactionsByBudget(Budget $budget, LimitRepetition $repetition = null)
+ {
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('ID', 'number');
+ $chart->addColumn('ID_Edit', 'string');
+ $chart->addColumn('ID_Delete', 'string');
+ $chart->addColumn('Date', 'date');
+ $chart->addColumn('Description_URL', 'string');
+ $chart->addColumn('Description', 'string');
+ $chart->addColumn('Amount', 'number');
+ $chart->addColumn('From_URL', 'string');
+ $chart->addColumn('From', 'string');
+ $chart->addColumn('To_URL', 'string');
+ $chart->addColumn('To', 'string');
+ $chart->addColumn('Budget_URL', 'string');
+ $chart->addColumn('Budget', 'string');
+ $chart->addColumn('Category_URL', 'string');
+ $chart->addColumn('Category', 'string');
+
+ if (is_null($repetition)) {
+ $journals = $budget->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->orderBy('date', 'DESC')->get();
+ } else {
+ $journals = $budget->transactionjournals()->with(['budgets', 'categories', 'transactions', 'transactions.account'])->
+ after($repetition->startdate)->before($repetition->enddate)->orderBy('date', 'DESC')->get();
+ }
+ /** @var TransactionJournal $transaction */
+ foreach ($journals as $journal) {
+ $date = $journal->date;
+ $descriptionURL = route('transactions.show', $journal->id);
+ $description = $journal->description;
+ /** @var Transaction $transaction */
+ foreach ($journal->transactions as $transaction) {
+ if (floatval($transaction->amount) > 0) {
+ $amount = floatval($transaction->amount);
+ $to = $transaction->account->name;
+ $toURL = route('accounts.show', $transaction->account->id);
+ } else {
+ $from = $transaction->account->name;
+ $fromURL = route('accounts.show', $transaction->account->id);
+ }
+
+ }
+ if (isset($journal->budgets[0])) {
+ $budgetURL = route('budgets.show', $journal->budgets[0]->id);
+ $budget = $journal->budgets[0]->name;
+ } else {
+ $budgetURL = '';
+ $budget = '';
+ }
+
+ if (isset($journal->categories[0])) {
+ $categoryURL = route('categories.show', $journal->categories[0]->id);
+ $category = $journal->categories[0]->name;
+ } else {
+ $categoryURL = '';
+ $category = '';
+ }
+
+
+ $id = $journal->id;
+ $edit = route('transactions.edit', $journal->id);
+ $delete = route('transactions.delete', $journal->id);
+ $chart->addRow(
+ $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $budget, $categoryURL,
+ $category
+ );
+ }
+
+
+ $chart->generate();
+ return Response::json($chart->getData());
+
+ }
+
+ /**
+ * @param Account $account
+ */
+ public function transactionsByAccount(Account $account)
+ {
+ /** @var \Grumpydictator\Gchart\GChart $chart */
+ $chart = App::make('gchart');
+ $chart->addColumn('ID', 'number');
+ $chart->addColumn('ID_Edit', 'string');
+ $chart->addColumn('ID_Delete', 'string');
+ $chart->addColumn('Date', 'date');
+ $chart->addColumn('Description_URL', 'string');
+ $chart->addColumn('Description', 'string');
+ $chart->addColumn('Amount', 'number');
+ $chart->addColumn('From_URL', 'string');
+ $chart->addColumn('From', 'string');
+ $chart->addColumn('To_URL', 'string');
+ $chart->addColumn('To', 'string');
+ $chart->addColumn('Budget_URL', 'string');
+ $chart->addColumn('Budget', 'string');
+ $chart->addColumn('Category_URL', 'string');
+ $chart->addColumn('Category', 'string');
+
+ /*
+ * Find transactions:
+ */
+ $accountID = $account->id;
+ $transactions = $account->transactions()->with(
+ ['transactionjournal', 'transactionjournal.transactions' => function ($q) use ($accountID) {
+ $q->where('account_id', '!=', $accountID);
+ }, 'transactionjournal.budgets', 'transactionjournal.transactiontype',
+ 'transactionjournal.categories']
+ )->before(Session::get('end'))->after(
+ Session::get('start')
+ )->orderBy('date', 'DESC')->get();
+
+ /** @var Transaction $transaction */
+ foreach ($transactions as $transaction) {
+ $date = $transaction->transactionJournal->date;
+ $descriptionURL = route('transactions.show', $transaction->transaction_journal_id);
+ $description = $transaction->transactionJournal->description;
+ $amount = floatval($transaction->amount);
+
+ if ($transaction->transactionJournal->transactions[0]->account->id == $account->id) {
+ $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[1]->account->id);
+ $opposingAccountName = $transaction->transactionJournal->transactions[1]->account->name;
+ } else {
+ $opposingAccountURI = route('accounts.show', $transaction->transactionJournal->transactions[0]->account->id);
+ $opposingAccountName = $transaction->transactionJournal->transactions[0]->account->name;
+ }
+ if (isset($transaction->transactionJournal->budgets[0])) {
+ $budgetURL = route('budgets.show', $transaction->transactionJournal->budgets[0]->id);
+ $budget = $transaction->transactionJournal->budgets[0]->name;
+ } else {
+ $budgetURL = '';
+ $budget = '';
+ }
+
+ if (isset($transaction->transactionJournal->categories[0])) {
+ $categoryURL = route('categories.show', $transaction->transactionJournal->categories[0]->id);
+ $category = $transaction->transactionJournal->categories[0]->name;
+ } else {
+ $categoryURL = '';
+ $category = '';
+ }
+
+
+ if ($amount < 0) {
+ $from = $account->name;
+ $fromURL = route('accounts.show', $account->id);
+
+ $to = $opposingAccountName;
+ $toURL = $opposingAccountURI;
+ } else {
+ $to = $account->name;
+ $toURL = route('accounts.show', $account->id);
+
+ $from = $opposingAccountName;
+ $fromURL = $opposingAccountURI;
+ }
+
+ $id = $transaction->transactionJournal->id;
+ $edit = route('transactions.edit', $transaction->transactionJournal->id);
+ $delete = route('transactions.delete', $transaction->transactionJournal->id);
+ $chart->addRow(
+ $id, $edit, $delete, $date, $descriptionURL, $description, $amount, $fromURL, $from, $toURL, $to, $budgetURL, $budget, $categoryURL, $category
+ );
+ }
+
+//
Date |
+// Description |
+// Amount (€) |
+// From |
+// To |
+// Budget / category |
+// ID |
+
+
+ $chart->generate();
+ return Response::json($chart->getData());
+ }
+}
\ No newline at end of file
diff --git a/app/controllers/HomeController.php b/app/controllers/HomeController.php
index 0f2a049c9d..ffd33b86cd 100644
--- a/app/controllers/HomeController.php
+++ b/app/controllers/HomeController.php
@@ -15,8 +15,8 @@ class HomeController extends BaseController
protected $_journal;
/**
- * @param ARI $accounts
- * @param PHI $preferences
+ * @param ARI $accounts
+ * @param PHI $preferences
* @param TJRI $journal
*/
public function __construct(ARI $accounts, PHI $preferences, TJRI $journal)
@@ -115,4 +115,59 @@ class HomeController extends BaseController
return View::make('index')->with('count', $count)->with('transactions', $transactions)->with('title', 'Firefly')
->with('subTitle', 'What\'s playing?')->with('mainTitleIcon', 'fa-fire');
}
+
+ public function cleanup()
+ {
+ /** @var \FireflyIII\Database\TransactionJournal $jrnls */
+ $jrnls = App::make('FireflyIII\Database\TransactionJournal');
+
+ /** @var \FireflyIII\Database\Account $acct */
+ $acct = \App::make('FireflyIII\Database\Account');
+
+ /** @var \FireflyIII\Database\AccountType $acctType */
+ $acctType = \App::make('FireflyIII\Database\AccountType');
+ $rightAcctType = $acctType->findByWhat('revenue');
+
+ $all = $jrnls->get();
+
+ /** @var \TransactionJournal $entry */
+ foreach ($all as $entry) {
+ $wrongFromType = false;
+ $wrongToType = false;
+ $transactions = $entry->transactions;
+ if (count($transactions) == 2) {
+ switch ($entry->transactionType->type) {
+ case 'Deposit':
+ /** @var \Transaction $transaction */
+ foreach ($transactions as $transaction) {
+ if (floatval($transaction->amount) < 0) {
+ $accountType = $transaction->account->accountType;
+ if ($accountType->type == 'Beneficiary account') {
+ // should be a Revenue account!
+ $name = $transaction->account->name;
+ /** @var \Account $account */
+ $account = \Auth::user()->accounts()->where('name', $name)->where('account_type_id', $rightAcctType->id)->first();
+ if (!$account) {
+ $new = [
+ 'name' => $name,
+ 'what' => 'revenue'
+ ];
+ $account = $acct->store($new);
+ }
+ $transaction->account()->associate($account);
+ $transaction->save();
+ }
+
+ echo 'Paid by: ' . $transaction->account->name . ' (' . $transaction->account->accountType->type . ')
';
+ }
+ }
+ break;
+ }
+
+
+ }
+ }
+
+
+ }
}
\ No newline at end of file
diff --git a/app/controllers/PiggybankController.php b/app/controllers/PiggybankController.php
index 6f08e87c1f..78b6c49ec0 100644
--- a/app/controllers/PiggybankController.php
+++ b/app/controllers/PiggybankController.php
@@ -1,31 +1,42 @@
_repository = $repository;
- $this->_accounts = $accounts;
+
+ /** @var \FireflyIII\Database\Account $acct */
+ $acct = App::make('FireflyIII\Database\Account');
+
+ /** @var \FireflyIII\Shared\Toolkit\Form $toolkit */
+ $toolkit = App::make('FireflyIII\Shared\Toolkit\Form');
+
+ $periods = Config::get('firefly.piggybank_periods');
+
+
+ $accounts = $toolkit->makeSelectList($acct->getAssetAccounts());
+ return View::make('piggybanks.create', compact('accounts', 'periods'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc')
+ ->with('subTitle', 'Create new piggy bank')->with('subTitleIcon', 'fa-plus');
}
/**
@@ -33,74 +44,13 @@ class PiggybankController extends BaseController
*
* @return $this
*/
- public function addMoney(Piggybank $piggyBank)
+ public function delete(Piggybank $piggybank)
{
- $what = 'add';
- $maxAdd = $this->_repository->leftOnAccount($piggyBank->account);
- $maxRemove = null;
-
- return View::make('piggybanks.modifyAmount')->with('what', $what)->with('maxAdd', $maxAdd)->with(
- 'maxRemove', $maxRemove
- )->with('piggybank', $piggyBank);
- }
-
- /**
- * @return $this
- */
- public function createPiggybank()
- {
- /** @var \Firefly\Helper\Toolkit\Toolkit $toolkit */
- $toolkit = App::make('Firefly\Helper\Toolkit\Toolkit');
-
-
- $periods = Config::get('firefly.piggybank_periods');
- $list = $this->_accounts->getActiveDefault();
- $accounts = $toolkit->makeSelectList($list);
-
+ View::share('subTitle', 'Delete "' . $piggybank->name . '"');
View::share('title', 'Piggy banks');
- View::share('subTitle', 'Create new');
View::share('mainTitleIcon', 'fa-sort-amount-asc');
- return View::make('piggybanks.create-piggybank')->with('accounts', $accounts)
- ->with('periods', $periods);
- }
-
- /**
- * @return $this
- */
- public function createRepeated()
- {
- /** @var \Firefly\Helper\Toolkit\Toolkit $toolkit */
- $toolkit = App::make('Firefly\Helper\Toolkit\Toolkit');
-
- $periods = Config::get('firefly.piggybank_periods');
- $list = $this->_accounts->getActiveDefault();
- $accounts = $toolkit->makeSelectList($list);
-
- View::share('title', 'Repeated expenses');
- View::share('subTitle', 'Create new');
- View::share('mainTitleIcon', 'fa-rotate-right');
-
- return View::make('piggybanks.create-repeated')->with('accounts', $accounts)->with('periods', $periods);
- }
-
- /**
- * @param Piggybank $piggyBank
- *
- * @return $this
- */
- public function delete(Piggybank $piggyBank)
- {
- View::share('subTitle', 'Delete "' . $piggyBank->name . '"');
- if ($piggyBank->repeats == 1) {
- View::share('title', 'Repeated expenses');
- View::share('mainTitleIcon', 'fa-rotate-right');
- } else {
- View::share('title', 'Piggy banks');
- View::share('mainTitleIcon', 'fa-sort-amount-asc');
- }
-
- return View::make('piggybanks.delete')->with('piggybank', $piggyBank);
+ return View::make('piggybanks.delete')->with('piggybank', $piggybank);
}
/**
@@ -111,18 +61,13 @@ class PiggybankController extends BaseController
public function destroy(Piggybank $piggyBank)
{
Event::fire('piggybanks.destroy', [$piggyBank]);
- if ($piggyBank->repeats == 1) {
- $route = 'piggybanks.index.repeated';
- $message = 'Repeated expense';
- } else {
- $route = 'piggybanks.index.piggybanks';
- $message = 'Piggybank';
- }
- $this->_repository->destroy($piggyBank);
- Session::flash('success', $message . ' deleted.');
+ /** @var \FireflyIII\Database\Piggybank $acct */
+ $repos = App::make('FireflyIII\Database\Piggybank');
+ $repos->destroy($piggyBank);
+ Session::flash('success', 'Piggy bank deleted.');
- return Redirect::route($route);
+ return Redirect::route('piggybanks.index');
}
/**
@@ -130,245 +75,203 @@ class PiggybankController extends BaseController
*
* @return $this
*/
- public function edit(Piggybank $piggyBank)
+ public function edit(Piggybank $piggybank)
{
- /** @var \Firefly\Helper\Toolkit\Toolkit $toolkit */
- $toolkit = App::make('Firefly\Helper\Toolkit\Toolkit');
- $list = $this->_accounts->getActiveDefault();
- $accounts = $toolkit->makeSelectList($list);
- $periods = Config::get('firefly.piggybank_periods');
+ /** @var \FireflyIII\Database\Account $acct */
+ $acct = App::make('FireflyIII\Database\Account');
+ /** @var \FireflyIII\Shared\Toolkit\Form $toolkit */
+ $toolkit = App::make('FireflyIII\Shared\Toolkit\Form');
- View::share('subTitle', 'Edit "' . $piggyBank->name . '"');
+ $periods = Config::get('firefly.piggybank_periods');
+ $accounts = $toolkit->makeSelectList($acct->getAssetAccounts());
- if ($piggyBank->repeats == 1) {
- View::share('title', 'Repeated expenses');
- View::share('mainTitleIcon', 'fa-rotate-left');
-
- return View::make('piggybanks.edit-repeated')->with('piggybank', $piggyBank)->with('accounts', $accounts)
- ->with('periods', $periods);
- } else {
- // piggy bank.
- View::share('title', 'Piggy banks');
- View::share('mainTitleIcon', 'fa-sort-amount-asc');
-
- return View::make('piggybanks.edit-piggybank')->with('piggybank', $piggyBank)->with('accounts', $accounts)
- ->with('periods', $periods);
- }
-
+ /*
+ * Flash some data to fill the form.
+ */
+ $prefilled = [
+ 'name' => $piggybank->name,
+ 'account_id' => $piggybank->account_id,
+ 'targetamount' => $piggybank->targetamount,
+ 'targetdate' => $piggybank->targetdate,
+ 'remind_me' => intval($piggybank->remind_me) == 1 ? true : false
+ ];
+ Session::flash('prefilled', $prefilled);
+ return View::make('piggybanks.edit', compact('piggybank', 'accounts', 'periods', 'prefilled'))->with('title', 'Piggybanks')->with(
+ 'mainTitleIcon', 'fa-sort-amount-asc'
+ )
+ ->with('subTitle', 'Edit piggy bank "' . e($piggybank->name) . '"')->with('subTitleIcon', 'fa-pencil');
}
/**
- * @param Piggybank $piggyBank
+ * @param Piggybank $piggybank
+ *
+ * @return $this
+ */
+ public function add(Piggybank $piggybank)
+ {
+ /** @var \FireflyIII\Database\Piggybank $acct */
+ $repos = App::make('FireflyIII\Database\Piggybank');
+
+ $leftOnAccount = $repos->leftOnAccount($piggybank->account);
+ $savedSoFar = $piggybank->currentRelevantRep()->currentamount;
+ $leftToSave = $piggybank->targetamount - $savedSoFar;
+ $amount = min($leftOnAccount, $leftToSave);
+
+
+ return View::make('piggybanks.add', compact('piggybank'))->with('maxAmount', $amount);
+ }
+
+ /**
+ * @param Piggybank $piggybank
*
* @return \Illuminate\Http\RedirectResponse
- * @throws Firefly\Exception\FireflyException
*/
- public function modMoney(Piggybank $piggyBank)
+ public function postAdd(Piggybank $piggybank)
+ {
+ $amount = round(floatval(Input::get('amount')), 2);
+
+ /** @var \FireflyIII\Database\Piggybank $acct */
+ $repos = App::make('FireflyIII\Database\Piggybank');
+
+ $leftOnAccount = $repos->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();
+ Session::flash('success', 'Added ' . mf($amount, false) . ' to "' . e($piggybank->name) . '".');
+ } else {
+ Session::flash('error', 'Could not add ' . mf($amount, false) . ' to "' . e($piggybank->name) . '".');
+ }
+ return Redirect::route('piggybanks.index');
+ }
+
+ /**
+ * @param Piggybank $piggybank
+ *
+ * @return \Illuminate\View\View
+ */
+ public function remove(Piggybank $piggybank)
+ {
+ return View::make('piggybanks.remove', compact('piggybank'));
+ }
+
+ /**
+ * @param Piggybank $piggybank
+ *
+ * @return \Illuminate\Http\RedirectResponse
+ */
+ public function postRemove(Piggybank $piggybank)
{
$amount = floatval(Input::get('amount'));
- switch (Input::get('what')) {
- default:
- throw new FireflyException('No such action');
- break;
- case 'add':
- $maxAdd = $this->_repository->leftOnAccount($piggyBank->account);
- if (round($amount, 2) <= round(min($maxAdd, $piggyBank->targetamount), 2)) {
- Session::flash('success', 'Amount updated!');
- $this->_repository->modifyAmount($piggyBank, $amount);
- Event::fire('piggybanks.modifyAmountAdd', [$piggyBank, $amount]);
- } else {
- Session::flash('warning', 'Could not!');
- }
- break;
- case 'remove':
- $rep = $piggyBank->currentRelevantRep();
- $maxRemove = $rep->currentamount;
- if (round($amount, 2) <= round($maxRemove, 2)) {
- Session::flash('success', 'Amount updated!');
- $this->_repository->modifyAmount($piggyBank, ($amount * -1));
- Event::fire('piggybanks.modifyAmountRemove', [$piggyBank, ($amount * -1)]);
- } else {
- Session::flash('warning', 'Could not!');
- }
- break;
- }
- if($piggyBank->repeats == 1) {
- $route = 'piggybanks.index.repeated';
+ $savedSoFar = $piggybank->currentRelevantRep()->currentamount;
+
+ if ($amount <= $savedSoFar) {
+ $repetition = $piggybank->currentRelevantRep();
+ $repetition->currentamount -= $amount;
+ $repetition->save();
+ Session::flash('success', 'Removed ' . mf($amount, false) . ' from "' . e($piggybank->name) . '".');
} else {
- $route = 'piggybanks.index.piggybanks';
+ Session::flash('error', 'Could not remove ' . mf($amount, false) . ' from "' . e($piggybank->name) . '".');
}
- return Redirect::route($route);
+ return Redirect::route('piggybanks.index');
}
- /**
- * @return $this
- */
- public function piggybanks()
+ public function index()
{
- $countRepeating = $this->_repository->countRepeating();
- $countNonRepeating = $this->_repository->countNonrepeating();
+ /** @var \FireflyIII\Database\Piggybank $repos */
+ $repos = App::make('FireflyIII\Database\Piggybank');
- $piggybanks = $this->_repository->get();
-
- // get the accounts with each piggy bank and check their balance; Fireflyy might needs to
- // show the user a correction.
+ /** @var Collection $piggybanks */
+ $piggybanks = $repos->get();
$accounts = [];
- /** @var \Piggybank $piggybank */
+ /** @var Piggybank $piggybank */
foreach ($piggybanks as $piggybank) {
+ $piggybank->savedSoFar = floatval($piggybank->currentRelevantRep()->currentamount);
+ $piggybank->percentage = intval($piggybank->savedSoFar / $piggybank->targetamount * 100);
+ $piggybank->leftToSave = $piggybank->targetamount - $piggybank->savedSoFar;
+
+ /*
+ * Fill account information:
+ */
$account = $piggybank->account;
- $id = $account->id;
- if (!isset($accounts[$id])) {
- $account->leftOnAccount = $this->_repository->leftOnAccount($account);
- $accounts[$id] = ['account' => $account, 'left' => $this->_repository->leftOnAccount($account)];
+ if (!isset($accounts[$account->id])) {
+ $accounts[$account->id] = [
+ 'name' => $account->name,
+ 'balance' => $account->balance(),
+ 'leftForPiggybanks' => $repos->leftOnAccount($account),
+ 'sumOfSaved' => $piggybank->savedSoFar,
+ 'sumOfTargets' => floatval($piggybank->targetamount),
+ 'leftToSave' => $piggybank->leftToSave
+ ];
+ } else {
+ $accounts[$account->id]['sumOfSaved'] += $piggybank->savedSoFar;
+ $accounts[$account->id]['sumOfTargets'] += floatval($piggybank->targetamount);
+ $accounts[$account->id]['leftToSave'] += $piggybank->leftToSave;
}
}
-
- View::share('title', 'Piggy banks');
- View::share('subTitle', 'Save for big expenses');
- View::share('mainTitleIcon', 'fa-sort-amount-asc');
-
- return View::make('piggybanks.index')->with('piggybanks', $piggybanks)
- ->with('countRepeating', $countRepeating)
- ->with('countNonRepeating', $countNonRepeating)
- ->with('accounts', $accounts);
+ return View::make('piggybanks.index', compact('piggybanks', 'accounts'))->with('title', 'Piggy banks')->with('mainTitleIcon', 'fa-sort-amount-asc');
}
- /**
- * @param Piggybank $piggyBank
- *
- * @return $this
- */
- public function removeMoney(Piggybank $piggyBank)
- {
- $what = 'remove';
- $maxAdd = $this->_repository->leftOnAccount($piggyBank->account);
- $maxRemove = $piggyBank->currentRelevantRep()->currentamount;
- return View::make('piggybanks.modifyAmount')->with('what', $what)->with('maxAdd', $maxAdd)->with(
- 'maxRemove', $maxRemove
- )->with('piggybank', $piggyBank);
- }
-
- /**
- * @return $this
- */
- public function repeated()
- {
- $countRepeating = $this->_repository->countRepeating();
- $countNonRepeating = $this->_repository->countNonrepeating();
-
- $piggybanks = $this->_repository->get();
-
- // get the accounts with each piggy bank and check their balance; Fireflyy might needs to
- // show the user a correction.
-
- $accounts = [];
- /** @var \Piggybank $piggybank */
- foreach ($piggybanks as $piggybank) {
- $account = $piggybank->account;
- $id = $account->id;
- if (!isset($accounts[$id])) {
- $account->leftOnAccount = $this->_repository->leftOnAccount($account);
- $accounts[$id] = ['account' => $account, 'left' => $this->_repository->leftOnAccount($account)];
- }
- }
-
- View::share('title', 'Repeated expenses');
- View::share('subTitle', 'Save for returning bills');
- View::share('mainTitleIcon', 'fa-rotate-left');
-
-
- return View::make('piggybanks.index')->with('piggybanks', $piggybanks)
- ->with('countRepeating', $countRepeating)
- ->with('countNonRepeating', $countNonRepeating)
- ->with('accounts', $accounts);
- }
-
- /**
- *
- */
public function show(Piggybank $piggyBank)
{
- $leftOnAccount = $this->_repository->leftOnAccount($piggyBank->account);
- $balance = $piggyBank->account->balance();
-
- View::share('subTitle', $piggyBank->name);
-
- if ($piggyBank->repeats == 1) {
- // repeated expense.
- View::share('title', 'Repeated expenses');
- View::share('mainTitleIcon', 'fa-rotate-left');
- } else {
- // piggy bank.
- View::share('title', 'Piggy banks');
- View::share('mainTitleIcon', 'fa-sort-amount-asc');
- }
-
- return View::make('piggybanks.show')->with('piggyBank', $piggyBank)->with('leftOnAccount', $leftOnAccount)
- ->with('balance', $balance);
- }
-
- /**
- * @return $this|\Illuminate\Http\RedirectResponse
- */
- public function storePiggybank()
- {
- $data = Input::all();
- unset($data['_token']);
-
- // extend the data array with the settings needed to create a piggy bank:
- $data['repeats'] = 0;
- $data['rep_times'] = 1;
- $data['rep_every'] = 1;
- $data['order'] = 0;
-
- $piggyBank = $this->_repository->store($data);
- if (!is_null($piggyBank->id)) {
- Session::flash('success', 'New piggy bank "' . $piggyBank->name . '" created!');
- Event::fire('piggybanks.store', [$piggyBank]);
-
- return Redirect::route('piggybanks.index.piggybanks');
-
-
- } else {
- Session::flash('error', 'Could not save piggy bank: ' . $piggyBank->errors()->first());
-
- return Redirect::route('piggybanks.create.piggybank')->withInput()->withErrors($piggyBank->errors());
- }
+ throw new NotImplementedException;
}
/**
- * @return $this|\Illuminate\Http\RedirectResponse
+ *
*/
- public function storeRepeated()
+ public function store()
{
+ $data = Input::all();
+ $data['repeats'] = 0;
+ /** @var \FireflyIII\Database\Piggybank $repos */
+ $repos = App::make('FireflyIII\Database\Piggybank');
- $data = Input::all();
- unset($data['_token']);
+ switch ($data['post_submit_action']) {
+ default:
+ throw new FireflyException('Cannot handle post_submit_action "' . e($data['post_submit_action']) . '"');
+ break;
+ case 'create_another':
+ case 'store':
+ $messages = $repos->validate($data);
+ /** @var MessageBag $messages ['errors'] */
+ if ($messages['errors']->count() > 0) {
+ Session::flash('warnings', $messages['warnings']);
+ Session::flash('successes', $messages['successes']);
+ Session::flash('error', 'Could not save piggy bank: ' . $messages['errors']->first());
+ return Redirect::route('piggybanks.create')->withInput()->withErrors($messages['errors']);
+ }
+ // store!
+ $repos->store($data);
+ Session::flash('success', 'New piggy bank stored!');
- // extend the data array with the settings needed to create a repeated:
- $data['repeats'] = 1;
- $data['order'] = 0;
+ if ($data['post_submit_action'] == 'create_another') {
+ return Redirect::route('piggybanks.create');
+ } else {
+ return Redirect::route('piggybanks.index');
+ }
+ break;
+ case 'validate_only':
+ $messageBags = $repos->validate($data);
+ Session::flash('warnings', $messageBags['warnings']);
+ Session::flash('successes', $messageBags['successes']);
+ Session::flash('errors', $messageBags['errors']);
- $piggyBank = $this->_repository->store($data);
- if ($piggyBank->id) {
- Session::flash('success', 'New piggy bank "' . $piggyBank->name . '" created!');
- Event::fire('piggybanks.store', [$piggyBank]);
- return Redirect::route('piggybanks.index.repeated');
-
- } else {
- Session::flash('error', 'Could not save piggy bank: ' . $piggyBank->errors()->first());
-
- return Redirect::route('piggybanks.create.repeated')->withInput()->withErrors($piggyBank->errors());
+ return Redirect::route('piggybanks.create')->withInput();
+ break;
}
-
}
/**
@@ -378,25 +281,41 @@ class PiggybankController extends BaseController
*/
public function update(Piggybank $piggyBank)
{
- $piggyBank = $this->_repository->update($piggyBank, Input::all());
- if ($piggyBank->validate()) {
- if ($piggyBank->repeats == 1) {
- $route = 'piggybanks.index.repeated';
- $message = 'Repeated expense';
- } else {
- $route = 'piggybanks.index.piggybanks';
- $message = 'Piggy bank';
- }
+ /** @var \FireflyIII\Database\Piggybank $repos */
+ $repos = App::make('FireflyIII\Database\Piggybank');
+ $data = Input::except('_token');
- Session::flash('success', $message . ' "' . $piggyBank->name . '" updated.');
- Event::fire('piggybanks.update', [$piggyBank]);
+ switch (Input::get('post_submit_action')) {
+ default:
+ throw new FireflyException('Cannot handle post_submit_action "' . e(Input::get('post_submit_action')) . '"');
+ break;
+ case 'create_another':
+ case 'update':
+ $messages = $repos->validate($data);
+ /** @var MessageBag $messages ['errors'] */
+ if ($messages['errors']->count() > 0) {
+ Session::flash('warnings', $messages['warnings']);
+ Session::flash('successes', $messages['successes']);
+ Session::flash('error', 'Could not save piggy bank: ' . $messages['errors']->first());
+ return Redirect::route('piggybanks.edit', $piggyBank->id)->withInput()->withErrors($messages['errors']);
+ }
+ // store!
+ $repos->update($piggyBank, $data);
+ Session::flash('success', 'Piggy bank updated!');
- return Redirect::route($route);
- } else {
- Session::flash('error', 'Could not update piggy bank: ' . $piggyBank->errors()->first());
-
- return Redirect::route('piggybanks.edit', $piggyBank->id)->withErrors($piggyBank->errors())->withInput();
+ if ($data['post_submit_action'] == 'create_another') {
+ return Redirect::route('piggybanks.edit', $piggyBank->id);
+ } else {
+ return Redirect::route('piggybanks.index');
+ }
+ case 'validate_only':
+ $messageBags = $repos->validate($data);
+ Session::flash('warnings', $messageBags['warnings']);
+ Session::flash('successes', $messageBags['successes']);
+ Session::flash('errors', $messageBags['errors']);
+ return Redirect::route('piggybanks.edit', $piggyBank->id)->withInput();
+ break;
}
diff --git a/app/controllers/ReportController.php b/app/controllers/ReportController.php
index a313d89564..baab2c53a0 100644
--- a/app/controllers/ReportController.php
+++ b/app/controllers/ReportController.php
@@ -1,4 +1,5 @@
with('title','Reports')->with('mainTitleIcon','fa-line-chart');
+ /** @var \FireflyIII\Database\TransactionJournal $journals */
+ $journals = App::make('FireflyIII\Database\TransactionJournal');
+ $journal = $journals->first();
+
+ $date = $journal->date;
+ $years = [];
+ while ($date <= Carbon::now()) {
+ $years[] = $date->format('Y');
+ $date->addYear();
+ }
+
+
+ return View::make('reports.index', compact('years'))->with('title', 'Reports')->with('mainTitleIcon', 'fa-line-chart');
+ }
+
+ /**
+ * @param $year
+ */
+ public function year($year)
+ {
+ try {
+ $date = new Carbon('01-01-' . $year);
+ } catch (Exception $e) {
+ App::abort(500);
+ }
+
+ /** @var \FireflyIII\Database\TransactionJournal $tj */
+ $tj = App::make('FireflyIII\Database\TransactionJournal');
+
+ // get some sums going
+ $summary = [];
+
+
+ $end = clone $date;
+ $end->endOfYear();
+ while ($date < $end) {
+ $summary[] = [
+ 'month' => $date->format('F'),
+ 'income' => $tj->getSumOfIncomesByMonth($date),
+ 'expense' => $tj->getSumOfExpensesByMonth($date),
+ ];
+ $date->addMonth();
+ }
+
+
+ // draw some charts etc.
+ return View::make('reports.year', compact('summary'))->with('title', 'Reports')->with('mainTitleIcon', 'fa-line-chart')->with('subTitle', $year)->with(
+ 'subTitleIcon', 'fa-bar-chart'
+ )->with('year', $year);
}
}
\ No newline at end of file
diff --git a/app/database/migrations/2014_06_27_163818_create_piggybanks_table.php b/app/database/migrations/2014_06_27_163818_create_piggybanks_table.php
index b30cae3406..74ff3e20c8 100644
--- a/app/database/migrations/2014_06_27_163818_create_piggybanks_table.php
+++ b/app/database/migrations/2014_06_27_163818_create_piggybanks_table.php
@@ -33,6 +33,7 @@ class CreatePiggybanksTable extends Migration
$table->smallInteger('rep_times')->unsigned()->nullable();
$table->enum('reminder', ['day', 'week', 'month', 'year'])->nullable();
$table->smallInteger('reminder_skip')->unsigned();
+ $table->boolean('remind_me');
$table->integer('order')->unsigned();
// connect account to piggybank.
diff --git a/app/lib/Firefly/Form/Form.php b/app/lib/Firefly/Form/Form.php
index 6414fd983e..a06c3184ec 100644
--- a/app/lib/Firefly/Form/Form.php
+++ b/app/lib/Firefly/Form/Form.php
@@ -10,9 +10,10 @@ class Form
{
/**
- * @param $name
- * @param null $value
+ * @param $name
+ * @param null $value
* @param array $options
+ *
* @return string
* @throws FireflyException
*/
@@ -29,18 +30,42 @@ class Form
return self::ffInput('checkbox', $name, $value, $options);
}
+ /**
+ * @param $name
+ * @param null $value
+ * @param array $options
+ *
+ * @return string
+ * @throws FireflyException
+ */
public static function ffAmount($name, $value = null, array $options = [])
{
$options['step'] = 'any';
- $options['min'] = '0.01';
+ $options['min'] = '0.01';
return self::ffInput('amount', $name, $value, $options);
}
/**
- * @param $name
- * @param null $value
+ * @param $name
+ * @param null $value
* @param array $options
+ *
+ * @return string
+ * @throws FireflyException
+ */
+ public static function ffBalance($name, $value = null, array $options = [])
+ {
+ $options['step'] = 'any';
+ return self::ffInput('amount', $name, $value, $options);
+
+ }
+
+ /**
+ * @param $name
+ * @param null $value
+ * @param array $options
+ *
* @return string
* @throws FireflyException
*/
@@ -50,9 +75,10 @@ class Form
}
/**
- * @param $name
- * @param null $value
+ * @param $name
+ * @param null $value
* @param array $options
+ *
* @return string
* @throws FireflyException
*/
@@ -63,10 +89,11 @@ class Form
}
/**
- * @param $name
+ * @param $name
* @param array $list
- * @param null $selected
+ * @param null $selected
* @param array $options
+ *
* @return string
* @throws FireflyException
*/
@@ -76,9 +103,10 @@ class Form
}
/**
- * @param $name
- * @param null $value
+ * @param $name
+ * @param null $value
* @param array $options
+ *
* @return string
* @throws FireflyException
*/
@@ -88,16 +116,25 @@ class Form
}
- public static function label($name)
+ /**
+ * @param $name
+ * @param $options
+ *
+ * @return string
+ */
+ public static function label($name, $options)
{
+ if (isset($options['label'])) {
+ return $options['label'];
+ }
$labels = [
- 'amount_min' => 'Amount (min)',
- 'amount_max' => 'Amount (max)',
- 'match' => 'Matches on',
- 'repeat_freq' => 'Repetition',
+ 'amount_min' => 'Amount (min)',
+ 'amount_max' => 'Amount (max)',
+ 'match' => 'Matches on',
+ 'repeat_freq' => 'Repetition',
'account_from_id' => 'Account from',
- 'account_to_id' => 'Account to',
- 'account_id' => 'Asset account'
+ 'account_to_id' => 'Account to',
+ 'account_id' => 'Asset account'
];
return isset($labels[$name]) ? $labels[$name] : str_replace('_', ' ', ucfirst($name));
@@ -151,28 +188,29 @@ class Form
case 'create':
$return = '';
break;
case 'update':
$return = '';
break;
default:
throw new FireflyException('Cannot create ffOptionsList for option (store+return) ' . $type);
break;
}
- return $store.$validate.$return;
+ return $store . $validate . $return;
}
/**
- * @param $type
- * @param $name
- * @param null $value
+ * @param $type
+ * @param $name
+ * @param null $value
* @param array $options
* @param array $list
+ *
* @return string
* @throws FireflyException
*/
@@ -181,10 +219,10 @@ class Form
/*
* add some defaults to this method:
*/
- $options['class'] = 'form-control';
- $options['id'] = 'ffInput_' . $name;
+ $options['class'] = 'form-control';
+ $options['id'] = 'ffInput_' . $name;
$options['autocomplete'] = 'off';
- $label = self::label($name);
+ $label = self::label($name, $options);
/*
* Make label and placeholder look nice.
*/
@@ -193,9 +231,9 @@ class Form
/*
* Get prefilled value:
*/
- if(\Session::has('prefilled')) {
+ if (\Session::has('prefilled')) {
$prefilled = \Session::get('prefilled');
- $value = isset($prefilled[$name]) && is_null($value) ? $prefilled[$name] : $value;
+ $value = isset($prefilled[$name]) && is_null($value) ? $prefilled[$name] : $value;
}
/*
diff --git a/app/lib/Firefly/Helper/Controllers/Account.php b/app/lib/Firefly/Helper/Controllers/Account.php
index a7fb95a02b..93dd3b12d7 100644
--- a/app/lib/Firefly/Helper/Controllers/Account.php
+++ b/app/lib/Firefly/Helper/Controllers/Account.php
@@ -12,14 +12,17 @@ class Account implements AccountInterface
/**
* @param \Account $account
+ *
* @return \TransactionJournal|null
*/
public function openingBalanceTransaction(\Account $account)
{
return \TransactionJournal::withRelevantData()
->accountIs($account)
- ->leftJoin('transaction_types', 'transaction_types.id', '=',
- 'transaction_journals.transaction_type_id')
+ ->leftJoin(
+ 'transaction_types', 'transaction_types.id', '=',
+ 'transaction_journals.transaction_type_id'
+ )
->where('transaction_types.type', 'Opening balance')
->first(['transaction_journals.*']);
}
@@ -36,7 +39,7 @@ class Account implements AccountInterface
* For now, Firefly simply warns the user of this.
*
* @param \Account $account
- * @param $perPage
+ * @param $perPage
*
* @return array|mixed
* @throws \Firefly\Exception\FireflyException
@@ -110,17 +113,25 @@ class Account implements AccountInterface
// statistics (transactions)
- $trIn = floatval(\Transaction::before($end)->after($start)->accountIs($account)->moreThan(0)
- ->transactionTypes(['Deposit', 'Withdrawal'])->sum('transactions.amount'));
- $trOut = floatval(\Transaction::before($end)->after($start)->accountIs($account)->lessThan(0)
- ->transactionTypes(['Deposit', 'Withdrawal'])->sum('transactions.amount'));
+ $trIn = floatval(
+ \Transaction::before($end)->after($start)->accountIs($account)->moreThan(0)
+ ->transactionTypes(['Deposit', 'Withdrawal'])->sum('transactions.amount')
+ );
+ $trOut = floatval(
+ \Transaction::before($end)->after($start)->accountIs($account)->lessThan(0)
+ ->transactionTypes(['Deposit', 'Withdrawal'])->sum('transactions.amount')
+ );
$trDiff = $trIn + $trOut;
// statistics (transfers)
- $trfIn = floatval(\Transaction::before($end)->after($start)->accountIs($account)->moreThan(0)
- ->transactionTypes(['Transfer'])->sum('transactions.amount'));
- $trfOut = floatval(\Transaction::before($end)->after($start)->accountIs($account)->lessThan(0)
- ->transactionTypes(['Transfer'])->sum('transactions.amount'));
+ $trfIn = floatval(
+ \Transaction::before($end)->after($start)->accountIs($account)->moreThan(0)
+ ->transactionTypes(['Transfer'])->sum('transactions.amount')
+ );
+ $trfOut = floatval(
+ \Transaction::before($end)->after($start)->accountIs($account)->lessThan(0)
+ ->transactionTypes(['Transfer'])->sum('transactions.amount')
+ );
$trfDiff = $trfIn + $trfOut;
$stats['period'] = [
diff --git a/app/lib/Firefly/Helper/Controllers/Json.php b/app/lib/Firefly/Helper/Controllers/Json.php
index 80b87286f7..34e4f1f11f 100644
--- a/app/lib/Firefly/Helper/Controllers/Json.php
+++ b/app/lib/Firefly/Helper/Controllers/Json.php
@@ -1,11 +1,4 @@
limitrepetitions()->get() as $l) {
- $l->delete();
- }
$limit->createRepetition($limit->startdate);
return true;
diff --git a/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php b/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php
index 80023eb48e..09e3943099 100644
--- a/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php
+++ b/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php
@@ -193,7 +193,7 @@ class EloquentPiggybankTrigger
'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@updateRelatedTransfer'
);
$events->listen(
- 'piggybanks.check', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@checkRepeatingPiggies'
+ 'piggybanks.storepiggybanks.check', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@checkRepeatingPiggies'
);
}
diff --git a/app/lib/FireflyIII/Database/Account.php b/app/lib/FireflyIII/Database/Account.php
new file mode 100644
index 0000000000..60726af53c
--- /dev/null
+++ b/app/lib/FireflyIII/Database/Account.php
@@ -0,0 +1,469 @@
+setUser(\Auth::user());
+ }
+
+ /**
+ * @param Ardent $model
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function update(Ardent $model, array $data)
+ {
+ $model->name = $data['name'];
+ $model->active = isset($data['active']) ? intval($data['active']) : 0;
+ $model->save();
+
+ if (isset($data['openingbalance']) && isset($data['openingbalancedate'])) {
+ $openingBalance = $this->openingBalanceTransaction($model);
+
+ $openingBalance->date = new Carbon($data['openingbalancedate']);
+ $openingBalance->save();
+ $amount = floatval($data['openingbalance']);
+ /** @var \Transaction $transaction */
+ foreach ($openingBalance->transactions as $transaction) {
+ if ($transaction->account_id == $model->id) {
+ $transaction->amount = $amount;
+ } else {
+ $transaction->amount = $amount * -1;
+ }
+ $transaction->save();
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Get all asset accounts. Optional JSON based parameters.
+ *
+ * @param array $parameters
+ *
+ * @return Collection
+ */
+ public function getAssetAccounts(array $parameters = [])
+ {
+ return $this->getAccountsByType(['Default account', 'Asset account'], $parameters);
+
+ }
+
+ /**
+ * @param \Account $account
+ *
+ * @return \Account|null
+ */
+ public function findInitialBalanceAccount(\Account $account)
+ {
+ /** @var \FireflyIII\Database\AccountType $acctType */
+ $acctType = \App::make('FireflyIII\Database\AccountType');
+
+ $accountType = $acctType->findByWhat('initial');
+
+ return $this->getUser()->accounts()->where('account_type_id', $accountType->id)->where('name', 'LIKE', $account->name . '%')->first();
+ }
+
+ /**
+ * @param array $types
+ * @param array $parameters
+ *
+ * @return Collection
+ */
+ public function getAccountsByType(array $types, array $parameters = [])
+ {
+ /*
+ * Basic query:
+ */
+ $query = $this->getUser()->accounts()->accountTypeIn($types);
+
+
+ /*
+ * Without an opening balance, the rest of these queries will fail.
+ */
+
+ $query->leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id');
+ $query->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id');
+
+ /*
+ * Not used, but useful for the balance within a certain month / year.
+ */
+ $balanceOnDate = isset($parameters['date']) ? $parameters['date'] : Carbon::now();
+ $query->where(
+ function ($q) use ($balanceOnDate) {
+ $q->where('transaction_journals.date', '<=', $balanceOnDate->format('Y-m-d'));
+ $q->orWhereNull('transaction_journals.date');
+ }
+ );
+
+ $query->groupBy('accounts.id');
+
+ /*
+ * If present, process parameters for sorting:
+ */
+ $query->orderBy('name', 'ASC');
+
+ /*
+ * If present, process parameters for searching.
+ */
+ if (isset($parameters['search'])) {
+ $query->where('name', 'LIKE', '%' . e($parameters['search']['value'] . '%'));
+ }
+
+ /*
+ * If present, start at $start:
+ */
+ if (isset($parameters['start'])) {
+ $query->skip(intval($parameters['start']));
+ }
+ if (isset($parameters['length'])) {
+ $query->take(intval($parameters['length']));
+ }
+
+ return $query->get(['accounts.*', \DB::Raw('SUM(`transactions`.`amount`) as `balance`')]);
+ }
+
+ /**
+ * @return int
+ */
+ public function countAssetAccounts()
+ {
+ return $this->countAccountsByType(['Default account', 'Asset account']);
+ }
+
+ /**
+ * @return int
+ */
+ public function countExpenseAccounts()
+ {
+ return $this->countAccountsByType(['Expense account', 'Beneficiary account']);
+ }
+
+ /**
+ * @param array $types
+ *
+ * @return int
+ */
+ public function countAccountsByType(array $types)
+ {
+ return $this->getUser()->accounts()->accountTypeIn($types)->count();
+ }
+
+ /**
+ * @param array $parameters
+ *
+ * @return Collection
+ */
+ public function getExpenseAccounts(array $parameters = [])
+ {
+ return $this->getAccountsByType(['Expense account', 'Beneficiary account'], $parameters);
+ }
+
+ /**
+ * Get all default accounts.
+ *
+ * @return Collection
+ */
+ public function getDefaultAccounts()
+ {
+ // TODO: Implement getDefaultAccounts() method.
+ }
+
+ /**
+ * Returns an object with id $id.
+ *
+ * @param int $id
+ *
+ * @return Ardent
+ */
+ public function find($id)
+ {
+ // TODO: Implement find() method.
+ }
+
+ /**
+ * Returns all objects.
+ *
+ * @return Collection
+ */
+ public function get()
+ {
+ // TODO: Implement get() method.
+ }
+
+ /**
+ * Counts the number of total revenue accounts. Useful for DataTables.
+ *
+ * @return int
+ */
+ public function countRevenueAccounts()
+ {
+ return $this->countAccountsByType(['Revenue account']);
+ }
+
+ /**
+ * Get all revenue accounts.
+ *
+ * @param array $parameters
+ *
+ * @return Collection
+ */
+ public function getRevenueAccounts(array $parameters = [])
+ {
+ return $this->getAccountsByType(['Revenue account'], $parameters);
+ }
+
+ /**
+ * @param Ardent $model
+ *
+ * @return bool
+ */
+ public function destroy(Ardent $model)
+ {
+ $model->delete();
+ return true;
+
+ }
+
+ /**
+ * @param \Account $account
+ *
+ * @return \TransactionJournal|null
+ */
+ public function openingBalanceTransaction(\Account $account)
+ {
+ return \TransactionJournal::withRelevantData()
+ ->accountIs($account)
+ ->leftJoin(
+ 'transaction_types', 'transaction_types.id', '=',
+ 'transaction_journals.transaction_type_id'
+ )
+ ->where('transaction_types.type', 'Opening balance')
+ ->first(['transaction_journals.*']);
+ }
+
+ /**
+ * Validates a model. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param Ardent $model
+ *
+ * @return array
+ */
+ public function validateObject(Ardent $model)
+ {
+ die('No impl');
+ }
+
+ /**
+ * Validates a model. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param array $model
+ *
+ * @return array
+ */
+ public function validate(array $model)
+ {
+ $warnings = new MessageBag;
+ $successes = new MessageBag;
+ $errors = new MessageBag;
+
+ /*
+ * Name validation:
+ */
+ if (!isset($model['name'])) {
+ $errors->add('name', 'Name is mandatory');
+ }
+
+ if (isset($model['name']) && strlen($model['name']) == 0) {
+ $errors->add('name', 'Name is too short');
+ }
+ if (isset($model['name']) && strlen($model['name']) > 100) {
+ $errors->add('name', 'Name is too long');
+ }
+ $validator = \Validator::make([$model], \Account::$rules);
+ if ($validator->invalid()) {
+ $errors->merge($errors);
+ }
+
+ /*
+ * type validation.
+ */
+ if (!isset($model['what'])) {
+ $errors->add('name', 'Internal error: need to know type of account!');
+ }
+
+ /*
+ * Opening balance and opening balance date.
+ */
+ if (isset($model['what']) && $model['what'] == 'asset') {
+ if (isset($model['openingbalance']) && strlen($model['openingbalance']) > 0 && !is_numeric($model['openingbalance'])) {
+ $errors->add('openingbalance', 'This is not a number.');
+ }
+ if (isset($model['openingbalancedate']) && strlen($model['openingbalancedate']) > 0) {
+ try {
+ new Carbon($model['openingbalancedate']);
+ } catch (\Exception $e) {
+ $errors->add('openingbalancedate', 'This date is invalid.');
+ }
+ }
+ }
+
+
+ if (!$errors->has('name')) {
+ $successes->add('name', 'OK');
+ }
+ if (!$errors->has('openingbalance')) {
+ $successes->add('openingbalance', 'OK');
+ }
+ if (!$errors->has('openingbalancedate')) {
+ $successes->add('openingbalancedate', 'OK');
+ }
+ return [
+ 'errors' => $errors,
+ 'warnings' => $warnings,
+ 'successes' => $successes
+ ];
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return Ardent
+ */
+ public function store(array $data)
+ {
+
+ /*
+ * Find account type.
+ */
+ /** @var \FireflyIII\Database\AccountType $acctType */
+ $acctType = \App::make('FireflyIII\Database\AccountType');
+
+ $accountType = $acctType->findByWhat($data['what']);
+
+ $data['user_id'] = $this->getUser()->id;
+ $data['account_type_id'] = $accountType->id;
+ $data['active'] = isset($data['active']) && $data['active'] === '1' ? 1 : 0;
+
+
+ $data = array_except($data, array('_token', 'what'));
+ $account = new \Account($data);
+ if (!$account->validate()) {
+ var_dump($account->errors()->all());
+ exit;
+ }
+ $account->save();
+ if (isset($data['openingbalance']) && floatval($data['openingbalance']) != 0) {
+ $this->storeInitialBalance($account, $data);
+ }
+
+
+ /* Tell transaction journal to store a new one.*/
+
+
+ return $account;
+
+ }
+
+ /**
+ * @param \Account $account
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function storeInitialBalance(\Account $account, array $data)
+ {
+ $opposingData = [
+ 'name' => $account->name . ' Initial Balance',
+ 'active' => 0,
+ 'what' => 'initial'
+ ];
+ $opposingAccount = $this->store($opposingData);
+
+ /*
+ * Create a journal from opposing to account or vice versa.
+ */
+ $balance = floatval($data['openingbalance']);
+ $date = new Carbon($data['openingbalancedate']);
+ /** @var \FireflyIII\Database\TransactionJournal $tj */
+ $tj = \App::make('FireflyIII\Database\TransactionJournal');
+ if ($balance < 0) {
+ // first transaction draws money from the new account to the opposing
+ $from = $account;
+ $to = $opposingAccount;
+ } else {
+ // first transaction puts money into account
+ $from = $opposingAccount;
+ $to = $account;
+ }
+
+ // data for transaction journal:
+ $balance = $balance < 0 ? $balance * -1 : $balance;
+ $opening = [
+ 'what' => 'opening',
+ 'currency' => 'EUR',
+ 'amount' => $balance,
+ 'from' => $from,
+ 'to' => $to,
+ 'date' => $date,
+ 'description' => 'Opening balance for new account ' . $account->name,
+ ];
+
+
+ $validation = $tj->validate($opening);
+ if ($validation['errors']->count() == 0) {
+ $tj->store($opening);
+ return true;
+ } else {
+ var_dump($validation['errors']);
+ exit;
+ }
+ return false;
+ }
+
+ /**
+ * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
+ *
+ * @param $what
+ *
+ * @return \AccountType|null
+ */
+ public function findByWhat($what)
+ {
+ // TODO: Implement findByWhat() method.
+ }
+
+ /**
+ * @param array $ids
+ *
+ * @return Collection
+ */
+ public function getByIds(array $ids)
+ {
+ return $this->getUser()->accounts()->whereIn('id', $ids)->get();
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Database/AccountType.php b/app/lib/FireflyIII/Database/AccountType.php
new file mode 100644
index 0000000000..8a4e13f1dc
--- /dev/null
+++ b/app/lib/FireflyIII/Database/AccountType.php
@@ -0,0 +1,139 @@
+first();
+ break;
+ case 'asset':
+ return \AccountType::whereType('Asset account')->first();
+ break;
+ case 'revenue':
+ return \AccountType::whereType('Revenue account')->first();
+ break;
+ case 'initial':
+ return \AccountType::whereType('Initial balance account')->first();
+ break;
+ default:
+ throw new FireflyException('Cannot find account type described as "' . e($what) . '".');
+ break;
+
+ }
+ return null;
+ }
+
+ /**
+ * @param Ardent $model
+ *
+ * @return bool
+ */
+ public function destroy(Ardent $model)
+ {
+ // TODO: Implement destroy() method.
+ }
+
+ /**
+ * Validates a model. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param Ardent $model
+ *
+ * @return array
+ */
+ public function validateObject(Ardent $model)
+ {
+ // TODO: Implement validateObject() method.
+ }
+
+ /**
+ * Validates an array. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param array $model
+ *
+ * @return array
+ */
+ public function validate(array $model)
+ {
+ // TODO: Implement validate() method.
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return Ardent
+ */
+ public function store(array $data)
+ {
+ // TODO: Implement store() method.
+ }
+
+ /**
+ * Returns an object with id $id.
+ *
+ * @param int $id
+ *
+ * @return Ardent
+ */
+ public function find($id)
+ {
+ // TODO: Implement find() method.
+ }
+
+ /**
+ * Returns all objects.
+ *
+ * @return Collection
+ */
+ public function get()
+ {
+ // TODO: Implement get() method.
+ }
+
+ /**
+ * @param array $ids
+ *
+ * @return Collection
+ */
+ public function getByIds(array $ids)
+ {
+ // TODO: Implement getByIds() method.
+ }
+
+ /**
+ * @param Ardent $model
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function update(Ardent $model, array $data)
+ {
+ // TODO: Implement update() method.
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Database/Budget.php b/app/lib/FireflyIII/Database/Budget.php
new file mode 100644
index 0000000000..ba8d22fcf4
--- /dev/null
+++ b/app/lib/FireflyIII/Database/Budget.php
@@ -0,0 +1,234 @@
+setUser(\Auth::user());
+ }
+
+ /**
+ * @param \Budget $budget
+ * @param Carbon $date
+ *
+ * @return \LimitRepetition|null
+ */
+ public function repetitionOnStartingOnDate(\Budget $budget, Carbon $date)
+ {
+ return \LimitRepetition::
+ leftJoin('limits', 'limit_repetitions.limit_id', '=', 'limits.id')->leftJoin(
+ 'components', 'limits.component_id', '=', 'components.id'
+ )->where('limit_repetitions.startdate', $date->format('Y-m-d'))->where(
+ 'components.id', $budget->id
+ )->first(['limit_repetitions.*']);
+ }
+
+ /**
+ * @param Ardent $model
+ *
+ * @return bool
+ */
+ public function destroy(Ardent $model)
+ {
+ $model->delete();
+ return true;
+ }
+
+ /**
+ * Validates a model. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param Ardent $model
+ *
+ * @return array
+ */
+ public function validateObject(Ardent $model)
+ {
+ // TODO: Implement validateObject() method.
+ }
+
+ /**
+ * Validates an array. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param array $model
+ *
+ * @return array
+ */
+ public function validate(array $model)
+ {
+ $warnings = new MessageBag;
+ $successes = new MessageBag;
+ $errors = new MessageBag;
+
+ if(isset($model['name'])) {
+ if(strlen($model['name']) < 1) {
+ $errors->add('name', 'Name is too short');
+ }
+ if(strlen($model['name']) > 200) {
+ $errors->add('name', 'Name is too long');
+
+ }
+ } else {
+ $errors->add('name', 'Name is mandatory');
+ }
+ $validator = \Validator::make($model, \Component::$rules);
+
+ if ($validator->invalid()) {
+ $errors->merge($validator->errors());
+ }
+
+
+ if(!$errors->has('name')) {
+ $successes->add('name','OK');
+ }
+
+ return [
+ 'errors' => $errors,
+ 'warnings' => $warnings,
+ 'successes' => $successes
+ ];
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return Ardent
+ */
+ public function store(array $data)
+ {
+ $data['user_id'] = $this->getUser()->id;
+
+ $budget = new \Budget($data);
+ $budget->class = 'Budget';
+
+ if (!$budget->validate()) {
+ var_dump($budget->errors()->all());
+ exit;
+ }
+ $budget->save();
+ return $budget;
+ }
+
+ /**
+ * Returns an object with id $id.
+ *
+ * @param int $id
+ *
+ * @return Ardent
+ */
+ public function find($id)
+ {
+ // TODO: Implement find() method.
+ }
+
+ /**
+ * Returns all objects.
+ *
+ * @return Collection
+ */
+ public function get()
+ {
+ $budgets = $this->getUser()->budgets()->get();
+
+ return $budgets;
+ }
+
+ /**
+ * @param \Budget $budget
+ * @param Carbon $date
+ * @return float
+ */
+ public function spentInMonth(\Budget $budget, Carbon $date) {
+ $end = clone $date;
+ $date->startOfMonth();
+ $end->endOfMonth();
+ $sum = floatval($budget->transactionjournals()->before($end)->after($date)->lessThan(0)->sum('amount')) * -1;
+ return $sum;
+ }
+
+ /**
+ * @param array $ids
+ *
+ * @return Collection
+ */
+ public function getByIds(array $ids)
+ {
+ // TODO: Implement getByIds() method.
+ }
+
+ /**
+ * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
+ *
+ * @param $what
+ *
+ * @return \AccountType|null
+ */
+ public function findByWhat($what)
+ {
+ // TODO: Implement findByWhat() method.
+ }
+
+ /**
+ * @param Carbon $start
+ * @param Carbon $end
+ *
+ * @return Collection
+ */
+ public function transactionsWithoutBudgetInDateRange(Carbon $start, Carbon $end)
+ {
+ // Add expenses that have no budget:
+ return \Auth::user()->transactionjournals()->whereNotIn(
+ 'transaction_journals.id', function ($query) use ($start, $end) {
+ $query->select('transaction_journals.id')->from('transaction_journals')
+ ->leftJoin(
+ 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=',
+ 'transaction_journals.id'
+ )
+ ->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')
+ ->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
+ ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
+ ->where('components.class', 'Budget');
+ }
+ )->before($end)->after($start)->lessThan(0)->transactionTypes(['Withdrawal'])->get();
+ }
+
+ /**
+ * @param Ardent $model
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function update(Ardent $model, array $data)
+ {
+ $model->name = $data['name'];
+ if (!$model->validate()) {
+ var_dump($model->errors()->all());
+ exit;
+ }
+
+
+ $model->save();
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Database/Category.php b/app/lib/FireflyIII/Database/Category.php
new file mode 100644
index 0000000000..47349ac021
--- /dev/null
+++ b/app/lib/FireflyIII/Database/Category.php
@@ -0,0 +1,129 @@
+setUser(\Auth::user());
+ }
+
+ /**
+ * @param Ardent $model
+ *
+ * @return bool
+ */
+ public function destroy(Ardent $model)
+ {
+ // TODO: Implement destroy() method.
+ }
+
+ /**
+ * Validates a model. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param Ardent $model
+ *
+ * @return array
+ */
+ public function validateObject(Ardent $model)
+ {
+ // TODO: Implement validateObject() method.
+ }
+
+ /**
+ * Validates an array. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param array $model
+ *
+ * @return array
+ */
+ public function validate(array $model)
+ {
+ // TODO: Implement validate() method.
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return Ardent
+ */
+ public function store(array $data)
+ {
+ // TODO: Implement store() method.
+ }
+
+ /**
+ * Returns an object with id $id.
+ *
+ * @param int $id
+ *
+ * @return Ardent
+ */
+ public function find($id)
+ {
+ // TODO: Implement find() method.
+ }
+
+ /**
+ * Returns all objects.
+ *
+ * @return Collection
+ */
+ public function get()
+ {
+ // TODO: Implement get() method.
+ }
+
+ /**
+ * @param array $ids
+ *
+ * @return Collection
+ */
+ public function getByIds(array $ids)
+ {
+ // TODO: Implement getByIds() method.
+ }
+
+ /**
+ * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
+ *
+ * @param $what
+ *
+ * @return \AccountType|null
+ */
+ public function findByWhat($what)
+ {
+ // TODO: Implement findByWhat() method.
+ }
+
+ /**
+ * @param Ardent $model
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function update(Ardent $model, array $data)
+ {
+ // TODO: Implement update() method.
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php b/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php
new file mode 100644
index 0000000000..a24fa07421
--- /dev/null
+++ b/app/lib/FireflyIII/Database/Ifaces/AccountInterface.php
@@ -0,0 +1,109 @@
+balance();
+ /** @var \Piggybank $p */
+ foreach ($account->piggybanks()->get() as $p) {
+ $balance -= $p->currentRelevantRep()->currentamount;
+ }
+
+ return $balance;
+
+ }
+
+ /**
+ *
+ */
+ public function __construct()
+ {
+ $this->setUser(\Auth::user());
+ }
+
+ /**
+ * @param Ardent $model
+ *
+ * @return bool
+ */
+ public function destroy(Ardent $model)
+ {
+ $model->delete();
+ }
+
+ /**
+ * Validates a model. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param Ardent $model
+ *
+ * @return array
+ */
+ public function validateObject(Ardent $model)
+ {
+ // TODO: Implement validateObject() method.
+ }
+
+ /**
+ * Validates an array. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param array $model
+ *
+ * @return array
+ */
+ public function validate(array $model)
+ {
+ $warnings = new MessageBag;
+ $successes = new MessageBag;
+ $errors = new MessageBag;
+
+ /*
+ * Name validation:
+ */
+ if (!isset($model['name'])) {
+ $errors->add('name', 'Name is mandatory');
+ }
+
+ if (isset($model['name']) && strlen($model['name']) == 0) {
+ $errors->add('name', 'Name is too short');
+ }
+ if (isset($model['name']) && strlen($model['name']) > 100) {
+ $errors->add('name', 'Name is too long');
+ }
+
+ if (intval($model['account_id']) == 0) {
+ $errors->add('account_id', 'Account is mandatory');
+ }
+ if ($model['targetdate'] == '' && isset($model['remind_me']) && intval($model['remind_me']) == 1) {
+ $errors->add('targetdate', 'Target date is mandatory when setting reminders.');
+ }
+ if ($model['targetdate'] != '') {
+ try {
+ new Carbon($model['targetdate']);
+ } catch (\Exception $e) {
+ $errors->add('date', 'Invalid date.');
+ }
+ }
+ if (floatval($model['targetamount']) < 0.01) {
+ $errors->add('targetamount', 'Amount should be above 0.01.');
+ }
+ if (!in_array(ucfirst($model['reminder']), \Config::get('firefly.piggybank_periods'))) {
+ $errors->add('reminder', 'Invalid reminder period (' . $model['reminder'] . ')');
+ }
+ // check period.
+ if (!$errors->has('reminder') && !$errors->has('targetdate') && isset($model['remind_me']) && intval($model['remind_me']) == 1) {
+ $today = new Carbon;
+ $target = new Carbon($model['targetdate']);
+ switch ($model['reminder']) {
+ case 'week':
+ $today->addWeek();
+ break;
+ case 'month':
+ $today->addMonth();
+ break;
+ case 'year':
+ $today->addYear();
+ break;
+ }
+ if ($today > $target) {
+ $errors->add('reminder', 'Target date is too close to today to set reminders.');
+ }
+ }
+
+ $validator = \Validator::make($model, \Piggybank::$rules);
+ if ($validator->invalid()) {
+ $errors->merge($errors);
+ }
+
+ // add ok messages.
+ $list = ['name', 'account_id', 'targetamount', 'targetdate', 'remind_me', 'reminder'];
+ foreach ($list as $entry) {
+ if (!$errors->has($entry) && !$warnings->has($entry)) {
+ $successes->add($entry, 'OK');
+ }
+ }
+
+ return [
+ 'errors' => $errors,
+ 'warnings' => $warnings,
+ 'successes' => $successes
+ ];
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return Ardent
+ */
+ public function store(array $data)
+ {
+ $data['rep_every'] = isset($data['rep_every']) ? $data['rep_every'] : 0;
+ $data['reminder_skip'] = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0;
+ $data['order'] = isset($data['order']) ? $data['order'] : 0;
+ $data['remind_me'] = isset($data['remind_me']) ? intval($data['remind_me']) : 0;
+ $data['startdate'] = isset($data['startdate']) ? $data['startdate'] : Carbon::now()->format('Y-m-d');
+ $data['targetdate'] = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null;
+
+
+ $piggybank = new \Piggybank($data);
+ if (!$piggybank->validate()) {
+ var_dump($piggybank->errors()->all());
+ exit;
+ }
+ $piggybank->save();
+ \Event::fire('piggybanks.store', [$piggybank]);
+ $piggybank->save();
+ }
+
+ /**
+ * Returns an object with id $id.
+ *
+ * @param int $id
+ *
+ * @return Ardent
+ */
+ public function find($id)
+ {
+ // TODO: Implement find() method.
+ }
+
+ /**
+ * Returns all objects.
+ *
+ * @return Collection
+ */
+ public function get()
+ {
+ return $this->getUser()->piggybanks()->where('repeats', 0)->get();
+ }
+
+ /**
+ * @param array $ids
+ *
+ * @return Collection
+ */
+ public function getByIds(array $ids)
+ {
+ // TODO: Implement getByIds() method.
+ }
+
+ /**
+ * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
+ *
+ * @param $what
+ *
+ * @return \AccountType|null
+ */
+ public function findByWhat($what)
+ {
+ // TODO: Implement findByWhat() method.
+ }
+
+ /**
+ * @param Ardent $model
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function update(Ardent $model, array $data)
+ {
+ /** @var \Piggybank $model */
+ $model->name = $data['name'];
+ $model->account_id = intval($data['account_id']);
+ $model->targetamount = floatval($data['targetamount']);
+ $model->targetdate = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null;
+ $model->rep_every = isset($data['rep_every']) ? $data['rep_every'] : 0;
+ $model->reminder_skip = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0;
+ $model->order = isset($data['order']) ? $data['order'] : 0;
+ $model->remind_me = isset($data['remind_me']) ? intval($data['remind_me']) : 0;
+ if(!$model->validate()) {
+ var_dump($model->errors());
+ exit();
+ }
+ $model->save();
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Database/Recurring.php b/app/lib/FireflyIII/Database/Recurring.php
new file mode 100644
index 0000000000..b8cb6ba29f
--- /dev/null
+++ b/app/lib/FireflyIII/Database/Recurring.php
@@ -0,0 +1,143 @@
+setUser(\Auth::user());
+ }
+
+ /**
+ * @param \RecurringTransaction $recurring
+ * @param Carbon $start
+ * @param Carbon $end
+ *
+ * @return \TransactionJournal|null
+ */
+ public function getJournalForRecurringInRange(\RecurringTransaction $recurring, Carbon $start, Carbon $end)
+ {
+ return $this->getUser()->transactionjournals()->where('recurring_transaction_id', $recurring->id)->after($start)->before($end)->first();
+
+ }
+
+ /**
+ * @param Ardent $model
+ *
+ * @return bool
+ */
+ public function destroy(Ardent $model)
+ {
+ // TODO: Implement destroy() method.
+ }
+
+ /**
+ * Validates a model. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param Ardent $model
+ *
+ * @return array
+ */
+ public function validateObject(Ardent $model)
+ {
+ // TODO: Implement validateObject() method.
+ }
+
+ /**
+ * Validates an array. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param array $model
+ *
+ * @return array
+ */
+ public function validate(array $model)
+ {
+ // TODO: Implement validate() method.
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return Ardent
+ */
+ public function store(array $data)
+ {
+ // TODO: Implement store() method.
+ }
+
+ /**
+ * Returns an object with id $id.
+ *
+ * @param int $id
+ *
+ * @return Ardent
+ */
+ public function find($id)
+ {
+ // TODO: Implement find() method.
+ }
+
+ /**
+ * Returns all objects.
+ *
+ * @return Collection
+ */
+ public function get()
+ {
+ return $this->getUser()->recurringtransactions()->get();
+ }
+
+ /**
+ * @param array $ids
+ *
+ * @return Collection
+ */
+ public function getByIds(array $ids)
+ {
+ // TODO: Implement getByIds() method.
+ }
+
+ /**
+ * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
+ *
+ * @param $what
+ *
+ * @return \AccountType|null
+ */
+ public function findByWhat($what)
+ {
+ // TODO: Implement findByWhat() method.
+ }
+
+ /**
+ * @param Ardent $model
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function update(Ardent $model, array $data)
+ {
+ // TODO: Implement update() method.
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Database/SwitchUser.php b/app/lib/FireflyIII/Database/SwitchUser.php
new file mode 100644
index 0000000000..3fa27d3f84
--- /dev/null
+++ b/app/lib/FireflyIII/Database/SwitchUser.php
@@ -0,0 +1,27 @@
+_user;
+ }
+
+ /**
+ * @param $user
+ */
+ public function setUser($user)
+ {
+ $this->_user = $user;
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Database/Transaction.php b/app/lib/FireflyIII/Database/Transaction.php
new file mode 100644
index 0000000000..744880dd73
--- /dev/null
+++ b/app/lib/FireflyIII/Database/Transaction.php
@@ -0,0 +1,195 @@
+add('account', 'No account present');
+ }
+ if (isset($model['account']) && !($model['account'] instanceof \Account)) {
+ $errors->add('account', 'No valid account present');
+ }
+ if (isset($model['account_id']) && intval($model['account_id']) < 0) {
+ $errors->add('account', 'No valid account_id present');
+ }
+
+ if (isset($model['piggybank_id']) && intval($model['piggybank_id']) < 0) {
+ $errors->add('piggybank', 'No valid piggybank_id present');
+ }
+
+ if (!isset($model['transaction_journal_id']) && !isset($model['transaction_journal'])) {
+ $errors->add('transaction_journal', 'No TJ present');
+ }
+ if (isset($model['transaction_journal']) && !($model['transaction_journal'] instanceof \TransactionJournal)) {
+ $errors->add('transaction_journal', 'No valid transaction_journal present');
+ }
+ if (isset($model['transaction_journal_id']) && intval($model['transaction_journal_id']) < 0) {
+ $errors->add('account', 'No valid transaction_journal_id present');
+ }
+
+ if (isset($model['description']) && strlen($model['description']) > 255) {
+ $errors->add('account', 'Description too long');
+ }
+
+ if (!isset($model['amount'])) {
+ $errors->add('amount', 'No amount present.');
+ }
+ if (isset($model['amount']) && floatval($model['amount']) == 0) {
+ $errors->add('amount', 'Invalid amount.');
+ }
+
+ if (!$errors->has('account')) {
+ $successes->add('account', 'OK');
+ }
+ if (!$errors->has('')) {
+ $successes->add('piggybank', 'OK');
+ }
+ if (!$errors->has('transaction_journal')) {
+ $successes->add('transaction_journal', 'OK');
+ }
+ if (!$errors->has('amount')) {
+ $successes->add('amount', 'OK');
+ }
+
+ return [
+ 'errors' => $errors,
+ 'warnings' => $warnings,
+ 'successes' => $successes
+ ];
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return Ardent
+ */
+ public function store(array $data)
+ {
+ // TODO: Implement store() method.
+ $transaction = new \Transaction;
+ $transaction->account()->associate($data['account']);
+ $transaction->transactionJournal()->associate($data['transaction_journal']);
+ $transaction->amount = floatval($data['amount']);
+ if (isset($data['piggybank'])) {
+ $transaction->piggybank()->associate($data['piggybank']);
+ }
+ if (isset($data['description'])) {
+ $transaction->description = $data['description'];
+ }
+ if ($transaction->validate()) {
+ $transaction->save();
+ } else {
+ throw new FireflyException($transaction->errors()->first());
+ }
+ return $transaction;
+ }
+
+ /**
+ * Returns an object with id $id.
+ *
+ * @param int $id
+ *
+ * @return Ardent
+ */
+ public function find($id)
+ {
+ // TODO: Implement find() method.
+ }
+
+ /**
+ * Returns all objects.
+ *
+ * @return Collection
+ */
+ public function get()
+ {
+ // TODO: Implement get() method.
+ }
+
+ /**
+ * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
+ *
+ * @param $what
+ *
+ * @return \AccountType|null
+ */
+ public function findByWhat($what)
+ {
+ // TODO: Implement findByWhat() method.
+ }
+
+ /**
+ * @param Ardent $model
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function update(Ardent $model, array $data)
+ {
+ // TODO: Implement update() method.
+ }
+
+ /**
+ * @param array $ids
+ *
+ * @return Collection
+ */
+ public function getByIds(array $ids)
+ {
+ // TODO: Implement getByIds() method.
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Database/TransactionCurrency.php b/app/lib/FireflyIII/Database/TransactionCurrency.php
new file mode 100644
index 0000000000..9e46efb207
--- /dev/null
+++ b/app/lib/FireflyIII/Database/TransactionCurrency.php
@@ -0,0 +1,130 @@
+first();
+ }
+
+ /**
+ * @param array $ids
+ *
+ * @return Collection
+ */
+ public function getByIds(array $ids)
+ {
+ // TODO: Implement getByIds() method.
+ }
+
+ /**
+ * @param Ardent $model
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function update(Ardent $model, array $data)
+ {
+ // TODO: Implement update() method.
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Database/TransactionJournal.php b/app/lib/FireflyIII/Database/TransactionJournal.php
new file mode 100644
index 0000000000..3355f458a8
--- /dev/null
+++ b/app/lib/FireflyIII/Database/TransactionJournal.php
@@ -0,0 +1,334 @@
+setUser(\Auth::user());
+ }
+
+ /**
+ * @param Carbon $date
+ *
+ * @return float
+ */
+ public function getSumOfIncomesByMonth(Carbon $date)
+ {
+ $end = clone $date;
+ $date->startOfMonth();
+ $end->endOfMonth();
+
+ $sum = \DB::table('transactions')
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id')
+ ->where('amount', '>', 0)
+ ->where('transaction_types.type', '=', 'Deposit')
+ ->where('transaction_journals.date', '>=', $date->format('Y-m-d'))
+ ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount');
+ $sum = floatval($sum);
+ return $sum;
+ }
+
+ /**
+ * @param Carbon $date
+ *
+ * @return float
+ */
+ public function getSumOfExpensesByMonth(Carbon $date)
+ {
+ $end = clone $date;
+ $date->startOfMonth();
+ $end->endOfMonth();
+
+ $sum = \DB::table('transactions')
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id')
+ ->where('amount', '>', 0)
+ ->where('transaction_types.type', '=', 'Withdrawal')
+ ->where('transaction_journals.date', '>=', $date->format('Y-m-d'))
+ ->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->sum('transactions.amount');
+ $sum = floatval($sum);
+ return $sum;
+ }
+
+ /**
+ * @param Carbon $start
+ * @param Carbon $end
+ *
+ * @return Collection
+ */
+ public function getInDateRange(Carbon $start, Carbon $end)
+ {
+ return $this->getuser()->transactionjournals()->withRelevantData()->before($end)->after($start)->get();
+ }
+
+ /**
+ * @return TransactionJournal
+ */
+ public function first()
+ {
+ return $this->getUser()->transactionjournals()->orderBy('date', 'ASC')->first();
+ }
+
+
+ /**
+ * @param Ardent $model
+ *
+ * @return bool
+ */
+ public function destroy(Ardent $model)
+ {
+ // TODO: Implement destroy() method.
+ }
+
+ /**
+ * Validates a model. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param Ardent $model
+ *
+ * @return array
+ */
+ public function validateObject(Ardent $model)
+ {
+ // TODO: Implement validateObject() method.
+ }
+
+ /**
+ * Validates an array. Returns an array containing MessageBags
+ * errors/warnings/successes.
+ *
+ * @param array $model
+ *
+ * @return array
+ */
+ public function validate(array $model)
+ {
+
+ $warnings = new MessageBag;
+ $successes = new MessageBag;
+ $errors = new MessageBag;
+
+
+ if (!isset($model['what'])) {
+ $errors->add('description', 'Internal error: need to know type of transaction!');
+ }
+ if (isset($model['recurring_transaction_id']) && intval($model['recurring_transaction_id']) < 0) {
+ $errors->add('recurring_transaction_id', 'Recurring transaction is invalid.');
+ }
+ if (!isset($model['description'])) {
+ $errors->add('description', 'This field is mandatory.');
+ }
+ if (isset($model['description']) && strlen($model['description']) == 0) {
+ $errors->add('description', 'This field is mandatory.');
+ }
+ if (isset($model['description']) && strlen($model['description']) > 255) {
+ $errors->add('description', 'Description is too long.');
+ }
+
+ if (!isset($model['currency'])) {
+ $errors->add('description', 'Internal error: currency is mandatory!');
+ }
+ if (isset($model['date']) && !($model['date'] instanceof Carbon) && strlen($model['date']) > 0) {
+ try {
+ new Carbon($model['date']);
+ } catch (\Exception $e) {
+ $errors->add('date', 'This date is invalid.');
+ }
+ }
+ if (!isset($model['date'])) {
+ $errors->add('date', 'This date is invalid.');
+ }
+
+ if (isset($model['to_id']) && intval($model['to_id']) < 0) {
+ $errors->add('account_to', 'Invalid to-account');
+ }
+ if (isset($model['from_id']) && intval($model['from_id']) < 0) {
+ $errors->add('account_from', 'Invalid from-account');
+ }
+ if (isset($model['to']) && !($model['to'] instanceof \Account)) {
+ $errors->add('account_to', 'Invalid to-account');
+ }
+ if (isset($model['from']) && !($model['from'] instanceof \Account)) {
+ $errors->add('account_from', 'Invalid from-account');
+ }
+ if (!isset($model['amount']) || (isset($model['amount']) && floatval($model['amount']) < 0)) {
+ $errors->add('amount', 'Invalid amount');
+ }
+ if (!isset($model['from']) && !isset($model['to'])) {
+ $errors->add('account_to', 'No accounts found!');
+ }
+
+ $validator = \Validator::make([$model], \Transaction::$rules);
+ if ($validator->invalid()) {
+ $errors->merge($errors);
+ }
+
+
+ /*
+ * Add "OK"
+ */
+ if (!$errors->has('description')) {
+ $successes->add('description', 'OK');
+ }
+ if (!$errors->has('date')) {
+ $successes->add('date', 'OK');
+ }
+ return [
+ 'errors' => $errors,
+ 'warnings' => $warnings,
+ 'successes' => $successes
+ ];
+
+
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return Ardent
+ */
+ public function store(array $data)
+ {
+
+ /** @var \FireflyIII\Database\TransactionType $typeRepository */
+ $typeRepository = \App::make('FireflyIII\Database\TransactionType');
+
+ /** @var \FireflyIII\Database\TransactionCurrency $currencyRepository */
+ $currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency');
+
+ /** @var \FireflyIII\Database\Transaction $transactionRepository */
+ $transactionRepository = \App::make('FireflyIII\Database\Transaction');
+
+ $journalType = $typeRepository->findByWhat($data['what']);
+ $currency = $currencyRepository->findByCode($data['currency']);
+
+ $journal = new \TransactionJournal;
+ $journal->transactionType()->associate($journalType);
+ $journal->transactionCurrency()->associate($currency);
+ $journal->user()->associate($this->getUser());
+ $journal->description = $data['description'];
+ $journal->date = $data['date'];
+ $journal->completed = 0;
+ //$journal->user_id = $this->getUser()->id;
+
+ /*
+ * This must be enough to store the journal:
+ */
+ if (!$journal->validate()) {
+ \Log::error($journal->errors()->all());
+ throw new FireflyException('store() transactionjournal failed, but it should not!');
+ }
+ $journal->save();
+
+ /*
+ * Then store both transactions.
+ */
+ $first = [
+ 'account' => $data['from'],
+ 'transaction_journal' => $journal,
+ 'amount' => ($data['amount'] * -1),
+ ];
+ $validate = $transactionRepository->validate($first);
+ if ($validate['errors']->count() == 0) {
+ $transactionRepository->store($first);
+ } else {
+ throw new FireflyException($validate['errors']->first());
+ }
+
+ $second = [
+ 'account' => $data['to'],
+ 'transaction_journal' => $journal,
+ 'amount' => floatval($data['amount']),
+ ];
+
+ $validate = $transactionRepository->validate($second);
+ if ($validate['errors']->count() == 0) {
+ $transactionRepository->store($second);
+ } else {
+ throw new FireflyException($validate['errors']->first());
+ }
+
+ $journal->completed = 1;
+ $journal->save();
+ return $journal;
+ }
+
+ /**
+ * Returns an object with id $id.
+ *
+ * @param int $id
+ *
+ * @return Ardent
+ */
+ public function find($id)
+ {
+ return $this->getUser()->transactionjournals()->find($id);
+ }
+
+ /**
+ * Returns all objects.
+ *
+ * @return Collection
+ */
+ public function get()
+ {
+ return $this->getUser()->transactionjournals()->get();
+ }
+
+ /**
+ * Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
+ *
+ * @param $what
+ *
+ * @return \AccountType|null
+ */
+ public function findByWhat($what)
+ {
+ // TODO: Implement findByWhat() method.
+ }
+
+ /**
+ * @param array $ids
+ *
+ * @return Collection
+ */
+ public function getByIds(array $ids)
+ {
+ // TODO: Implement getByIds() method.
+ }
+
+ /**
+ * @param Ardent $model
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function update(Ardent $model, array $data)
+ {
+ // TODO: Implement update() method.
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Database/TransactionType.php b/app/lib/FireflyIII/Database/TransactionType.php
new file mode 100644
index 0000000000..0022ec36fb
--- /dev/null
+++ b/app/lib/FireflyIII/Database/TransactionType.php
@@ -0,0 +1,129 @@
+first();
+ break;
+ default:
+ throw new FireflyException('Cannot find transaction type described as "' . e($what) . '".');
+ break;
+
+ }
+ return null;
+ }
+
+ /**
+ * @param array $ids
+ *
+ * @return Collection
+ */
+ public function getByIds(array $ids)
+ {
+ // TODO: Implement getByIds() method.
+ }
+
+ /**
+ * @param Ardent $model
+ * @param array $data
+ *
+ * @return bool
+ */
+ public function update(Ardent $model, array $data)
+ {
+ // TODO: Implement update() method.
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Exception/NotImplementedException.php b/app/lib/FireflyIII/Exception/NotImplementedException.php
new file mode 100644
index 0000000000..208566204f
--- /dev/null
+++ b/app/lib/FireflyIII/Exception/NotImplementedException.php
@@ -0,0 +1,13 @@
+ intval(\Input::get('start')),
+ 'length' => $length,
+ 'draw' => intval(\Input::get('draw')),
+ ];
+
+
+ /*
+ * Columns:
+ */
+ if (!is_null(\Input::get('columns')) && is_array(\Input::get('columns'))) {
+ foreach (\Input::get('columns') as $column) {
+ $parameters['columns'][] = [
+ 'data' => $column['data'],
+ 'name' => $column['name'],
+ 'searchable' => $column['searchable'] == 'true' ? true : false,
+ 'orderable' => $column['orderable'] == 'true' ? true : false,
+ 'search' => [
+ 'value' => $column['search']['value'],
+ 'regex' => $column['search']['regex'] == 'true' ? true : false,
+ ]
+ ];
+ }
+ }
+
+
+ /*
+ * Sorting.
+ */
+ $parameters['orderOnAccount'] = false;
+ if (!is_null(\Input::get('order')) && is_array(\Input::get('order'))) {
+ foreach (\Input::get('order') as $order) {
+ $columnIndex = intval($order['column']);
+ $columnName = $parameters['columns'][$columnIndex]['name'];
+ $parameters['order'][] = [
+ 'name' => $columnName,
+ 'dir' => strtoupper($order['dir'])
+ ];
+ if ($columnName == 'to' || $columnName == 'from') {
+ $parameters['orderOnAccount'] = true;
+ }
+ }
+ }
+ /*
+ * Search parameters:
+ */
+ $parameters['search'] = [
+ 'value' => '',
+ 'regex' => false
+ ];
+ if (!is_null(\Input::get('search')) && is_array(\Input::get('search'))) {
+ $search = \Input::get('search');
+ $parameters['search'] = [
+ 'value' => $search['value'],
+ 'regex' => $search['regex'] == 'true' ? true : false
+ ];
+ }
+ return $parameters;
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Shared/Preferences/Preferences.php b/app/lib/FireflyIII/Shared/Preferences/Preferences.php
new file mode 100644
index 0000000000..0fa5bfda7a
--- /dev/null
+++ b/app/lib/FireflyIII/Shared/Preferences/Preferences.php
@@ -0,0 +1,58 @@
+id)->where('name', $name)->first();
+ if (is_null($default) && is_null($pref)) {
+ // return NULL
+ return null;
+ }
+ if (!is_null($pref)) {
+ return $pref;
+ }
+ if (!is_null($default) && is_null($pref)) {
+ // create preference, return that:
+ return $this->set($name, $default);
+ }
+
+ return null;
+
+ }
+
+ /**
+ * @param $name
+ * @param $value
+ *
+ * @return \Preference
+ */
+ public function set($name, $value)
+ {
+ $pref = \Preference::where('user_id', \Auth::user()->id)->where('name', $name)->first();
+ if (is_null($pref)) {
+ $pref = new \Preference;
+ $pref->name = $name;
+ $pref->user()->associate(\Auth::user());
+
+ }
+ $pref->data = $value;
+ $pref->save();
+
+
+ return $pref;
+
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Shared/Preferences/PreferencesInterface.php b/app/lib/FireflyIII/Shared/Preferences/PreferencesInterface.php
new file mode 100644
index 0000000000..4e7389695f
--- /dev/null
+++ b/app/lib/FireflyIII/Shared/Preferences/PreferencesInterface.php
@@ -0,0 +1,29 @@
+addDay();
+ break;
+ case 'weekly':
+ $currentEnd->addWeek()->subDay();
+ break;
+ case 'monthly':
+ $currentEnd->addMonth()->subDay();
+ break;
+ case 'quarterly':
+ $currentEnd->addMonths(3)->subDay();
+ break;
+ case 'half-year':
+ $currentEnd->addMonths(6)->subDay();
+ break;
+ case 'yearly':
+ $currentEnd->addYear()->subDay();
+ break;
+ }
+ }
+
+ /**
+ * @param Carbon $date
+ * @param $repeatFreq
+ * @param $skip
+ *
+ * @return Carbon
+ * @throws FireflyException
+ */
+ public function addPeriod(Carbon $date, $repeatFreq, $skip)
+ {
+ $add = ($skip + 1);
+ switch ($repeatFreq) {
+ default:
+ throw new FireflyException('Cannot do addPeriod for $repeat_freq ' . $repeatFreq);
+ break;
+ case 'daily':
+ $date->addDays($add);
+ break;
+ case 'weekly':
+ $date->addWeeks($add);
+ break;
+ case 'monthly':
+ $date->addMonths($add);
+ break;
+ case 'quarterly':
+ $months = $add * 3;
+ $date->addMonths($months);
+ break;
+ case 'half-year':
+ $months = $add * 6;
+ $date->addMonths($months);
+ break;
+ case 'yearly':
+ $date->addYears($add);
+ break;
+ }
+ return $date;
+ }
+}
\ No newline at end of file
diff --git a/app/lib/FireflyIII/Shared/Toolkit/Form.php b/app/lib/FireflyIII/Shared/Toolkit/Form.php
new file mode 100644
index 0000000000..7383a0e7a2
--- /dev/null
+++ b/app/lib/FireflyIII/Shared/Toolkit/Form.php
@@ -0,0 +1,50 @@
+id);
+ $title = null;
+ if (is_null($titleField)) {
+ // try 'title' field.
+ if (isset($entry->title)) {
+ $title = $entry->title;
+ }
+ // try 'name' field
+ if (is_null($title)) {
+ $title = $entry->name;
+ }
+
+ // try 'description' field
+ if (is_null($title)) {
+ $title = $entry->description;
+ }
+ } else {
+ $title = $entry->$titleField;
+ }
+ $selectList[$id] = $title;
+ }
+ return $selectList;
+ }
+
+}
\ No newline at end of file
diff --git a/app/models/Limit.php b/app/models/Limit.php
index 5c11896933..49571e2d25 100644
--- a/app/models/Limit.php
+++ b/app/models/Limit.php
@@ -89,9 +89,9 @@ class Limit extends Ardent
break;
}
$end->subDay();
- $count = $this->limitrepetitions()->where('startdate', $start->format('Y-m-d'))->where(
- 'enddate', $start->format('Y-m-d')
- )->count();
+ $count = $this->limitrepetitions()->where('startdate', $start->format('Y-m-d'))->where('enddate', $end->format('Y-m-d'))->count();
+ \Log::debug('All: '.$this->limitrepetitions()->count().' (#'.$this->id.')');
+ \Log::debug('Found ' . $count.' limit-reps for limit #' . $this->id.' with start '.$start->format('Y-m-d') .' and end ' . $end->format('Y-m-d'));
if ($count == 0) {
@@ -115,6 +115,12 @@ class Limit extends Ardent
if (isset($repetition->id)) {
\Event::fire('limits.repetition', [$repetition]);
}
+ } else if($count == 1) {
+ // update this one:
+ $repetition = $this->limitrepetitions()->where('startdate', $start->format('Y-m-d'))->where('enddate', $end->format('Y-m-d'))->first();
+ $repetition->amount = $this->amount;
+ $repetition->save();
+
}
}
diff --git a/app/models/LimitRepetition.php b/app/models/LimitRepetition.php
index 943512aed4..0c4188bbb7 100644
--- a/app/models/LimitRepetition.php
+++ b/app/models/LimitRepetition.php
@@ -5,14 +5,14 @@ use LaravelBook\Ardent\Ardent as Ardent;
/**
* LimitRepetition
*
- * @property integer $id
+ * @property integer $id
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
- * @property integer $limit_id
+ * @property integer $limit_id
* @property \Carbon\Carbon $startdate
* @property \Carbon\Carbon $enddate
- * @property float $amount
- * @property-read \Limit $limit
+ * @property float $amount
+ * @property-read \Limit $limit
* @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereId($value)
* @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereCreatedAt($value)
* @method static \Illuminate\Database\Query\Builder|\LimitRepetition whereUpdatedAt($value)
@@ -39,29 +39,27 @@ class LimitRepetition extends Ardent
return ['created_at', 'updated_at', 'startdate', 'enddate'];
}
+ public function spentInRepetition() {
+ $sum = \DB::table('transactions')
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->leftJoin('component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
+ ->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')
+ ->leftJoin('limits', 'limits.component_id', '=', 'components.id')
+ ->leftJoin('limit_repetitions', 'limit_repetitions.limit_id', '=', 'limits.id')
+ ->where('transaction_journals.date', '>=', $this->startdate->format('Y-m-d'))
+ ->where('transaction_journals.date', '<=', $this->enddate->format('Y-m-d'))
+ ->where('transactions.amount', '>', 0)
+ ->where('limit_repetitions.id', '=', $this->id)->sum('transactions.amount');
+ return floatval($sum);
+ }
+
/**
* How much money is left in this?
*/
public function leftInRepetition()
{
- $left = floatval($this->amount);
+ return floatval($this->amount - $this->spentInRepetition());
- // budget:
- $budget = $this->limit->budget;
-
- /** @var \Firefly\Storage\Limit\EloquentLimitRepository $limits */
- $limits = App::make('Firefly\Storage\Limit\EloquentLimitRepository');
- $set = $limits->getTJByBudgetAndDateRange($budget, $this->startdate, $this->enddate);
-
- foreach ($set as $journal) {
- foreach ($journal->transactions as $t) {
- if ($t->amount < 0) {
- $left += floatval($t->amount);
- }
- }
- }
-
- return $left;
}
/**
@@ -85,8 +83,10 @@ class LimitRepetition extends Ardent
}
switch ($this->repeat_freq) {
default:
- throw new \Firefly\Exception\FireflyException('No date formats for frequency "' . $this->repeat_freq
- . '"!');
+ throw new \Firefly\Exception\FireflyException(
+ 'No date formats for frequency "' . $this->repeat_freq
+ . '"!'
+ );
break;
case 'daily':
return $this->startdate->format('Ymd') . '-5';
@@ -119,8 +119,10 @@ class LimitRepetition extends Ardent
}
switch ($this->repeat_freq) {
default:
- throw new \Firefly\Exception\FireflyException('No date formats for frequency "' . $this->repeat_freq
- . '"!');
+ throw new \Firefly\Exception\FireflyException(
+ 'No date formats for frequency "' . $this->repeat_freq
+ . '"!'
+ );
break;
case 'daily':
return $this->startdate->format('j F Y');
diff --git a/app/models/Piggybank.php b/app/models/Piggybank.php
index b754e133f2..143f900543 100644
--- a/app/models/Piggybank.php
+++ b/app/models/Piggybank.php
@@ -56,6 +56,7 @@ class Piggybank extends Ardent
'rep_times' => 'min:1|max:100', // how many times do you want to save this amount? eg. 3 times
'reminder' => 'in:day,week,month,year', // want a reminder to put money in this?
'reminder_skip' => 'required|min:0|max:100', // every week? every 2 months?
+ 'remind_me' => 'required|boolean',
'order' => 'required:min:1', // not yet used.
];
public $fillable
@@ -71,6 +72,7 @@ class Piggybank extends Ardent
'rep_times',
'reminder',
'reminder_skip',
+ 'remind_me',
'order'
];
@@ -90,7 +92,6 @@ class Piggybank extends Ardent
$rep->targetdate = $target;
$rep->currentamount = 0;
$rep->save();
-
\Event::fire('piggybanks.repetition', [$rep]);
return $rep;
diff --git a/app/models/TransactionJournal.php b/app/models/TransactionJournal.php
index 41c8f79805..fb760e6782 100644
--- a/app/models/TransactionJournal.php
+++ b/app/models/TransactionJournal.php
@@ -4,242 +4,6 @@ use Carbon\Carbon;
use LaravelBook\Ardent\Ardent;
use LaravelBook\Ardent\Builder;
-/**
- * TransactionJournal
- *
- * @property integer $id
- * @property \Carbon\Carbon $created_at
- * @property \Carbon\Carbon $updated_at
- * @property integer $user_id
- * @property integer $transaction_type_id
- * @property integer $transaction_currency_id
- * @property string $description
- * @property boolean $completed
- * @property \Carbon\Carbon $date
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * 'Budget[] $budgets
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * 'Category[] $categories
- * @property-read \Illuminate\Database\Eloquent\Collection|\Component[] $components
- * @property-read \TransactionCurrency $transactionCurrency
- * @property-read \TransactionType $transactionType
- * @property-read \Illuminate\Database\Eloquent\Collection|\Transaction[] $transactions
- * @property-read \User $user
- * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereId($value)
- * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCreatedAt($value)
- * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereUpdatedAt($value)
- * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereUserId($value)
- * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionTypeId($value)
- * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereTransactionCurrencyId($value)
- * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDescription($value)
- * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereCompleted($value)
- * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereDate($value)
- * @method static \TransactionJournal account($account)
- * @method static \TransactionJournal after($date)
- * @method static \TransactionJournal before($date)
- * @method static \TransactionJournal defaultSorting()
- * @method static \TransactionJournal moreThan($amount)
- * @method static \TransactionJournal lessThan($amount)
- * @method static \TransactionJournal onDate($date)
- * @method static \TransactionJournal transactionTypes($types)
- * @method static \TransactionJournal withRelevantData()
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * 'Budget[] $budgets
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * 'Category[] $categories
- * @property integer $recurring_transaction_id
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * 'Budget[] $budgets
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * 'Category[] $categories
- * @property-read \RecurringTransaction $recurringTransaction
- * @method static \Illuminate\Database\Query\Builder|\TransactionJournal whereRecurringTransactionId($value)
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * 'Budget[] $budgets
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * 'Category[] $categories
- * @method static \TransactionJournal accountIs($account)
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * '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
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * 'Budget[] $budgets
- * @property-read \Illuminate\Database\Eloquent\Collection|\
- * 'Category[] $categories
- */
class TransactionJournal extends Ardent
{
@@ -259,7 +23,7 @@ class TransactionJournal extends Ardent
public function budgets()
{
return $this->belongsToMany(
- 'Budget', 'component_transaction_journal', 'transaction_journal_id', 'component_id'
+ 'Budget', 'component_transaction_journal', 'transaction_journal_id', 'component_id'
);
}
@@ -269,7 +33,7 @@ class TransactionJournal extends Ardent
public function categories()
{
return $this->belongsToMany(
- 'Category', 'component_transaction_journal', 'transaction_journal_id', 'component_id'
+ 'Category', 'component_transaction_journal', 'transaction_journal_id', 'component_id'
);
}
@@ -281,6 +45,20 @@ class TransactionJournal extends Ardent
return $this->belongsToMany('Component');
}
+ /**
+ * @return float
+ */
+ public function getAmount()
+ {
+
+ foreach ($this->transactions as $t) {
+ if (floatval($t->amount) > 0) {
+ return floatval($t->amount);
+ }
+ }
+ return -0.01;
+ }
+
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
@@ -312,7 +90,7 @@ class TransactionJournal extends Ardent
/**
* @param $query
- * @param Carbon $date
+ * @param Carbon $date
*
* @return mixed
*/
@@ -323,7 +101,7 @@ class TransactionJournal extends Ardent
/**
* @param $query
- * @param Carbon $date
+ * @param Carbon $date
*
* @return mixed
*/
@@ -340,8 +118,10 @@ class TransactionJournal extends Ardent
public function scopeMoreThan(Builder $query, $amount)
{
if (is_null($this->joinedTransactions)) {
- $query->leftJoin('transactions', 'transactions.transaction_journal_id', '=',
- 'transaction_journals.id');
+ $query->leftJoin(
+ 'transactions', 'transactions.transaction_journal_id', '=',
+ 'transaction_journals.id'
+ );
$this->joinedTransactions = true;
}
@@ -351,8 +131,10 @@ class TransactionJournal extends Ardent
public function scopeLessThan(Builder $query, $amount)
{
if (is_null($this->joinedTransactions)) {
- $query->leftJoin('transactions', 'transactions.transaction_journal_id', '=',
- 'transaction_journals.id');
+ $query->leftJoin(
+ 'transactions', 'transactions.transaction_journal_id', '=',
+ 'transaction_journals.id'
+ );
$this->joinedTransactions = true;
}
@@ -373,8 +155,10 @@ class TransactionJournal extends Ardent
public function scopeTransactionTypes(Builder $query, array $types)
{
if (is_null($this->joinedTransactionTypes)) {
- $query->leftJoin('transaction_types', 'transaction_types.id', '=',
- 'transaction_journals.transaction_type_id');
+ $query->leftJoin(
+ 'transaction_types', 'transaction_types.id', '=',
+ 'transaction_journals.transaction_type_id'
+ );
$this->joinedTransactionTypes = true;
}
$query->whereIn('transaction_types.type', $types);
@@ -389,11 +173,11 @@ class TransactionJournal extends Ardent
public function scopeWithRelevantData(Builder $query)
{
$query->with(
- ['transactions' => function ($q) {
- $q->orderBy('amount', 'ASC');
- }, 'transactiontype', 'components' => function ($q) {
- $q->orderBy('class');
- }, 'transactions.account.accounttype','recurringTransaction']
+ ['transactions' => function ($q) {
+ $q->orderBy('amount', 'ASC');
+ }, 'transactiontype', 'components' => function ($q) {
+ $q->orderBy('class');
+ }, 'transactions.account.accounttype', 'recurringTransaction']
);
}
diff --git a/app/routes.php b/app/routes.php
index 535b161678..4d85b37703 100644
--- a/app/routes.php
+++ b/app/routes.php
@@ -3,174 +3,183 @@
//use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-
// models:
-Route::bind('account', function($value, $route)
- {
- if(Auth::check()) {
+Route::bind(
+ 'account', function ($value, $route) {
+ if (Auth::check()) {
$account = Account::
- leftJoin('account_types','account_types.id','=','accounts.account_type_id')->
- where('account_types.editable',1)->
- where('accounts.id', $value)->
- where('user_id',Auth::user()->id)->
- first(['accounts.*']);
- if($account) {
+ leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')->where('account_types.editable', 1)->where('accounts.id', $value)
+ ->where('user_id', Auth::user()->id)->first(['accounts.*']);
+ if ($account) {
return $account;
}
}
App::abort(404);
- });
-
-Route::bind('accountname', function($value, $route)
- {
- if(Auth::check()) {
- return Account::
- leftJoin('account_types','account_types.id','=','accounts.account_type_id')->
- where('account_types.editable',1)->
- where('name', $value)->
- where('user_id',Auth::user()->id)->first();
- }
- return null;
- });
-
-
-Route::bind('recurring', function($value, $route)
- {
- if(Auth::check()) {
- return RecurringTransaction::
- where('id', $value)->
- where('user_id',Auth::user()->id)->first();
- }
- return null;
- });
-Route::bind('budget', function($value, $route)
- {
- if(Auth::check()) {
- return Budget::
- where('id', $value)->
- where('user_id',Auth::user()->id)->first();
- }
- return null;
- });
-
-Route::bind('reminder', function($value, $route)
- {
- if(Auth::check()) {
- return Reminder::
- where('id', $value)->
- where('user_id',Auth::user()->id)->first();
- }
- return null;
- });
-
-Route::bind('category', function($value, $route)
-{
- if(Auth::check()) {
- return Category::
- where('id', $value)->
- where('user_id',Auth::user()->id)->first();
}
- return null;
-});
+);
-Route::bind('tj', function($value, $route)
- {
- if(Auth::check()) {
+Route::bind(
+ 'accountname', function ($value, $route) {
+ if (Auth::check()) {
+ return Account::
+ leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')->where('account_types.editable', 1)->where('name', $value)->where(
+ 'user_id', Auth::user()->id
+ )->first();
+ }
+ return null;
+ }
+);
+
+
+Route::bind(
+ 'recurring', function ($value, $route) {
+ if (Auth::check()) {
+ return RecurringTransaction::
+ where('id', $value)->where('user_id', Auth::user()->id)->first();
+ }
+ return null;
+ }
+);
+Route::bind(
+ 'budget', function ($value, $route) {
+ if (Auth::check()) {
+ return Budget::
+ where('id', $value)->where('user_id', Auth::user()->id)->first();
+ }
+ return null;
+ }
+);
+
+Route::bind(
+ 'reminder', function ($value, $route) {
+ if (Auth::check()) {
+ return Reminder::
+ where('id', $value)->where('user_id', Auth::user()->id)->first();
+ }
+ return null;
+ }
+);
+
+Route::bind(
+ 'category', function ($value, $route) {
+ if (Auth::check()) {
+ return Category::
+ where('id', $value)->where('user_id', Auth::user()->id)->first();
+ }
+ return null;
+ }
+);
+
+Route::bind(
+ 'tj', function ($value, $route) {
+ if (Auth::check()) {
return TransactionJournal::
- where('id', $value)->
- where('user_id',Auth::user()->id)->first();
+ where('id', $value)->where('user_id', Auth::user()->id)->first();
}
return null;
- });
+ }
+);
-Route::bind('limit', function($value, $route)
- {
- if(Auth::check()) {
+Route::bind(
+ 'limit', function ($value, $route) {
+ if (Auth::check()) {
return Limit::
- where('limits.id', $value)->
- leftJoin('components','components.id','=','limits.component_id')->
- where('components.class','Budget')->
- where('components.user_id',Auth::user()->id)->first(['limits.*']);
+ where('limits.id', $value)->leftJoin('components', 'components.id', '=', 'limits.component_id')->where('components.class', 'Budget')->where(
+ 'components.user_id', Auth::user()->id
+ )->first(['limits.*']);
}
return null;
- });
+ }
+);
-Route::bind('limitrepetition', function($value, $route)
- {
- if(Auth::check()) {
+Route::bind(
+ 'limitrepetition', function ($value, $route) {
+ if (Auth::check()) {
return LimitRepetition::
- where('limit_repetitions.id', $value)->
- leftjoin('limits','limits.id','=','limit_repetitions.limit_id')->
- leftJoin('components','components.id','=','limits.component_id')->
- where('components.class','Budget')->
- where('components.user_id',Auth::user()->id)->first(['limit_repetitions.*']);
+ where('limit_repetitions.id', $value)->leftjoin('limits', 'limits.id', '=', 'limit_repetitions.limit_id')->leftJoin(
+ 'components', 'components.id', '=', 'limits.component_id'
+ )->where('components.class', 'Budget')->where('components.user_id', Auth::user()->id)->first(['limit_repetitions.*']);
}
return null;
- });
+ }
+);
-Route::bind('piggybank', function($value, $route)
- {
- if(Auth::check()) {
+Route::bind(
+ 'piggybank', function ($value, $route) {
+ if (Auth::check()) {
return Piggybank::
- where('piggybanks.id', $value)->
- leftJoin('accounts','accounts.id','=','piggybanks.account_id')->
- where('accounts.user_id',Auth::user()->id)->first(['piggybanks.*']);
+ where('piggybanks.id', $value)->leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where('accounts.user_id', Auth::user()->id)
+ ->first(['piggybanks.*']);
}
return null;
- });
-
+ }
+);
// a development route:
Route::get('/dev', ['uses' => 'HomeController@jobDev']);
// protected routes:
-Route::group(['before' => 'auth'], function () {
-
-
+Route::group(
+ ['before' => 'auth'], function () {
// some date routes:
- Route::get('/prev',['uses' => 'HomeController@sessionPrev', 'as' => 'sessionPrev']);
- Route::get('/next',['uses' => 'HomeController@sessionNext', 'as' => 'sessionNext']);
- Route::get('/jump/{range}',['uses' => 'HomeController@rangeJump','as' => 'rangeJump']);
+ Route::get('/prev', ['uses' => 'HomeController@sessionPrev', 'as' => 'sessionPrev']);
+ Route::get('/next', ['uses' => 'HomeController@sessionNext', 'as' => 'sessionNext']);
+ Route::get('/jump/{range}', ['uses' => 'HomeController@rangeJump', 'as' => 'rangeJump']);
+ Route::get('/cleanup', ['uses' => 'HomeController@cleanup', 'as' => 'cleanup']);
// account controller:
- Route::get('/accounts', ['uses' => 'AccountController@index', 'as' => 'accounts.index']);
- Route::get('/accounts/asset', ['uses' => 'AccountController@asset', 'as' => 'accounts.asset']);
- Route::get('/accounts/expense', ['uses' => 'AccountController@expense', 'as' => 'accounts.expense']);
- Route::get('/accounts/revenue', ['uses' => 'AccountController@revenue', 'as' => 'accounts.revenue']);
-
- Route::get('/accounts/create/{what}', ['uses' => 'AccountController@create', 'as' => 'accounts.create'])->where('what','revenue|asset|expense');
- Route::get('/accounts/{account}', ['uses' => 'AccountController@show', 'as' => 'accounts.show']);
- Route::get('/accounts/{account}/edit', ['uses' => 'AccountController@edit', 'as' => 'accounts.edit']);
- Route::get('/accounts/{account}/delete', ['uses' => 'AccountController@delete', 'as' => 'accounts.delete']);
+ Route::get('/accounts/json/{what}', ['uses' => 'AccountController@json', 'as' => 'accounts.json'])->where('what', 'revenue|asset|expense');
+ Route::get('/accounts/{what}', ['uses' => 'AccountController@index', 'as' => 'accounts.index'])->where('what', 'revenue|asset|expense');
+ Route::get('/accounts/create/{what}', ['uses' => 'AccountController@create', 'as' => 'accounts.create'])->where('what', 'revenue|asset|expense');
+ Route::get('/accounts/edit/{account}', ['uses' => 'AccountController@edit', 'as' => 'accounts.edit']);
+ Route::get('/accounts/delete/{account}', ['uses' => 'AccountController@delete', 'as' => 'accounts.delete']);
+ Route::get('/accounts/show/{account}', ['uses' => 'AccountController@show', 'as' => 'accounts.show']);
// budget controller:
- Route::get('/budgets/date',['uses' => 'BudgetController@indexByDate','as' => 'budgets.index.date']);
- Route::get('/budgets/budget',['uses' => 'BudgetController@indexByBudget','as' => 'budgets.index.budget']);
- Route::get('/budgets/create',['uses' => 'BudgetController@create', 'as' => 'budgets.create']);
+ Route::get('/budgets', ['uses' => 'BudgetController@index', 'as' => 'budgets.index']);
+ Route::get('/budgets/income', ['uses' => 'BudgetController@updateIncome', 'as' => 'budgets.income']);
+ Route::get('/budgets/show/{budget}/{limitrepetition?}', ['uses' => 'BudgetController@show', 'as' => 'budgets.show']);
- Route::get('/budgets/nobudget/{period}',['uses' => 'BudgetController@nobudget', 'as' => 'budgets.nobudget']);
+ #Route::get('/budgets/date', ['uses' => 'BudgetController@indexByDate', 'as' => 'budgets.index.date']);
+ #Route::get('/budgets/budget', ['uses' => 'BudgetController@indexByBudget', 'as' => 'budgets.index.budget']);
+ Route::get('/budgets/create', ['uses' => 'BudgetController@create', 'as' => 'budgets.create']);
+ #Route::get('/budgets/nobudget/{period}', ['uses' => 'BudgetController@nobudget', 'as' => 'budgets.nobudget']);
- Route::get('/budgets/show/{budget}/{limitrepetition?}',['uses' => 'BudgetController@show', 'as' => 'budgets.show']);
- Route::get('/budgets/edit/{budget}',['uses' => 'BudgetController@edit', 'as' => 'budgets.edit']);
- Route::get('/budgets/delete/{budget}',['uses' => 'BudgetController@delete', 'as' => 'budgets.delete']);
+ Route::get('/budgets/edit/{budget}', ['uses' => 'BudgetController@edit', 'as' => 'budgets.edit']);
+ Route::get('/budgets/delete/{budget}', ['uses' => 'BudgetController@delete', 'as' => 'budgets.delete']);
// category controller:
- Route::get('/categories',['uses' => 'CategoryController@index','as' => 'categories.index']);
- Route::get('/categories/create',['uses' => 'CategoryController@create','as' => 'categories.create']);
- Route::get('/categories/show/{category}',['uses' => 'CategoryController@show','as' => 'categories.show']);
- Route::get('/categories/edit/{category}',['uses' => 'CategoryController@edit','as' => 'categories.edit']);
- Route::get('/categories/delete/{category}',['uses' => 'CategoryController@delete','as' => 'categories.delete']);
+ Route::get('/categories', ['uses' => 'CategoryController@index', 'as' => 'categories.index']);
+ Route::get('/categories/create', ['uses' => 'CategoryController@create', 'as' => 'categories.create']);
+ Route::get('/categories/show/{category}', ['uses' => 'CategoryController@show', 'as' => 'categories.show']);
+ Route::get('/categories/edit/{category}', ['uses' => 'CategoryController@edit', 'as' => 'categories.edit']);
+ Route::get('/categories/delete/{category}', ['uses' => 'CategoryController@delete', 'as' => 'categories.delete']);
+
+ // google chart controller
+ Route::get('/chart/home/account', ['uses' => 'GoogleChartController@allAccountsBalanceChart']);
+ Route::get('/chart/home/budgets', ['uses' => 'GoogleChartController@allBudgetsHomeChart']);
+ Route::get('/chart/home/categories', ['uses' => 'GoogleChartController@allCategoriesHomeChart']);
+ Route::get('/chart/home/recurring', ['uses' => 'GoogleChartController@recurringTransactionsOverview']);
+ Route::get('/chart/account/{account}', ['uses' => 'GoogleChartController@accountBalanceChart']);
+ Route::get('/chart/sankey/{account}/out', ['uses' => 'GoogleChartController@accountSankeyOutChart']);
+ Route::get('/chart/sankey/{account}/in', ['uses' => 'GoogleChartController@accountSankeyInChart']);
+ Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']);
+ Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']);
+ Route::get('/chart/reports/budgets/{year}', ['uses' => 'GoogleChartController@budgetsReportChart']);
+ Route::get('/chart/budgets/{budget}/spending/{year}', ['uses' => 'GoogleChartController@budgetsAndSpending']);
+
+ // google table controller
+ Route::get('/table/account/{account}/transactions', ['uses' => 'GoogleTableController@transactionsByAccount']);
+ Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']);
+ Route::get('/table/budget/{budget}/{limitrepetition?}/transactions', ['uses' => 'GoogleTableController@transactionsByBudget']);
+
- // chart controller
- Route::get('/chart/home/account/{account?}', ['uses' => 'ChartController@homeAccount', 'as' => 'chart.home']);
- Route::get('/chart/home/categories', ['uses' => 'ChartController@homeCategories', 'as' => 'chart.categories']);
- Route::get('/chart/home/budgets', ['uses' => 'ChartController@homeBudgets', 'as' => 'chart.budgets']);
Route::get('/chart/home/info/{accountnameA}/{day}/{month}/{year}', ['uses' => 'ChartController@homeAccountInfo', 'as' => 'chart.info']);
- Route::get('/chart/categories/show/{category}', ['uses' => 'ChartController@categoryShowChart','as' => 'chart.showcategory']);
- Route::get('/chart/home/recurring', ['uses' => 'ChartController@homeRecurring', 'as' => 'chart.recurring']);
+ Route::get('/chart/categories/show/{category}', ['uses' => 'ChartController@categoryShowChart', 'as' => 'chart.showcategory']);
+
// (new charts for budgets)
Route::get('/chart/budget/{budget}/default', ['uses' => 'ChartController@budgetDefault', 'as' => 'chart.budget.default']);
Route::get('chart/budget/{budget}/no_envelope', ['uses' => 'ChartController@budgetNoLimits', 'as' => 'chart.budget.nolimit']);
@@ -192,96 +201,111 @@ Route::group(['before' => 'auth'], function () {
Route::get('/json/recurringjournals/{recurring}', ['uses' => 'JsonController@recurringjournals', 'as' => 'json.recurringjournals']);
// 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']);
- Route::get('/budgets/limits/edit/{limit}',['uses' => 'LimitController@edit','as' => 'budgets.limits.edit']);
+ 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']);
+ Route::get('/budgets/limits/edit/{limit}', ['uses' => 'LimitController@edit', 'as' => 'budgets.limits.edit']);
- Route::get('/migrate',['uses' => 'MigrateController@index', 'as' => 'migrate.index']);
+ Route::get('/migrate', ['uses' => 'MigrateController@index', 'as' => 'migrate.index']);
// piggy bank controller
- Route::get('/piggybanks',['uses' => 'PiggybankController@piggybanks','as' => 'piggybanks.index.piggybanks']);
- Route::get('/repeated',['uses' => 'PiggybankController@repeated','as' => 'piggybanks.index.repeated']);
- Route::get('/piggybanks/create/piggybank', ['uses' => 'PiggybankController@createPiggybank','as' => 'piggybanks.create.piggybank']);
- Route::get('/piggybanks/create/repeated', ['uses' => 'PiggybankController@createRepeated','as' => 'piggybanks.create.repeated']);
- Route::get('/piggybanks/addMoney/{piggybank}', ['uses' => 'PiggybankController@addMoney','as' => 'piggybanks.amount.add']);
- Route::get('/piggybanks/removeMoney/{piggybank}', ['uses' => 'PiggybankController@removeMoney','as' => 'piggybanks.amount.remove']);
- Route::get('/piggybanks/show/{piggybank}', ['uses' => 'PiggybankController@show','as' => 'piggybanks.show']);
- Route::get('/piggybanks/edit/{piggybank}', ['uses' => 'PiggybankController@edit','as' => 'piggybanks.edit']);
- Route::get('/piggybanks/delete/{piggybank}', ['uses' => 'PiggybankController@delete','as' => 'piggybanks.delete']);
- Route::post('/piggybanks/updateAmount/{piggybank}',['uses' => 'PiggybankController@updateAmount','as' => 'piggybanks.updateAmount']);
+ Route::get('/piggybanks', ['uses' => 'PiggybankController@index', 'as' => 'piggybanks.index']);
+ Route::get('/piggybanks/add/{piggybank}', ['uses' => 'PiggybankController@add']);
+ Route::get('/piggybanks/remove/{piggybank}', ['uses' => 'PiggybankController@remove']);
+ Route::get('/piggybanks/edit/{piggybank}', ['uses' => 'PiggybankController@edit', 'as' => 'piggybanks.edit']);
+ Route::get('/piggybanks/create', ['uses' => 'PiggybankController@create', 'as' => 'piggybanks.create']);
+ Route::get('/piggybanks/delete/{piggybank}', ['uses' => 'PiggybankController@delete', 'as' => 'piggybanks.delete']);
+
+
+// Route::get('/repeated',['uses' => 'PiggybankController@repeated','as' => 'piggybanks.index.repeated']);
+// Route::get('/piggybanks/create/repeated', ['uses' => 'PiggybankController@createRepeated','as' => 'piggybanks.create.repeated']);
+// Route::get('/piggybanks/addMoney/{piggybank}', ['uses' => 'PiggybankController@addMoney','as' => 'piggybanks.amount.add']);
+// Route::get('/piggybanks/removeMoney/{piggybank}', ['uses' => 'PiggybankController@removeMoney','as' => 'piggybanks.amount.remove']);
+// Route::get('/piggybanks/show/{piggybank}', ['uses' => 'PiggybankController@show','as' => 'piggybanks.show']);
+// Route::get('/piggybanks/delete/{piggybank}', ['uses' => 'PiggybankController@delete','as' => 'piggybanks.delete']);
+// Route::post('/piggybanks/updateAmount/{piggybank}',['uses' => 'PiggybankController@updateAmount','as' => 'piggybanks.updateAmount']);
// preferences controller
Route::get('/preferences', ['uses' => 'PreferencesController@index', 'as' => 'preferences']);
//profile controller
Route::get('/profile', ['uses' => 'ProfileController@index', 'as' => 'profile']);
- Route::get('/profile/change-password',['uses' => 'ProfileController@changePassword', 'as' => 'change-password']);
+ Route::get('/profile/change-password', ['uses' => 'ProfileController@changePassword', 'as' => 'change-password']);
// recurring transactions controller
- Route::get('/recurring',['uses' => 'RecurringController@index', 'as' => 'recurring.index']);
- Route::get('/recurring/show/{recurring}',['uses' => 'RecurringController@show', 'as' => 'recurring.show']);
- Route::get('/recurring/rescan/{recurring}',['uses' => 'RecurringController@rescan', 'as' => 'recurring.rescan']);
- Route::get('/recurring/create',['uses' => 'RecurringController@create', 'as' => 'recurring.create']);
- Route::get('/recurring/edit/{recurring}',['uses' => 'RecurringController@edit','as' => 'recurring.edit']);
- Route::get('/recurring/delete/{recurring}',['uses' => 'RecurringController@delete','as' => 'recurring.delete']);
+ Route::get('/recurring', ['uses' => 'RecurringController@index', 'as' => 'recurring.index']);
+ Route::get('/recurring/show/{recurring}', ['uses' => 'RecurringController@show', 'as' => 'recurring.show']);
+ Route::get('/recurring/rescan/{recurring}', ['uses' => 'RecurringController@rescan', 'as' => 'recurring.rescan']);
+ Route::get('/recurring/create', ['uses' => 'RecurringController@create', 'as' => 'recurring.create']);
+ Route::get('/recurring/edit/{recurring}', ['uses' => 'RecurringController@edit', 'as' => 'recurring.edit']);
+ Route::get('/recurring/delete/{recurring}', ['uses' => 'RecurringController@delete', 'as' => 'recurring.delete']);
// report controller:
- Route::get('/reports',['uses' => 'ReportController@index','as' => 'reports.index']);
+ Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']);
+ Route::get('/reports/{year}', ['uses' => 'ReportController@year', 'as' => 'reports.year']);
// search controller:
- Route::get('/search',['uses' => 'SearchController@index','as' => 'search']);
+ Route::get('/search', ['uses' => 'SearchController@index', 'as' => 'search']);
// transaction controller:
- Route::get('/transactions/create/{what}', ['uses' => 'TransactionController@create', 'as' => 'transactions.create'])->where(['what' => 'withdrawal|deposit|transfer']);
- Route::get('/transaction/show/{tj}',['uses' => 'TransactionController@show','as' => 'transactions.show']);
- Route::get('/transaction/edit/{tj}',['uses' => 'TransactionController@edit','as' => 'transactions.edit']);
- Route::get('/transaction/delete/{tj}',['uses' => 'TransactionController@delete','as' => 'transactions.delete']);
- Route::get('/transactions/index',['uses' => 'TransactionController@index','as' => 'transactions.index']);
- Route::get('/transactions/expenses',['uses' => 'TransactionController@expenses','as' => 'transactions.expenses']);
- Route::get('/transactions/revenue',['uses' => 'TransactionController@revenue','as' => 'transactions.revenue']);
- Route::get('/transactions/transfers',['uses' => 'TransactionController@transfers','as' => 'transactions.transfers']);
+ Route::get('/transactions/create/{what}', ['uses' => 'TransactionController@create', 'as' => 'transactions.create'])->where(
+ ['what' => 'withdrawal|deposit|transfer']
+ );
+ Route::get('/transaction/show/{tj}', ['uses' => 'TransactionController@show', 'as' => 'transactions.show']);
+ Route::get('/transaction/edit/{tj}', ['uses' => 'TransactionController@edit', 'as' => 'transactions.edit']);
+ Route::get('/transaction/delete/{tj}', ['uses' => 'TransactionController@delete', 'as' => 'transactions.delete']);
+ Route::get('/transactions/index', ['uses' => 'TransactionController@index', 'as' => 'transactions.index']);
+ Route::get('/transactions/expenses', ['uses' => 'TransactionController@expenses', 'as' => 'transactions.expenses']);
+ Route::get('/transactions/revenue', ['uses' => 'TransactionController@revenue', 'as' => 'transactions.revenue']);
+ Route::get('/transactions/transfers', ['uses' => 'TransactionController@transfers', 'as' => 'transactions.transfers']);
- Route::get('/transactions/expenses',['uses' => 'TransactionController@expenses','as' => 'transactions.index.withdrawal']);
- Route::get('/transactions/revenue',['uses' => 'TransactionController@revenue','as' => 'transactions.index.deposit']);
- Route::get('/transactions/transfers',['uses' => 'TransactionController@transfers','as' => 'transactions.index.transfer']);
+ Route::get('/transactions/expenses', ['uses' => 'TransactionController@expenses', 'as' => 'transactions.index.withdrawal']);
+ Route::get('/transactions/revenue', ['uses' => 'TransactionController@revenue', 'as' => 'transactions.index.deposit']);
+ Route::get('/transactions/transfers', ['uses' => 'TransactionController@transfers', 'as' => 'transactions.index.transfer']);
// user controller
Route::get('/logout', ['uses' => 'UserController@logout', 'as' => 'logout']);
+ Route::post('budgets/amount/{budget}', ['uses' => 'BudgetController@amount']);
+
+
}
);
// protected + csrf routes (POST)
-Route::group(['before' => 'csrf|auth'], function () {
+Route::group(
+ ['before' => 'csrf|auth'], function () {
// account controller:
Route::post('/accounts/store', ['uses' => 'AccountController@store', 'as' => 'accounts.store']);
Route::post('/accounts/update/{account}', ['uses' => 'AccountController@update', 'as' => 'accounts.update']);
Route::post('/accounts/destroy/{account}', ['uses' => 'AccountController@destroy', 'as' => 'accounts.destroy']);
// budget controller:
- Route::post('/budgets/store',['uses' => 'BudgetController@store', 'as' => 'budgets.store']);
+ Route::post('/budgets/income', ['uses' => 'BudgetController@postUpdateIncome', 'as' => 'budgets.postIncome']);
Route::post('/budgets/update/{budget}', ['uses' => 'BudgetController@update', 'as' => 'budgets.update']);
+ Route::post('/budgets/store', ['uses' => 'BudgetController@store', 'as' => 'budgets.store']);
Route::post('/budgets/destroy/{budget}', ['uses' => 'BudgetController@destroy', 'as' => 'budgets.destroy']);
// category controller
- Route::post('/categories/store',['uses' => 'CategoryController@store', 'as' => 'categories.store']);
+ Route::post('/categories/store', ['uses' => 'CategoryController@store', 'as' => 'categories.store']);
Route::post('/categories/update/{category}', ['uses' => 'CategoryController@update', 'as' => 'categories.update']);
Route::post('/categories/destroy/{category}', ['uses' => 'CategoryController@destroy', 'as' => 'categories.destroy']);
// limit controller:
Route::post('/budgets/limits/store/{budget?}', ['uses' => 'LimitController@store', 'as' => 'budgets.limits.store']);
- Route::post('/budgets/limits/destroy/{limit}',['uses' => 'LimitController@destroy','as' => 'budgets.limits.destroy']);
- Route::post('/budgets/limits/update/{limit}',['uses' => 'LimitController@update','as' => 'budgets.limits.update']);
+ Route::post('/budgets/limits/destroy/{limit}', ['uses' => 'LimitController@destroy', 'as' => 'budgets.limits.destroy']);
+ Route::post('/budgets/limits/update/{limit}', ['uses' => 'LimitController@update', 'as' => 'budgets.limits.update']);
- Route::post('/migrate/upload',['uses' => 'MigrateController@upload', 'as' => 'migrate.upload']);
+ Route::post('/migrate/upload', ['uses' => 'MigrateController@upload', 'as' => 'migrate.upload']);
// piggy bank controller
- Route::post('/piggybanks/store/piggybank',['uses' => 'PiggybankController@storePiggybank','as' => 'piggybanks.store.piggybank']);
- Route::post('/piggybanks/store/repeated',['uses' => 'PiggybankController@storeRepeated','as' => 'piggybanks.store.repeated']);
- Route::post('/piggybanks/update/{piggybank}', ['uses' => 'PiggybankController@update','as' => 'piggybanks.update']);
- Route::post('/piggybanks/destroy/{piggybank}', ['uses' => 'PiggybankController@destroy','as' => 'piggybanks.destroy']);
- Route::post('/piggybanks/mod/{piggybank}', ['uses' => 'PiggybankController@modMoney','as' => 'piggybanks.modMoney']);
+ Route::post('/piggybanks/store', ['uses' => 'PiggybankController@store', 'as' => 'piggybanks.store']);
+ #Route::post('/piggybanks/store/repeated', ['uses' => 'PiggybankController@storeRepeated', 'as' => 'piggybanks.store.repeated']);
+ Route::post('/piggybanks/update/{piggybank}', ['uses' => 'PiggybankController@update', 'as' => 'piggybanks.update']);
+ Route::post('/piggybanks/destroy/{piggybank}', ['uses' => 'PiggybankController@destroy', 'as' => 'piggybanks.destroy']);
+ #Route::post('/piggybanks/mod/{piggybank}', ['uses' => 'PiggybankController@modMoney', 'as' => 'piggybanks.modMoney']);
+ Route::post('/piggybanks/add/{piggybank}', ['uses' => 'PiggybankController@postAdd', 'as' => 'piggybanks.add']);
+ Route::post('/piggybanks/remove/{piggybank}', ['uses' => 'PiggybankController@postRemove', 'as' => 'piggybanks.remove']);
// preferences controller
@@ -291,20 +315,23 @@ Route::group(['before' => 'csrf|auth'], function () {
Route::post('/profile/change-password', ['uses' => 'ProfileController@postChangePassword']);
// recurring controller
- Route::post('/recurring/store',['uses' => 'RecurringController@store', 'as' => 'recurring.store']);
- Route::post('/recurring/update/{recurring}',['uses' => 'RecurringController@update','as' => 'recurring.update']);
- Route::post('/recurring/destroy/{recurring}',['uses' => 'RecurringController@destroy','as' => 'recurring.destroy']);
+ Route::post('/recurring/store', ['uses' => 'RecurringController@store', 'as' => 'recurring.store']);
+ Route::post('/recurring/update/{recurring}', ['uses' => 'RecurringController@update', 'as' => 'recurring.update']);
+ Route::post('/recurring/destroy/{recurring}', ['uses' => 'RecurringController@destroy', 'as' => 'recurring.destroy']);
// transaction controller:
- Route::post('/transactions/store/{what}', ['uses' => 'TransactionController@store', 'as' => 'transactions.store'])->where(['what' => 'withdrawal|deposit|transfer']);
- Route::post('/transaction/update/{tj}',['uses' => 'TransactionController@update','as' => 'transactions.update']);
- Route::post('/transaction/destroy/{tj}',['uses' => 'TransactionController@destroy','as' => 'transactions.destroy']);
+ Route::post('/transactions/store/{what}', ['uses' => 'TransactionController@store', 'as' => 'transactions.store'])->where(
+ ['what' => 'withdrawal|deposit|transfer']
+ );
+ Route::post('/transaction/update/{tj}', ['uses' => 'TransactionController@update', 'as' => 'transactions.update']);
+ Route::post('/transaction/destroy/{tj}', ['uses' => 'TransactionController@destroy', 'as' => 'transactions.destroy']);
}
);
// guest routes:
-Route::group(['before' => 'guest'], function () {
+Route::group(
+ ['before' => 'guest'], function () {
// user controller
Route::get('/login', ['uses' => 'UserController@login', 'as' => 'login']);
Route::get('/register', ['uses' => 'UserController@register', 'as' => 'register']);
@@ -317,7 +344,8 @@ Route::group(['before' => 'guest'], function () {
);
// guest + csrf routes:
-Route::group(['before' => 'csrf|guest'], function () {
+Route::group(
+ ['before' => 'csrf|guest'], function () {
// user controller
Route::post('/login', ['uses' => 'UserController@postLogin']);
diff --git a/app/start/global.php b/app/start/global.php
index c5098db09d..10109df498 100644
--- a/app/start/global.php
+++ b/app/start/global.php
@@ -72,30 +72,51 @@ App::down(
);
// forms:
-\Form::macro('ffText', function ($name, $value = null, array $options = []) {
- return \Firefly\Form\Form::ffText($name, $value, $options);
-});
-\Form::macro('ffSelect', function ($name, array $list = [], $selected = null, array $options = []) {
- return \Firefly\Form\Form::ffSelect($name, $list, $selected, $options);
-});
-\Form::macro('ffInteger', function ($name, $value = null, array $options = []) {
- return \Firefly\Form\Form::ffInteger($name, $value, $options);
-});
-\Form::macro('ffAmount', function ($name, $value = null, array $options = []) {
- return \Firefly\Form\Form::ffAmount($name, $value, $options);
-});
-\Form::macro('ffDate', function ($name, $value = null, array $options = []) {
- return \Firefly\Form\Form::ffDate($name, $value, $options);
-});
-\Form::macro('ffTags', function ($name, $value = null, array $options = []) {
- return \Firefly\Form\Form::ffTags($name, $value, $options);
-});
-\Form::macro('ffCheckbox',function ($name, $value = 1, $checked = null, $options = []) {
- return \Firefly\Form\Form::ffCheckbox($name, $value, $checked, $options);
-});
-\Form::macro('ffOptionsList',function ($type, $name) {
- return \Firefly\Form\Form::ffOptionsList($type, $name);
-});
+\Form::macro(
+ 'ffText', function ($name, $value = null, array $options = []) {
+ return \Firefly\Form\Form::ffText($name, $value, $options);
+ }
+);
+\Form::macro(
+ 'ffSelect', function ($name, array $list = [], $selected = null, array $options = []) {
+ return \Firefly\Form\Form::ffSelect($name, $list, $selected, $options);
+ }
+);
+\Form::macro(
+ 'ffInteger', function ($name, $value = null, array $options = []) {
+ return \Firefly\Form\Form::ffInteger($name, $value, $options);
+ }
+);
+\Form::macro(
+ 'ffAmount', function ($name, $value = null, array $options = []) {
+ return \Firefly\Form\Form::ffAmount($name, $value, $options);
+ }
+);
+\Form::macro(
+ 'ffBalance', function ($name, $value = null, array $options = []) {
+ return \Firefly\Form\Form::ffBalance($name, $value, $options);
+ }
+);
+\Form::macro(
+ 'ffDate', function ($name, $value = null, array $options = []) {
+ return \Firefly\Form\Form::ffDate($name, $value, $options);
+ }
+);
+\Form::macro(
+ 'ffTags', function ($name, $value = null, array $options = []) {
+ return \Firefly\Form\Form::ffTags($name, $value, $options);
+ }
+);
+\Form::macro(
+ 'ffCheckbox', function ($name, $value = 1, $checked = null, $options = []) {
+ return \Firefly\Form\Form::ffCheckbox($name, $value, $checked, $options);
+ }
+);
+\Form::macro(
+ 'ffOptionsList', function ($type, $name) {
+ return \Firefly\Form\Form::ffOptionsList($type, $name);
+ }
+);
/*
diff --git a/app/views/accounts/asset.blade.php b/app/views/accounts/asset.blade.php
deleted file mode 100644
index 5cc72b31c9..0000000000
--- a/app/views/accounts/asset.blade.php
+++ /dev/null
@@ -1,18 +0,0 @@
-@extends('layouts.default')
-@section('content')
-
-
-@stop
\ No newline at end of file
diff --git a/app/views/accounts/create.blade.php b/app/views/accounts/create.blade.php
index 6e3c7d2128..edf174bce6 100644
--- a/app/views/accounts/create.blade.php
+++ b/app/views/accounts/create.blade.php
@@ -4,98 +4,50 @@
{{Form::hidden('what',$what)}}