mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 18:54:58 +00:00 
			
		
		
		
	Half-way through with some cleaning up.
This commit is contained in:
		| @@ -39,9 +39,7 @@ return [ | ||||
|         'Illuminate\Workbench\WorkbenchServiceProvider', | ||||
|         'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider', | ||||
|         'Barryvdh\Debugbar\ServiceProvider', | ||||
|         'Firefly\Storage\StorageServiceProvider', | ||||
|         'Firefly\Helper\HelperServiceProvider', | ||||
|         'Firefly\Validation\ValidationServiceProvider', | ||||
|         'FireflyIII\FF3ServiceProvider', | ||||
|         'DaveJamesMiller\Breadcrumbs\ServiceProvider', | ||||
|         'Grumpydictator\Gchart\GchartServiceProvider', | ||||
|     ], | ||||
|   | ||||
| @@ -50,70 +50,6 @@ class AccountController extends BaseController | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @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 | ||||
|      */ | ||||
|   | ||||
| @@ -1,603 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Firefly\Exception\FireflyException; | ||||
| use Firefly\Helper\Controllers\ChartInterface; | ||||
| use Firefly\Storage\Account\AccountRepositoryInterface; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Class ChartController | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CamelCasePropertyName) | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class ChartController extends BaseController | ||||
| { | ||||
|  | ||||
|     protected $_chart; | ||||
|     protected $_accounts; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param ChartInterface $chart | ||||
|      * @param AccountRepositoryInterface $accounts | ||||
|      */ | ||||
|     public function __construct(ChartInterface $chart, AccountRepositoryInterface $accounts) | ||||
|     { | ||||
|         $this->_chart    = $chart; | ||||
|         $this->_accounts = $accounts; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method takes a budget, all limits and all their repetitions and displays three numbers per repetition: | ||||
|      * the amount of money in the repetition (represented as "an envelope"), the amount spent and the spent percentage. | ||||
|      * | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function budgetDefault(\Budget $budget) | ||||
|     { | ||||
|         $expense  = []; | ||||
|         $left     = []; | ||||
|         $envelope = []; | ||||
|         // get all limit repetitions for this budget. | ||||
|         /** @var \Limit $limit */ | ||||
|         foreach ($budget->limits as $limit) { | ||||
|             /** @var \LimitRepetition $rep */ | ||||
|             foreach ($limit->limitrepetitions as $rep) { | ||||
|                 // get the amount of money spent in this period on this budget. | ||||
|                 $spentInRep = $rep->amount - $rep->leftInRepetition(); | ||||
|                 $pct        = round((floatval($spentInRep) / floatval($limit->amount)) * 100, 2); | ||||
|                 $name       = $rep->periodShow(); | ||||
|                 $envelope[] = [$name, floatval($limit->amount)]; | ||||
|                 $expense[]  = [$name, floatval($spentInRep)]; | ||||
|                 $left[]     = [$name, $pct]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $return = [ | ||||
|             'chart_title' => 'Overview for budget ' . $budget->name, | ||||
|             'subtitle' => 'All envelopes', | ||||
|             'series' => [ | ||||
|                 [ | ||||
|                     'type' => 'line', | ||||
|                     'yAxis' => 1, | ||||
|                     'name' => 'Amount in envelope', | ||||
|                     'data' => $envelope | ||||
|                 ], | ||||
|                 [ | ||||
|                     'type' => 'column', | ||||
|                     'name' => 'Expenses in envelope', | ||||
|                     'data' => $expense | ||||
|                 ], | ||||
|                 [ | ||||
|                     'type' => 'line', | ||||
|                     'yAxis' => 1, | ||||
|                     'name' => 'Spent percentage for envelope', | ||||
|                     'data' => $left | ||||
|                 ] | ||||
|  | ||||
|  | ||||
|             ] | ||||
|         ]; | ||||
|  | ||||
|         return Response::json($return); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method takes a single limit repetition (so a single "envelope") and displays the amount of money spent | ||||
|      * per day and subsequently how much money is left. | ||||
|      * | ||||
|      * @param LimitRepetition $rep | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function budgetLimit(\LimitRepetition $rep) | ||||
|     { | ||||
|         $budget             = $rep->limit->budget; | ||||
|         $current            = clone $rep->startdate; | ||||
|         $expense            = []; | ||||
|         $leftInLimit        = []; | ||||
|         $currentLeftInLimit = floatval($rep->limit->amount); | ||||
|         while ($current <= $rep->enddate) { | ||||
|             $spent              = $this->_chart->spentOnDay($budget, $current); | ||||
|             $spent              = floatval($spent) == 0 ? null : floatval($spent); | ||||
|             $entry              = [$current->timestamp * 1000, $spent]; | ||||
|             $expense[]          = $entry; | ||||
|             $currentLeftInLimit = $currentLeftInLimit - $spent; | ||||
|             $leftInLimit[]      = [$current->timestamp * 1000, $currentLeftInLimit]; | ||||
|             $current->addDay(); | ||||
|         } | ||||
|  | ||||
|         $return = [ | ||||
|             'chart_title' => 'Overview for budget ' . $budget->name, | ||||
|             'subtitle' => | ||||
|                 'Between ' . $rep->startdate->format('M jS, Y') . ' and ' . $rep->enddate->format('M jS, Y'), | ||||
|             'series' => [ | ||||
|                 [ | ||||
|                     'type' => 'column', | ||||
|                     'name' => 'Expenses per day', | ||||
|                     'yAxis' => 1, | ||||
|                     'data' => $expense | ||||
|                 ], | ||||
|                 [ | ||||
|                     'type' => 'line', | ||||
|                     'name' => 'Left in envelope', | ||||
|                     'data' => $leftInLimit | ||||
|                 ] | ||||
|  | ||||
|             ] | ||||
|         ]; | ||||
|  | ||||
|         return Response::json($return); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method takes a budget and gets all transactions in it which haven't got an envelope (limit). | ||||
|      * | ||||
|      * Usually this means that very old and unorganized or very NEW transactions get displayed; there was never an | ||||
|      * envelope or it hasn't been created (yet). | ||||
|      * | ||||
|      * | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function budgetNoLimits(\Budget $budget) | ||||
|     { | ||||
|         /* | ||||
|          * Firefly can go about this two ways. Either it finds all transactions which definitely are IN an envelope | ||||
|          * and exclude them or it searches for transactions outside of the range of any of the envelopes there are. | ||||
|          * | ||||
|          * Since either is kinda shitty Firefly uses the first one because it's easier to build. | ||||
|          */ | ||||
|         $inRepetitions = $this->_chart->allJournalsInBudgetEnvelope($budget); | ||||
|  | ||||
|         /* | ||||
|          * With this set of id's, Firefly can search for all journals NOT in that set. | ||||
|          * BUT they have to be in the budget (duh). | ||||
|          */ | ||||
|         $set = $this->_chart->journalsNotInSet($budget, $inRepetitions); | ||||
|         /* | ||||
|          * Next step: get all transactions for those journals. | ||||
|          */ | ||||
|         $transactions = $this->_chart->transactionsByJournals($set); | ||||
|  | ||||
|  | ||||
|         /* | ||||
|          *  this set builds the chart: | ||||
|          */ | ||||
|         $expense = []; | ||||
|  | ||||
|         foreach ($transactions as $t) { | ||||
|             $date      = new Carbon($t->date); | ||||
|             $expense[] = [$date->timestamp * 1000, floatval($t->aggregate)]; | ||||
|         } | ||||
|         $return = [ | ||||
|             'chart_title' => 'Overview for ' . $budget->name, | ||||
|             'subtitle' => 'Not organized by an envelope', | ||||
|             'series' => [ | ||||
|                 [ | ||||
|                     'type' => 'column', | ||||
|                     'name' => 'Expenses per day', | ||||
|                     'data' => $expense | ||||
|                 ] | ||||
|  | ||||
|             ] | ||||
|         ]; | ||||
|         return Response::json($return); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method gets all transactions within a budget within the period set by the current session | ||||
|      * start and end date. It also includes any envelopes which might exist within this period. | ||||
|      * | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function budgetSession(\Budget $budget) | ||||
|     { | ||||
|         $series = []; | ||||
|         $end    = clone Session::get('end'); | ||||
|         $start  = clone Session::get('start'); | ||||
|  | ||||
|  | ||||
|         /* | ||||
|          * Expenses per day in the session's period. That's easy. | ||||
|          */ | ||||
|         $expense = []; | ||||
|         $current = clone Session::get('start'); | ||||
|         while ($current <= $end) { | ||||
|             $spent     = $this->_chart->spentOnDay($budget, $current); | ||||
|             $spent     = floatval($spent) == 0 ? null : floatval($spent); | ||||
|             $expense[] = [$current->timestamp * 1000, $spent]; | ||||
|             $current->addDay(); | ||||
|         } | ||||
|  | ||||
|         $series[] = [ | ||||
|             'type' => 'column', | ||||
|             'name' => 'Expenses per day', | ||||
|             'data' => $expense | ||||
|         ]; | ||||
|         unset($expense, $spent, $current); | ||||
|  | ||||
|         /* | ||||
|          * Find all limit repetitions (for this budget) between start and end. This is | ||||
|          * quite a complex query. | ||||
|          */ | ||||
|         $reps = $this->_chart->limitsInRange($budget, $start, $end); | ||||
|  | ||||
|         /* | ||||
|          * For each limitrepetition Firefly creates a serie that contains the amount left in | ||||
|          * the limitrepetition for its entire date-range. Entries are only actually included when they | ||||
|          * fall into the charts date range. | ||||
|          * | ||||
|          * So example: the user has a session date from Jan 15 to Jan 30. The limitrepetition | ||||
|          * starts at 1 Jan until 1 Feb. | ||||
|          * | ||||
|          * Firefly loops from 1 Jan to 1 Feb but only includes Jan 15 / Jan 30. | ||||
|          * But it does keep count of the amount outside of these dates because otherwise the line might be wrong. | ||||
|          */ | ||||
|         /** @var \LimitRepetition $repetition */ | ||||
|         foreach ($reps as $repetition) { | ||||
|             $limitAmount = $repetition->limit->amount; | ||||
|  | ||||
|             // create a serie for the repetition. | ||||
|             $currentSerie = [ | ||||
|                 'type' => 'spline', | ||||
|                 'id' => 'rep-' . $repetition->id, | ||||
|                 'yAxis' => 1, | ||||
|                 'name' => 'Envelope #' . $repetition->id . ' in ' . $repetition->periodShow(), | ||||
|                 'data' => [] | ||||
|             ]; | ||||
|             $current      = clone $repetition->startdate; | ||||
|             while ($current <= $repetition->enddate) { | ||||
|                 if ($current >= $start && $current <= $end) { | ||||
|                     // spent on limit: | ||||
|                     $spentSoFar  = $this->_chart->spentOnLimitRepetitionBetweenDates( | ||||
|                         $repetition, $repetition->startdate, $current | ||||
|                     ); | ||||
|                     $leftInLimit = floatval($limitAmount) - floatval($spentSoFar); | ||||
|  | ||||
|                     $currentSerie['data'][] = [$current->timestamp * 1000, $leftInLimit]; | ||||
|                 } | ||||
|                 $current->addDay(); | ||||
|             } | ||||
|  | ||||
|             // do something here. | ||||
|             $series[] = $currentSerie; | ||||
|         } | ||||
|  | ||||
|         $return = [ | ||||
|             'chart_title' => 'Overview for budget ' . $budget->name, | ||||
|             'subtitle' => | ||||
|                 'Between ' . Session::get('start')->format('M jS, Y') . ' and ' . Session::get('end')->format( | ||||
|                     'M jS, Y' | ||||
|                 ), | ||||
|             'series' => $series | ||||
|         ]; | ||||
|  | ||||
|         return Response::json($return); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function categoryShowChart(Category $category) | ||||
|     { | ||||
|         $start = Session::get('start'); | ||||
|         $end   = Session::get('end'); | ||||
|         $range = Session::get('range'); | ||||
|  | ||||
|         $serie = $this->_chart->categoryShowChart($category, $range, $start, $end); | ||||
|         $data  = [ | ||||
|             'chart_title' => $category->name, | ||||
|             'subtitle' => '<a href="' . route('categories.show', [$category->id]) . '">View more</a>', | ||||
|             'series' => $serie | ||||
|         ]; | ||||
|  | ||||
|         return Response::json($data); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function homeAccount(Account $account = null) | ||||
|     { | ||||
|         // get preferences and accounts (if necessary): | ||||
|         $start = Session::get('start'); | ||||
|         $end   = Session::get('end'); | ||||
|  | ||||
|         if (is_null($account)) { | ||||
|             // get, depending on preferences: | ||||
|             /** @var  \Firefly\Helper\Preferences\PreferencesHelperInterface $prefs */ | ||||
|             $prefs = \App::make('Firefly\Helper\Preferences\PreferencesHelperInterface'); | ||||
|             $pref  = $prefs->get('frontpageAccounts', []); | ||||
|  | ||||
|             /** @var \Firefly\Storage\Account\AccountRepositoryInterface $acct */ | ||||
|             $acct     = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|             $accounts = $acct->getByIds($pref->data); | ||||
|         } else { | ||||
|             $accounts = [$account]; | ||||
|         } | ||||
|         // loop and get array data. | ||||
|  | ||||
|         $url  = count($accounts) == 1 && is_array($accounts) | ||||
|             ? '<a href="' . route('accounts.show', [$account->id]) . '">View more</a>' | ||||
|             : | ||||
|             '<a href="' . route('accounts.index') . '">View more</a>'; | ||||
|         $data = [ | ||||
|             'chart_title' => count($accounts) == 1 ? $accounts[0]->name : 'All accounts', | ||||
|             'subtitle' => $url, | ||||
|             'series' => [] | ||||
|         ]; | ||||
|  | ||||
|         foreach ($accounts as $account) { | ||||
|             $data['series'][] = $this->_chart->account($account, $start, $end); | ||||
|         } | ||||
|  | ||||
|         return Response::json($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $name | ||||
|      * @param $day | ||||
|      * @param $month | ||||
|      * @param $year | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function homeAccountInfo($name, $day, $month, $year) | ||||
|     { | ||||
|         $account = $this->_accounts->findByName($name); | ||||
|  | ||||
|         $date   = Carbon::createFromDate($year, $month, $day); | ||||
|         $result = $this->_chart->accountDailySummary($account, $date); | ||||
|  | ||||
|         return View::make('charts.info')->with('rows', $result['rows'])->with('sum', $result['sum'])->with( | ||||
|             'account', $account | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function homeBudgets() | ||||
|     { | ||||
|         $start = Session::get('start'); | ||||
|         $end   = Session::get('end'); | ||||
|         $data  = [ | ||||
|             'labels' => [], | ||||
|             'series' => [ | ||||
|                 [ | ||||
|                     'name' => 'Limit', | ||||
|                     'data' => [] | ||||
|                 ], | ||||
|                 [ | ||||
|                     'name' => 'Spent', | ||||
|                     'data' => [] | ||||
|                 ], | ||||
|             ] | ||||
|         ]; | ||||
|  | ||||
|         // Get all budgets. | ||||
|         $budgets   = \Auth::user()->budgets()->orderBy('name', 'ASC')->get(); | ||||
|         $budgetIds = []; | ||||
|         /** @var \Budget $budget */ | ||||
|         foreach ($budgets as $budget) { | ||||
|             $budgetIds[] = $budget->id; | ||||
|  | ||||
|             // Does the budget have a limit starting on $start? | ||||
|             $rep = \LimitRepetition:: | ||||
|             leftJoin('limits', 'limit_repetitions.limit_id', '=', 'limits.id')->leftJoin( | ||||
|                 'components', 'limits.component_id', '=', 'components.id' | ||||
|             )->where('limit_repetitions.startdate', $start->format('Y-m-d'))->where( | ||||
|                 'components.id', $budget->id | ||||
|             )->first(['limit_repetitions.*']); | ||||
|  | ||||
|             if (is_null($rep)) { | ||||
|                 $limit     = 0.0; | ||||
|                 $id        = null; | ||||
|                 $parameter = 'useSession=true'; | ||||
|             } else { | ||||
|                 $limit     = floatval($rep->amount); | ||||
|                 $id        = $rep->id; | ||||
|                 $parameter = ''; | ||||
|             } | ||||
|  | ||||
|             // Date range to check for expenses made? | ||||
|             if (is_null($rep)) { | ||||
|                 // use the session start and end for our search query | ||||
|                 $expenseStart = Session::get('start'); | ||||
|                 $expenseEnd   = Session::get('end'); | ||||
|  | ||||
|             } else { | ||||
|                 // use the limit's start and end for our search query | ||||
|                 $expenseStart = $rep->startdate; | ||||
|                 $expenseEnd   = $rep->enddate; | ||||
|             } | ||||
|             // How much have we spent on this budget? | ||||
|             $expenses = floatval($budget->transactionjournals()->before($expenseEnd)->after($expenseStart)->lessThan(0)->sum('amount')) * -1; | ||||
|  | ||||
|             // Append to chart: | ||||
|             if ($limit > 0 || $expenses > 0) { | ||||
|                 $data['labels'][]            = $budget->name; | ||||
|                 $data['series'][0]['data'][] = [ | ||||
|                     'y' => $limit, | ||||
|                     'url' => route('budgets.show', [$budget->id, $id]) . '?' . $parameter | ||||
|                 ]; | ||||
|                 $data['series'][1]['data'][] = [ | ||||
|                     'y' => $expenses, | ||||
|                     'url' => route('budgets.show', [$budget->id, $id]) . '?' . $parameter | ||||
|                 ]; | ||||
|             } | ||||
|         } | ||||
|         // 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)->lessThan(0)->transactionTypes(['Withdrawal'])->sum('amount'); | ||||
|  | ||||
|         // This can be debugged by using get(['transaction_journals.*','transactions.amount']); | ||||
|         $data['labels'][]            = 'No budget'; | ||||
|         $data['series'][0]['data'][] = [ | ||||
|             'y' => 0, | ||||
|             'url' => route('budgets.nobudget', 'session') | ||||
|         ]; | ||||
|         $data['series'][1]['data'][] = [ | ||||
|             'y' => floatval($set) * -1, | ||||
|             'url' => route('budgets.nobudget', 'session') | ||||
|         ]; | ||||
|  | ||||
|         return Response::json($data); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function homeCategories() | ||||
|     { | ||||
|         $start = Session::get('start'); | ||||
|         $end   = Session::get('end'); | ||||
|  | ||||
|         return Response::json($this->_chart->categories($start, $end)); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * This method checks all recurring transactions, calculates the current "moment" and returns | ||||
|      * a list of yet to be paid (and paid) recurring transactions. This list can be used to show a beautiful chart | ||||
|      * to the end user who will love it and cherish it. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function homeRecurring() | ||||
|     { | ||||
|         /** @var \Firefly\Helper\Toolkit\ToolkitInterface $toolkit */ | ||||
|         $toolkit = App::make('Firefly\Helper\Toolkit\ToolkitInterface'); | ||||
|  | ||||
|         /* | ||||
|          * Set of paid transaction journals. | ||||
|          * Set of unpaid recurring transactions. | ||||
|          */ | ||||
|         $paid   = []; | ||||
|         $unpaid = []; | ||||
|  | ||||
|         /* | ||||
|          * Loop the recurring transactions. | ||||
|          */ | ||||
|  | ||||
|         /** @var \RecurringTransaction $recurring */ | ||||
|         foreach (\Auth::user()->recurringtransactions()->get() as $recurring) { | ||||
|             /* | ||||
|              * Start another loop starting at the $date. | ||||
|              */ | ||||
|             $start = clone $recurring->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; | ||||
|                 $toolkit->endOfPeriod($currentEnd, $recurring->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 */ | ||||
|                     $transaction = \Auth::user()->transactionjournals()->where('recurring_transaction_id', $recurring->id)->after($current)->before($currentEnd)->first(); | ||||
|  | ||||
|                     if(is_null($transaction)) { | ||||
|                         $unpaid[] = $recurring; | ||||
|                     } else { | ||||
|                         $paid[] = $transaction; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 /* | ||||
|                  * Add some time for the next loop! | ||||
|                  */ | ||||
|                 $toolkit->addPeriod($current, $recurring->repeat_freq, intval($recurring->skip)); | ||||
|  | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         /* | ||||
|          * Get some colors going. | ||||
|          */ | ||||
|         $unPaidColours = $toolkit->colorRange('AA4643', 'FFFFFF', count($unpaid) == 0 ? 1 : count($unpaid)); | ||||
|         $paidColours   = $toolkit->colorRange('4572A7', 'FFFFFF', count($paid) == 0 ? 1 : count($paid)); | ||||
|  | ||||
|         /* | ||||
|          * The chart serie: | ||||
|          */ | ||||
|         $serie         = [ | ||||
|             'type' => 'pie', | ||||
|             'name' => 'Amount', | ||||
|             'data' => [] | ||||
|         ]; | ||||
|  | ||||
|         /* | ||||
|          * Loop paid and unpaid to make two haves for a pie chart. | ||||
|          */ | ||||
|         /** @var TransactionJournal $entry */ | ||||
|         foreach ($paid as $index => $entry) { | ||||
|             $transactions    = $entry->transactions()->get(); | ||||
|             $amount          = max(floatval($transactions[0]->amount), floatval($transactions[1]->amount)); | ||||
|             $serie['data'][] = [ | ||||
|                 'name' => 'Already paid "'.$entry->description.'"', | ||||
|                 'y' => $amount, | ||||
|                 'url' => route('transactions.show',$entry->id), | ||||
|                 'objType' => 'paid', | ||||
|                 'color' => $paidColours[$index] | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /** @var RecurringTransaction $entry */ | ||||
|         foreach ($unpaid as $index => $entry) { | ||||
|             $amount          = (floatval($entry->amount_max) + floatval($entry->amount_min)) / 2; | ||||
|             $serie['data'][] = [ | ||||
|                 'name' => 'Still due: '.$entry->name, | ||||
|                 'y' => $amount, | ||||
|                 'url' => route('recurring.show',$entry->id), | ||||
|                 'objType' => 'unpaid', | ||||
|                 'color' => $unPaidColours[$index] | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         return Response::json([$serie]); | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -1,7 +1,5 @@ | ||||
| <?php | ||||
| use Firefly\Helper\Preferences\PreferencesHelperInterface as PHI; | ||||
| use Firefly\Storage\Account\AccountRepositoryInterface as ARI; | ||||
| use Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface as TJRI; | ||||
| use FireflyIII\Shared\Preferences\PreferencesInterface as Prefs; | ||||
|  | ||||
| /** | ||||
|  * Class HomeController | ||||
| @@ -10,20 +8,15 @@ use Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface as | ||||
|  */ | ||||
| class HomeController extends BaseController | ||||
| { | ||||
|     protected $_accounts; | ||||
|     protected $_preferences; | ||||
|     protected $_journal; | ||||
|  | ||||
|     /** | ||||
|      * @param ARI  $accounts | ||||
|      * @param PHI  $preferences | ||||
|      * @param TJRI $journal | ||||
|      */ | ||||
|     public function __construct(ARI $accounts, PHI $preferences, TJRI $journal) | ||||
|     public function __construct(Prefs $preferences) | ||||
|     { | ||||
|         $this->_accounts    = $accounts; | ||||
|         $this->_preferences = $preferences; | ||||
|         $this->_journal     = $journal; | ||||
|     } | ||||
|  | ||||
|     public function jobDev() | ||||
| @@ -85,12 +78,19 @@ class HomeController extends BaseController | ||||
|      */ | ||||
|     public function index() | ||||
|     { | ||||
|         Event::fire('limits.check'); | ||||
|         Event::fire('piggybanks.check'); | ||||
|         Event::fire('recurring.check'); | ||||
| //        Event::fire('limits.check'); | ||||
| //        Event::fire('piggybanks.check'); | ||||
| //        Event::fire('recurring.check'); | ||||
|  | ||||
|         // count, maybe Firefly needs some introducing text to show: | ||||
|         $count = $this->_accounts->count(); | ||||
|         /** @var \FireflyIII\Database\Account $acct */ | ||||
|         $acct = App::make('FireflyIII\Database\Account'); | ||||
|  | ||||
|         /** @var \FireflyIII\Database\TransactionJournal $jrnls */ | ||||
|         $jrnls = App::make('FireflyIII\Database\TransactionJournal'); | ||||
|  | ||||
|         $count = $acct->countAssetAccounts(); | ||||
|  | ||||
|         $start = Session::get('start'); | ||||
|         $end   = Session::get('end'); | ||||
|  | ||||
| @@ -98,14 +98,14 @@ class HomeController extends BaseController | ||||
|         // get the preference for the home accounts to show: | ||||
|         $frontpage = $this->_preferences->get('frontpageAccounts', []); | ||||
|         if ($frontpage->data == []) { | ||||
|             $accounts = $this->_accounts->getActiveDefault(); | ||||
|             $accounts = $acct->getAssetAccounts(); | ||||
|         } else { | ||||
|             $accounts = $this->_accounts->getByIds($frontpage->data); | ||||
|             $accounts = $acct->getByIds($frontpage->data); | ||||
|         } | ||||
|  | ||||
|         $transactions = []; | ||||
|         foreach ($accounts as $account) { | ||||
|             $set = $this->_journal->getByAccountInDateRange($account, 10, $start, $end); | ||||
|             $set = $jrnls->getInDateRangeAccount($account, 10, $start, $end); | ||||
|             if (count($set) > 0) { | ||||
|                 $transactions[] = [$set, $account]; | ||||
|             } | ||||
| @@ -115,59 +115,4 @@ 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 . ')<br />'; | ||||
|                             } | ||||
|                         } | ||||
|                         break; | ||||
|                 } | ||||
|  | ||||
|  | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -1,186 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| use Firefly\Helper\Controllers\JsonInterface as JI; | ||||
| use Illuminate\Support\Collection; | ||||
| use LaravelBook\Ardent\Builder; | ||||
|  | ||||
| /** | ||||
|  * Class JsonController | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CamelCasePropertyName) | ||||
|  */ | ||||
| class JsonController extends BaseController | ||||
| { | ||||
|     /** @var \Firefly\Helper\Controllers\JsonInterface $helper */ | ||||
|     protected $helper; | ||||
|  | ||||
|     public function __construct(JI $helper) | ||||
|     { | ||||
|         $this->helper = $helper; | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a list of categories. | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function categories() | ||||
|     { | ||||
|         /** @var \Firefly\Storage\Category\EloquentCategoryRepository $categories */ | ||||
|         $categories = App::make('Firefly\Storage\Category\CategoryRepositoryInterface'); | ||||
|         $list       = $categories->get(); | ||||
|         $return     = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->name; | ||||
|         } | ||||
|  | ||||
|         return Response::json($return); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a JSON list of all beneficiaries. | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function expenseAccounts() | ||||
|     { | ||||
|         /** @var \Firefly\Storage\Account\EloquentAccountRepository $accounts */ | ||||
|         $accounts = App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $list     = $accounts->getOfTypes(['Expense account', 'Beneficiary account']); | ||||
|         $return   = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->name; | ||||
|         } | ||||
|  | ||||
|         return Response::json($return); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a list of transactions, expenses only, using the given parameters. | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function expenses() | ||||
|     { | ||||
|  | ||||
|         /* | ||||
|          * Gets most parameters from the Input::all() array: | ||||
|          */ | ||||
|         $parameters = $this->helper->dataTableParameters(); | ||||
|  | ||||
|         /* | ||||
|          * Add some more parameters to fine tune the query: | ||||
|          */ | ||||
|         $parameters['transactionTypes'] = ['Withdrawal']; | ||||
|         $parameters['amount']           = 'negative'; | ||||
|  | ||||
|         /* | ||||
|          * Get the query: | ||||
|          */ | ||||
|         $query = $this->helper->journalQuery($parameters); | ||||
|  | ||||
|         /* | ||||
|          * Build result set: | ||||
|          */ | ||||
|         $resultSet = $this->helper->journalDataset($parameters, $query); | ||||
|  | ||||
|  | ||||
|         /* | ||||
|          * Build return data: | ||||
|          */ | ||||
|         return Response::json($resultSet); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function recurringjournals(RecurringTransaction $recurringTransaction) | ||||
|     { | ||||
|         $parameters                     = $this->helper->dataTableParameters(); | ||||
|         $parameters['transactionTypes'] = ['Withdrawal']; | ||||
|         $parameters['amount']           = 'negative'; | ||||
|  | ||||
|         $query = $this->helper->journalQuery($parameters); | ||||
|  | ||||
|         $query->where('recurring_transaction_id', $recurringTransaction->id); | ||||
|         $resultSet = $this->helper->journalDataset($parameters, $query); | ||||
|  | ||||
|  | ||||
|         /* | ||||
|          * Build return data: | ||||
|          */ | ||||
|         return Response::json($resultSet); | ||||
|     } | ||||
|  | ||||
|     public function recurring() | ||||
|     { | ||||
|         $parameters = $this->helper->dataTableParameters(); | ||||
|         $query      = $this->helper->recurringTransactionsQuery($parameters); | ||||
|         $resultSet  = $this->helper->recurringTransactionsDataset($parameters, $query); | ||||
|         return Response::json($resultSet); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return \Illuminate\Http\JsonResponse|string | ||||
|      */ | ||||
|     public function revenue() | ||||
|     { | ||||
|         $parameters                     = $this->helper->dataTableParameters(); | ||||
|         $parameters['transactionTypes'] = ['Deposit']; | ||||
|         $parameters['amount']           = 'positive'; | ||||
|  | ||||
|         $query     = $this->helper->journalQuery($parameters); | ||||
|         $resultSet = $this->helper->journalDataset($parameters, $query); | ||||
|  | ||||
|  | ||||
|         /* | ||||
|          * Build return data: | ||||
|          */ | ||||
|         return Response::json($resultSet); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a JSON list of all revenue accounts. | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function revenueAccounts() | ||||
|     { | ||||
|         /** @var \Firefly\Storage\Account\EloquentAccountRepository $accounts */ | ||||
|         $accounts = App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $list     = $accounts->getOfTypes(['Revenue account']); | ||||
|         $return   = []; | ||||
|         foreach ($list as $entry) { | ||||
|             $return[] = $entry->name; | ||||
|         } | ||||
|  | ||||
|         return Response::json($return); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a list of all transfers. | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function transfers() | ||||
|     { | ||||
|         $parameters                     = $this->helper->dataTableParameters(); | ||||
|         $parameters['transactionTypes'] = ['Transfer']; | ||||
|         $parameters['amount']           = 'positive'; | ||||
|  | ||||
|         $query     = $this->helper->journalQuery($parameters); | ||||
|         $resultSet = $this->helper->journalDataset($parameters, $query); | ||||
|  | ||||
|  | ||||
|         /* | ||||
|          * Build return data: | ||||
|          */ | ||||
|         return Response::json($resultSet); | ||||
|     } | ||||
| }  | ||||
| @@ -1,162 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| use Firefly\Storage\Budget\BudgetRepositoryInterface as BRI; | ||||
| use Firefly\Storage\Limit\LimitRepositoryInterface as LRI; | ||||
|  | ||||
| /** | ||||
|  * Class LimitController | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CamelCasePropertyName) | ||||
|  */ | ||||
| class LimitController extends BaseController | ||||
| { | ||||
|  | ||||
|     protected $_budgets; | ||||
|     protected $_limits; | ||||
|  | ||||
|     /** | ||||
|      * @param BRI $budgets | ||||
|      * @param LRI $limits | ||||
|      */ | ||||
|     public function __construct(BRI $budgets, LRI $limits) | ||||
|     { | ||||
|         $this->_budgets = $budgets; | ||||
|         $this->_limits  = $limits; | ||||
|  | ||||
|         View::share('title','Envelopes'); | ||||
|         View::share('mainTitleIcon', 'fa-tasks'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function create(\Budget $budget = null) | ||||
|     { | ||||
|         $periods   = \Config::get('firefly.periods_to_text'); | ||||
|         $prefilled = [ | ||||
|             'startdate'   => \Input::get('startdate') ? : date('Y-m-d'), | ||||
|             'repeat_freq' => \Input::get('repeat_freq') ? : 'monthly', | ||||
|             'budget_id'   => $budget ? $budget->id : null | ||||
|         ]; | ||||
|  | ||||
|         /** @var \Firefly\Helper\Toolkit\Toolkit $toolkit */ | ||||
|         $toolkit = App::make('Firefly\Helper\Toolkit\Toolkit'); | ||||
|         $budgets = $toolkit->makeSelectList($this->_budgets->get()); | ||||
|  | ||||
|         return View::make('limits.create')->with('budgets', $budgets)->with( | ||||
|             'periods', $periods | ||||
|         )->with('prefilled', $prefilled)->with('subTitle','New envelope'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Limit $limit | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function delete(\Limit $limit) | ||||
|     { | ||||
|         return View::make('limits.delete')->with('limit', $limit)->with('subTitle','Delete envelope'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Limit $limit | ||||
|      * | ||||
|      * @return \Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function destroy(\Limit $limit) | ||||
|     { | ||||
|         Event::fire('limits.destroy', [$limit]); // before | ||||
|         $success = $this->_limits->destroy($limit); | ||||
|  | ||||
|         if ($success) { | ||||
|             Session::flash('success', 'The envelope was deleted.'); | ||||
|         } else { | ||||
|             Session::flash('error', 'Could not delete the envelope. Check the logs to be sure.'); | ||||
|         } | ||||
|         if (Input::get('from') == 'date') { | ||||
|             return Redirect::route('budgets.index'); | ||||
|         } else { | ||||
|             return Redirect::route('budgets.index.budget'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Limit $limit | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function edit(Limit $limit) | ||||
|     { | ||||
|         /** @var \Firefly\Helper\Toolkit\Toolkit $toolkit */ | ||||
|         $toolkit = App::make('Firefly\Helper\Toolkit\Toolkit'); | ||||
|  | ||||
|         $budgets    = $toolkit->makeSelectList($this->_budgets->get()); | ||||
|         $periods = \Config::get('firefly.periods_to_text'); | ||||
|  | ||||
|         return View::make('limits.edit')->with('limit', $limit)->with('budgets', $budgets)->with( | ||||
|             'periods', $periods | ||||
|         )->with('subTitle','Edit envelope'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function store(Budget $budget = null) | ||||
|     { | ||||
|  | ||||
|         // find a limit with these properties, as Firefly might already have one: | ||||
|         $limit = $this->_limits->store(Input::all()); | ||||
|         if ($limit->validate()) { | ||||
|             Session::flash('success', 'Envelope created!'); | ||||
|             Event::fire('limits.store', [$limit]); | ||||
|             if (Input::get('from') == 'date') { | ||||
|                 return Redirect::route('budgets.index'); | ||||
|             } else { | ||||
|                 return Redirect::route('budgets.index.budget'); | ||||
|             } | ||||
|         } else { | ||||
|             Session::flash('error', 'Could not save new envelope.'); | ||||
|             $budgetId   = $budget ? $budget->id : null; | ||||
|             $parameters = [$budgetId, 'from' => Input::get('from')]; | ||||
|  | ||||
|             return Redirect::route('budgets.limits.create', $parameters)->withInput() | ||||
|                 ->withErrors($limit->errors()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Limit $limit | ||||
|      * | ||||
|      * @return $this|\Illuminate\Http\RedirectResponse | ||||
|      */ | ||||
|     public function update(\Limit $limit) | ||||
|     { | ||||
|  | ||||
|  | ||||
|         $limit = $this->_limits->update($limit, Input::all()); | ||||
|  | ||||
|         if ($limit->validate()) { | ||||
|             Event::fire('limits.update', [$limit]); | ||||
|             Session::flash('success', 'Limit saved!'); | ||||
|             if (Input::get('from') == 'date') { | ||||
|                 return Redirect::route('budgets.index'); | ||||
|             } else { | ||||
|                 return Redirect::route('budgets.index.budget'); | ||||
|             } | ||||
|  | ||||
|  | ||||
|         } else { | ||||
|             Session::flash('error', 'Could not save new limit: ' . $limit->errors()->first()); | ||||
|  | ||||
|             return Redirect::route('budgets.limits.edit', [$limit->id, 'from' => Input::get('from')])->withInput() | ||||
|                 ->withErrors($limit->errors()); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
| }  | ||||
| @@ -1,52 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Class MigrateController | ||||
|  */ | ||||
| class MigrateController extends BaseController | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function index() | ||||
|     { | ||||
|         return View::make('migrate.index')->with('index', 'Migration')->with('title','Migrate')-> | ||||
|             with('subTitle','From Firefly II to Firefly III'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function upload() | ||||
|     { | ||||
|         if (Input::hasFile('file') && Input::file('file')->isValid()) { | ||||
|             $path     = storage_path(); | ||||
|             $fileName = 'firefly-iii-import-' . date('Y-m-d-H-i') . '.json'; | ||||
|             $fullName = $path . DIRECTORY_SEPARATOR . $fileName; | ||||
|             if (Input::file('file')->move($path, $fileName)) { | ||||
|                 // so now Firefly pushes something in a queue and does something with it! Yay! | ||||
|                 \Log::debug('Pushed a job to start the import.'); | ||||
|                 Queue::push('Firefly\Queue\Import@start', ['file' => $fullName, 'user' => \Auth::user()->id]); | ||||
|                 if (Config::get('queue.default') == 'sync') { | ||||
|                     Session::flash('success', 'Your data has been imported!'); | ||||
|                 } else { | ||||
|                     Session::flash( | ||||
|                         'success', | ||||
|                         'The import job has been queued. Please be patient. Data will appear slowly. Please be patient.' | ||||
|                     ); | ||||
|                 } | ||||
|  | ||||
|                 return Redirect::route('index'); | ||||
|             } | ||||
|             Session::flash('error', 'Could not save file to storage.'); | ||||
|             return Redirect::route('migrate.index'); | ||||
|  | ||||
|         } else { | ||||
|             Session::flash('error', 'Please upload a file.'); | ||||
|             return Redirect::route('migrate.index'); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| }  | ||||
| @@ -6,11 +6,10 @@ App::before( | ||||
|     function ($request) { | ||||
|  | ||||
|         if (Auth::check()) { | ||||
|             /** @var \Firefly\Helper\Toolkit\ToolkitInterface $toolkit */ | ||||
|             $toolkit = App::make('Firefly\Helper\Toolkit\ToolkitInterface'); | ||||
|             $toolkit->getDateRange(); | ||||
|             $toolkit->checkImportJobs(); | ||||
|             Event::fire('recurring.verify'); | ||||
|             /** @var \FireflyIII\Shared\Toolkit\Filter $toolkit */ | ||||
|             $filter = App::make('FireflyIII\Shared\Toolkit\Filter'); | ||||
|             $filter->setSessionDateRange(); | ||||
|             //Event::fire('recurring.verify'); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|   | ||||
| @@ -107,9 +107,6 @@ class Toolkit implements ToolkitInterface | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|      */ | ||||
|     protected function _getRange() | ||||
|     { | ||||
|         if (!is_null(\Session::get('range'))) { | ||||
|   | ||||
| @@ -85,6 +85,34 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData | ||||
|         return $this->getuser()->transactionjournals()->withRelevantData()->before($end)->after($start)->get(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \Account $account | ||||
|      * @param int      $count | ||||
|      * @param Carbon   $start | ||||
|      * @param Carbon   $end | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getInDateRangeAccount(\Account $account, $count = 20, Carbon $start, Carbon $end) | ||||
|     { | ||||
|  | ||||
|         $accountID = $account->id; | ||||
|         $query     = $this->_user | ||||
|             ->transactionjournals() | ||||
|             ->with(['transactions', 'transactioncurrency', 'transactiontype']) | ||||
|             ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|             ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') | ||||
|             ->where('accounts.id', $accountID) | ||||
|             ->where('date', '>=', $start->format('Y-m-d')) | ||||
|             ->where('date', '<=', $end->format('Y-m-d')) | ||||
|             ->orderBy('transaction_journals.date', 'DESC') | ||||
|             ->orderBy('transaction_journals.id', 'DESC') | ||||
|             ->take($count) | ||||
|             ->get(['transaction_journals.*']); | ||||
|  | ||||
|         return $query; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return TransactionJournal | ||||
|      */ | ||||
|   | ||||
							
								
								
									
										28
									
								
								app/lib/FireflyIII/FF3ServiceProvider.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/lib/FireflyIII/FF3ServiceProvider.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| <?php | ||||
| namespace FireflyIII; | ||||
|  | ||||
| use Illuminate\Support\ServiceProvider; | ||||
|  | ||||
| /** | ||||
|  * Class FF3ServiceProvider | ||||
|  * | ||||
|  * @package FireflyIII | ||||
|  */ | ||||
| class FF3ServiceProvider extends ServiceProvider | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Triggered automatically by Laravel | ||||
|      */ | ||||
|     public function register() | ||||
|     { | ||||
|         // FORMAT: | ||||
|         #$this->app->bind('Interface', 'Class'); | ||||
|  | ||||
|         // preferences: | ||||
|         $this->app->bind('FireflyIII\Shared\Preferences\PreferencesInterface', 'FireflyIII\Shared\Preferences\Preferences'); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										296
									
								
								app/lib/FireflyIII/Shared/Toolkit/Filter.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								app/lib/FireflyIII/Shared/Toolkit/Filter.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,296 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Created by PhpStorm. | ||||
|  * User: sander | ||||
|  * Date: 11/11/14 | ||||
|  * Time: 11:17 | ||||
|  */ | ||||
|  | ||||
| namespace FireflyIII\Shared\Toolkit; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Firefly\Exception\FireflyException; | ||||
|  | ||||
| /** | ||||
|  * Class Filter | ||||
|  * | ||||
|  * @package FireflyIII\Shared\Toolkit | ||||
|  */ | ||||
| class Filter | ||||
| { | ||||
|     /** | ||||
|      * Checks and sets the currently set 'range' or defaults to a session | ||||
|      * and if that fails, defaults to 1M. Always returns the final value. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function setSessionRangeValue() | ||||
|     { | ||||
|         if (!is_null(\Session::get('range'))) { | ||||
|             $range = \Session::get('range'); | ||||
|         } else { | ||||
|             /** @noinspection PhpUndefinedClassInspection */ | ||||
|             $preferences = \App::make('Firefly\Helper\Preferences\PreferencesHelperInterface'); | ||||
|             $viewRange   = $preferences->get('viewRange', '1M'); | ||||
|  | ||||
|             // default range: | ||||
|             $range = $viewRange->data; | ||||
|             \Session::put('range', $range); | ||||
|         } | ||||
|         return $range; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Save Session::get('start') and Session::get('end') for other methods to use. | ||||
|      */ | ||||
|     public function setSessionDateRange() | ||||
|     { | ||||
|         /* | ||||
|          * Get the current range. | ||||
|          */ | ||||
|         $range = $this->setSessionRangeValue(); | ||||
|         $start = \Session::has('start') ? \Session::get('start') : new Carbon; | ||||
|  | ||||
|         /* | ||||
|          * Force start date to at the start of the $range. | ||||
|          * Ie. the start of the week, month, year. This also to protect against nefarious users | ||||
|          * who change their session data (I just wanted to use the word "nefarious"). | ||||
|          */ | ||||
|         $start = $this->updateStartDate($range, $start); | ||||
|  | ||||
|         /* | ||||
|          * Force end date to at the END of the $range. Always based on $start. | ||||
|          * Ie. the END of the week, month, year. | ||||
|          */ | ||||
|         $end = $this->updateEndDate($range, $start); | ||||
|         #\Log::debug('After update, session end is  : ' . $end->format('Y-m-d')); | ||||
|  | ||||
|         /* | ||||
|          * get the name of the month, depending on the range. Purely for astetics | ||||
|          */ | ||||
|         $period = $this->periodName($range, $start); | ||||
|  | ||||
|         /* | ||||
|          * Get the date for the previous and next period. | ||||
|          * Ie. next week, next month, etc. | ||||
|          */ | ||||
|         $prev = $this->previous($range, clone $start); | ||||
|         $next = $this->next($range, clone $start); | ||||
|  | ||||
|         /* | ||||
|          * Save everything in the session: | ||||
|          */ | ||||
|         \Session::put('start', $start); | ||||
|         \Session::put('end', $end); | ||||
|         \Session::put('range', $range); | ||||
|         \Session::put('period', $period); | ||||
|         \Session::put('prev', $this->periodName($range, $prev)); | ||||
|         \Session::put('next', $this->periodName($range, $next)); | ||||
|         return null; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param        $range | ||||
|      * @param Carbon $start | ||||
|      * | ||||
|      * @return Carbon | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     protected function updateStartDate($range, Carbon $start) | ||||
|     { | ||||
|         switch ($range) { | ||||
|             default: | ||||
|                 throw new FireflyException('updateStartDate cannot handle $range ' . $range); | ||||
|                 break; | ||||
|             case '1D': | ||||
|                 $start->startOfDay(); | ||||
|                 break; | ||||
|             case '1W': | ||||
|                 $start->startOfWeek(); | ||||
|                 break; | ||||
|             case '1M': | ||||
|                 $start->startOfMonth(); | ||||
|                 break; | ||||
|             case '3M': | ||||
|                 $start->firstOfQuarter(); | ||||
|                 break; | ||||
|             case '6M': | ||||
|                 if (intval($start->format('m')) >= 7) { | ||||
|                     $start->startOfYear()->addMonths(6); | ||||
|                 } else { | ||||
|                     $start->startOfYear(); | ||||
|                 } | ||||
|                 break; | ||||
|             case '1Y': | ||||
|                 $start->startOfYear(); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $start; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param        $range | ||||
|      * @param Carbon $start | ||||
|      * | ||||
|      * @return Carbon | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     protected function updateEndDate($range, Carbon $start) | ||||
|     { | ||||
|         $end = clone $start; | ||||
|         switch ($range) { | ||||
|             default: | ||||
|                 throw new FireflyException('updateEndDate cannot handle $range ' . $range); | ||||
|                 break; | ||||
|             case '1D': | ||||
|                 $end->endOfDay(); | ||||
|                 break; | ||||
|             case '1W': | ||||
|                 $end->endOfWeek(); | ||||
|                 break; | ||||
|             case '1M': | ||||
|                 $end->endOfMonth(); | ||||
|                 break; | ||||
|             case '3M': | ||||
|                 $end->lastOfQuarter(); | ||||
|                 break; | ||||
|             case '6M': | ||||
|                 if (intval($start->format('m')) >= 7) { | ||||
|                     $end->endOfYear(); | ||||
|                 } else { | ||||
|                     $end->startOfYear()->addMonths(6); | ||||
|                 } | ||||
|                 break; | ||||
|             case '1Y': | ||||
|                 $end->endOfYear(); | ||||
|                 break; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         return $end; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param        $range | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return string | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     protected function periodName($range, Carbon $date) | ||||
|     { | ||||
|         switch ($range) { | ||||
|             default: | ||||
|                 throw new FireflyException('No _periodName() for range "' . $range . '"'); | ||||
|                 break; | ||||
|             case '1D': | ||||
|                 return $date->format('jS F Y'); | ||||
|                 break; | ||||
|             case '1W': | ||||
|                 return 'week ' . $date->format('W, Y'); | ||||
|                 break; | ||||
|             case '1M': | ||||
|                 return $date->format('F Y'); | ||||
|                 break; | ||||
|             case '3M': | ||||
|                 $month = intval($date->format('m')); | ||||
|                 return 'Q' . ceil(($month / 12) * 4) . ' ' . $date->format('Y'); | ||||
|                 break; | ||||
|             case '6M': | ||||
|                 $month    = intval($date->format('m')); | ||||
|                 $half     = ceil(($month / 12) * 2); | ||||
|                 $halfName = $half == 1 ? 'first' : 'second'; | ||||
|                 return $halfName . ' half of ' . $date->format('d-m-Y'); | ||||
|                 break; | ||||
|             case '1Y': | ||||
|                 return $date->format('Y'); | ||||
|                 break; | ||||
|  | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param        $range | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return Carbon | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     protected function previous($range, Carbon $date) | ||||
|     { | ||||
|         switch ($range) { | ||||
|             default: | ||||
|                 throw new FireflyException('Cannot do _previous() on ' . $range); | ||||
|                 break; | ||||
|             case '1D': | ||||
|                 $date->startOfDay()->subDay(); | ||||
|                 break; | ||||
|             case '1W': | ||||
|                 $date->startOfWeek()->subWeek(); | ||||
|                 break; | ||||
|             case '1M': | ||||
|                 $date->startOfMonth()->subMonth(); | ||||
|                 break; | ||||
|             case '3M': | ||||
|                 $date->firstOfQuarter()->subMonths(3)->firstOfQuarter(); | ||||
|                 break; | ||||
|             case '6M': | ||||
|                 $month = intval($date->format('m')); | ||||
|                 if ($month <= 6) { | ||||
|                     $date->startOfYear()->subMonths(6); | ||||
|                 } else { | ||||
|                     $date->startOfYear(); | ||||
|                 } | ||||
|                 break; | ||||
|             case '1Y': | ||||
|                 $date->startOfYear()->subYear(); | ||||
|                 break; | ||||
|  | ||||
|         } | ||||
|         return $date; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param        $range | ||||
|      * @param Carbon $date | ||||
|      * | ||||
|      * @return Carbon | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     protected function next($range, Carbon $date) | ||||
|     { | ||||
|         switch ($range) { | ||||
|             case '1D': | ||||
|                 $date->endOfDay()->addDay(); | ||||
|                 break; | ||||
|             case '1W': | ||||
|                 $date->endOfWeek()->addDay()->startOfWeek(); | ||||
|                 break; | ||||
|             case '1M': | ||||
|                 $date->endOfMonth()->addDay()->startOfMonth(); | ||||
|                 break; | ||||
|             case '3M': | ||||
|                 $date->lastOfQuarter()->addDay(); | ||||
|                 break; | ||||
|             case '6M': | ||||
|                 if (intval($date->format('m')) >= 7) { | ||||
|                     $date->startOfYear()->addYear(); | ||||
|                 } else { | ||||
|                     $date->startOfYear()->addMonths(6); | ||||
|                 } | ||||
|                 break; | ||||
|             case '1Y': | ||||
|                 $date->startOfYear()->addYear(); | ||||
|                 break; | ||||
|             default: | ||||
|                 throw new FireflyException('Cannot do _next() on ' . $range); | ||||
|                 break; | ||||
|         } | ||||
|         return $date; | ||||
|     } | ||||
| }  | ||||
							
								
								
									
										123
									
								
								app/routes.php
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								app/routes.php
									
									
									
									
									
								
							| @@ -1,8 +1,5 @@ | ||||
| <?php | ||||
|  | ||||
| //use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||||
|  | ||||
|  | ||||
| // models: | ||||
| Route::bind( | ||||
|     'account', function ($value, $route) { | ||||
| @@ -90,18 +87,6 @@ Route::bind( | ||||
|     } | ||||
| ); | ||||
|  | ||||
| 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.*']); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| ); | ||||
|  | ||||
| Route::bind( | ||||
|     'limitrepetition', function ($value, $route) { | ||||
|         if (Auth::check()) { | ||||
| @@ -126,22 +111,18 @@ Route::bind( | ||||
| ); | ||||
|  | ||||
|  | ||||
| // a development route: | ||||
| Route::get('/dev', ['uses' => 'HomeController@jobDev']); | ||||
|  | ||||
| // protected routes: | ||||
| Route::group( | ||||
|     ['before' => 'auth'], function () { | ||||
|  | ||||
|  | ||||
|         // some date routes: | ||||
|         // some date routes used for (well duh) date-based navigation. | ||||
|         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/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']); | ||||
| @@ -150,23 +131,18 @@ Route::group( | ||||
|  | ||||
|         // budget controller: | ||||
|         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/date', ['uses' => 'BudgetController@indexByDate', 'as' => 'budgets.index.date']); | ||||
|         #Route::get('/budgets/budget', ['uses' => 'BudgetController@indexByBudget', 'as' => 'budgets.index.budget']); | ||||
|         Route::get('/budgets/income', ['uses' => 'BudgetController@updateIncome', 'as' => 'budgets.income']); # extra. | ||||
|         Route::get('/budgets/create', ['uses' => 'BudgetController@create', 'as' => 'budgets.create']); | ||||
|         #Route::get('/budgets/nobudget/{period}', ['uses' => 'BudgetController@nobudget', 'as' => 'budgets.nobudget']); | ||||
|  | ||||
|         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/show/{budget}/{limitrepetition?}', ['uses' => 'BudgetController@show', 'as' => 'budgets.show']); | ||||
|  | ||||
|         // 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/show/{category}', ['uses' => 'CategoryController@show', 'as' => 'categories.show']); | ||||
|  | ||||
|         // google chart controller | ||||
|         Route::get('/chart/home/account', ['uses' => 'GoogleChartController@allAccountsBalanceChart']); | ||||
| @@ -180,7 +156,7 @@ Route::group( | ||||
|         Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']); | ||||
|         Route::get('/chart/reports/budgets/{year}', ['uses' => 'GoogleChartController@budgetsReportChart']); | ||||
|  | ||||
|         // google chart (categories + budgets) | ||||
|         // google chart for components (categories + budgets combined) | ||||
|         Route::get('/chart/component/{component}/spending/{year}', ['uses' => 'GoogleChartController@componentsAndSpending']); | ||||
|  | ||||
|         // google table controller | ||||
| @@ -188,57 +164,23 @@ Route::group( | ||||
|         Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']); | ||||
|         Route::get('/table/categories', ['uses' => 'GoogleTableController@categoryList']); | ||||
|  | ||||
|         // google table (categories + budgets) | ||||
|  | ||||
|         // google table for components (categories + budgets) | ||||
|         Route::get('/table/component/{component}/{limitrepetition}/transactions', ['uses' => 'GoogleTableController@transactionsByComponent']); | ||||
|  | ||||
|  | ||||
|         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']); | ||||
|  | ||||
|         // (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']); | ||||
|         Route::get('chart/budget/{budget}/session', ['uses' => 'ChartController@budgetSession', 'as' => 'chart.budget.session']); | ||||
|         Route::get('chart/budget/envelope/{limitrepetition}', ['uses' => 'ChartController@budgetLimit', 'as' => 'chart.budget.limit']); | ||||
|  | ||||
|         // home controller | ||||
|         Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']); | ||||
|         Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); | ||||
|  | ||||
|         // JSON controller: | ||||
|         Route::get('/json/expense-accounts', ['uses' => 'JsonController@expenseAccounts', 'as' => 'json.expense-accounts']); | ||||
|         Route::get('/json/revenue-accounts', ['uses' => 'JsonController@revenueAccounts', 'as' => 'json.revenue-accounts']); | ||||
|         Route::get('/json/categories', ['uses' => 'JsonController@categories', 'as' => 'json.categories']); | ||||
|         Route::get('/json/expenses', ['uses' => 'JsonController@expenses', 'as' => 'json.expenses']); | ||||
|         Route::get('/json/revenue', ['uses' => 'JsonController@revenue', 'as' => 'json.revenue']); | ||||
|         Route::get('/json/transfers', ['uses' => 'JsonController@transfers', 'as' => 'json.transfers']); | ||||
|         Route::get('/json/recurring', ['uses' => 'JsonController@recurring', 'as' => 'json.recurring']); | ||||
|         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('/migrate', ['uses' => 'MigrateController@index', 'as' => 'migrate.index']); | ||||
|         Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); # even though nothing is cached. | ||||
|  | ||||
|         // piggy bank controller | ||||
|         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/add/{piggybank}', ['uses' => 'PiggybankController@add']); # add money | ||||
|         Route::get('/piggybanks/remove/{piggybank}', ['uses' => 'PiggybankController@remove']); #remove money | ||||
|  | ||||
|         Route::get('/piggybanks/create', ['uses' => 'PiggybankController@create', 'as' => 'piggybanks.create']); | ||||
|         Route::get('/piggybanks/edit/{piggybank}', ['uses' => 'PiggybankController@edit', 'as' => 'piggybanks.edit']); | ||||
|         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']); | ||||
|         Route::get('/piggybanks/show/{piggybank}', ['uses' => 'PiggybankController@show', 'as' => 'piggybanks.show']); | ||||
|  | ||||
|         // preferences controller | ||||
|         Route::get('/preferences', ['uses' => 'PreferencesController@index', 'as' => 'preferences']); | ||||
| @@ -249,11 +191,11 @@ Route::group( | ||||
|  | ||||
|         // 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/rescan/{recurring}', ['uses' => 'RecurringController@rescan', 'as' => 'recurring.rescan']); # rescan for matching. | ||||
|         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/show/{recurring}', ['uses' => 'RecurringController@show', 'as' => 'recurring.show']); | ||||
|  | ||||
|         // report controller: | ||||
|         Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']); | ||||
| @@ -263,25 +205,20 @@ Route::group( | ||||
|         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('/transactions/{what}', ['uses' => 'TransactionController@index', 'as' => 'transactions.index'])->where( | ||||
|             ['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers'] | ||||
|         ); | ||||
|         Route::get('/transactions/create/{what}', ['uses' => 'TransactionController@create', 'as' => 'transactions.create'])->where( | ||||
|             ['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers'] | ||||
|         ); | ||||
|         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('/transaction/show/{tj}', ['uses' => 'TransactionController@show', 'as' => 'transactions.show']); | ||||
|  | ||||
|         // user controller | ||||
|         Route::get('/logout', ['uses' => 'UserController@logout', 'as' => 'logout']); | ||||
|  | ||||
|         Route::post('budgets/amount/{budget}', ['uses' => 'BudgetController@amount']); | ||||
|         //Route::post('budgets/amount/{budget}', ['uses' => 'BudgetController@amount']); | ||||
|  | ||||
|  | ||||
|     } | ||||
| @@ -297,8 +234,8 @@ Route::group( | ||||
|  | ||||
|         // budget controller: | ||||
|         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/update/{budget}', ['uses' => 'BudgetController@update', 'as' => 'budgets.update']); | ||||
|         Route::post('/budgets/destroy/{budget}', ['uses' => 'BudgetController@destroy', 'as' => 'budgets.destroy']); | ||||
|  | ||||
|         // category controller | ||||
| @@ -306,22 +243,12 @@ Route::group( | ||||
|         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('/migrate/upload', ['uses' => 'MigrateController@upload', 'as' => 'migrate.upload']); | ||||
|  | ||||
|  | ||||
|         // piggy bank controller | ||||
|         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']); | ||||
|         Route::post('/piggybanks/add/{piggybank}', ['uses' => 'PiggybankController@postAdd', 'as' => 'piggybanks.add']); # add money | ||||
|         Route::post('/piggybanks/remove/{piggybank}', ['uses' => 'PiggybankController@postRemove', 'as' => 'piggybanks.remove']); # remove money. | ||||
|  | ||||
|  | ||||
|         // preferences controller | ||||
| @@ -337,7 +264,7 @@ Route::group( | ||||
|  | ||||
|         // transaction controller: | ||||
|         Route::post('/transactions/store/{what}', ['uses' => 'TransactionController@store', 'as' => 'transactions.store'])->where( | ||||
|             ['what' => 'withdrawal|deposit|transfer'] | ||||
|             ['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers'] | ||||
|         ); | ||||
|         Route::post('/transaction/update/{tj}', ['uses' => 'TransactionController@update', 'as' => 'transactions.update']); | ||||
|         Route::post('/transaction/destroy/{tj}', ['uses' => 'TransactionController@destroy', 'as' => 'transactions.destroy']); | ||||
|   | ||||
| @@ -12,40 +12,6 @@ | ||||
| <!-- /.navbar-header --> | ||||
|  | ||||
| <ul class="nav navbar-top-links navbar-right"> | ||||
|     @if(Session::has('job_pct')) | ||||
|     <!-- /.dropdown --> | ||||
|     <li class="dropdown"> | ||||
|         <a class="dropdown-toggle" data-toggle="dropdown" href="#"> | ||||
|             <i class="fa fa-tasks fa-fw"></i>  <i class="fa fa-caret-down"></i> | ||||
|         </a> | ||||
|         <!-- display for import tasks, possibly others --> | ||||
|  | ||||
|         <ul class="dropdown-menu dropdown-tasks"> | ||||
|             <li> | ||||
|                 <a href="#"> | ||||
|                     <div> | ||||
|                         <p> | ||||
|                             <strong>Import from Firefly II</strong> | ||||
|                             <span class="pull-right text-muted">{{Session::get('job_pct')}}% Complete</span> | ||||
|                         </p> | ||||
|                         <div class="progress progress-striped active"> | ||||
|                             <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{Session::get('job_pct')}}" aria-valuemin="0" aria-valuemax="100" style="width: {{Session::get('job_pct')}}%"> | ||||
|                                 <span class="sr-only">{{Session::get('job_pct')}}% Complete (success)</span> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <p> | ||||
|                             <small>Finished ~ {{Session::get('job_text')}}</small> | ||||
|                         </p> | ||||
|                     </div> | ||||
|                 </a> | ||||
|             </li> | ||||
|         </ul> | ||||
|         <!-- /.dropdown-tasks --> | ||||
|     </li> | ||||
|     @endif | ||||
|  | ||||
|  | ||||
|  | ||||
|     <li class="dropdown"> | ||||
|     <a class="dropdown-toggle" data-toggle="dropdown" href="#"> | ||||
|         <i class="fa fa-user fa-fw"></i> <i class="fa fa-caret-down"></i> | ||||
| @@ -75,7 +41,6 @@ | ||||
|             <li class="sidebar-search"> | ||||
|             <form action="{{route('search')}}" method="GET" class="form-inline"> | ||||
|                 <div class="input-group custom-search-form"> | ||||
|  | ||||
|                     <input type="text" name="q" class="form-control" placeholder="Search..."> | ||||
|                                 <span class="input-group-btn"> | ||||
|                                 <button class="btn btn-default" type="submit"> | ||||
| @@ -90,133 +55,75 @@ | ||||
|             <li> | ||||
|                 <a @if($r == 'index') class="active" @endif href="{{route('index')}}"><i class="fa fa-dashboard fa-fw"></i> Dashboard</a> | ||||
|             </li> | ||||
|             <li | ||||
|                 @if(!(strpos($r,'accounts') === false)) | ||||
|                     class="active" | ||||
|                 @endif | ||||
|                 > | ||||
|             <li> | ||||
|                 <a href="#"><i class="fa fa-credit-card fa-fw"></i> Accounts <span class="fa arrow"></span></a> | ||||
|                 <ul class="nav nav-second-level"> | ||||
|                     <li> | ||||
|                         <a @if(isset($what) && $what == 'asset')class="active"@endif href="{{route('accounts.index','asset')}}"><i class="fa fa-money fa-fw"></i> Asset accounts</a> | ||||
|                         <a href="{{route('accounts.index','asset')}}"><i class="fa fa-money fa-fw"></i> Asset accounts</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a @if(isset($what) && $what == 'expense')class="active"@endif href="{{route('accounts.index','expense')}}"><i class="fa fa-shopping-cart fa-fw"></i> Expense accounts</a> | ||||
|                         <a href="{{route('accounts.index','expense')}}"><i class="fa fa-shopping-cart fa-fw"></i> Expense accounts</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a @if(isset($what) && $what == 'revenue')class="active"@endif href="{{route('accounts.index','revenue')}}"><i class="fa fa-download fa-fw"></i> Revenue accounts</a> | ||||
|                         <a href="{{route('accounts.index','revenue')}}"><i class="fa fa-download fa-fw"></i> Revenue accounts</a> | ||||
|                     </li> | ||||
|                 </ul> | ||||
|                 <!-- /.nav-second-level --> | ||||
|             </li> | ||||
|             <li> | ||||
|                 <a href="{{route('budgets.index')}}"><i class="fa fa-tasks fa-fw"></i> Budgets</a> | ||||
|                 <a @if($r == 'budgets.index') class="index" @endif href="{{route('budgets.index')}}"><i class="fa fa-tasks fa-fw"></i> Budgets</a> | ||||
|             </li> | ||||
|             <li> | ||||
|                 <a | ||||
|                 @if(!(strpos($r,'categories') === false)) | ||||
|                 class="active" | ||||
|                 @endif | ||||
|                     href="{{route('categories.index')}}"><i class="fa fa-bar-chart fa-fw"></i> Categories</a> | ||||
|                 <a @if($r == 'categories.index') class="active" @endif href="{{route('categories.index')}}"><i class="fa fa-bar-chart fa-fw"></i> Categories</a> | ||||
|             </li> | ||||
|             <li> | ||||
|                 <a href="#"><i class="fa fa-tags fa-fw"></i> Tags</a> | ||||
|             </li> | ||||
|             <li | ||||
|             @if(!(strpos($r,'reports') === false)) | ||||
|             class="active" | ||||
|             @endif | ||||
|             > | ||||
|                 <a href="{{route('reports.index')}}"><i class="fa fa-line-chart fa-fw"></i> Reports</a> | ||||
|             <li> | ||||
|                 <a @if($r == 'reports.index') class="active" @endif href="{{route('reports.index')}}"><i class="fa fa-line-chart fa-fw"></i> Reports</a> | ||||
|             </li> | ||||
|             <li | ||||
|             @if( | ||||
|             !(strpos($r,'transactions.expenses') === false) || | ||||
|             !(strpos($r,'transactions.revenue') === false) || | ||||
|             !(strpos($r,'transactions.transfers') === false) || | ||||
|             !(strpos($r,'transactions.index') === false) | ||||
|             ) | ||||
|             class="active" | ||||
|             @endif | ||||
|                 > | ||||
|                 <a href="{{route('transactions.index')}}"><i class="fa fa-repeat fa-fw"></i> Transactions<span class="fa arrow"></span></a> | ||||
|             <li> | ||||
|                 <a href="#"><i class="fa fa-repeat fa-fw"></i> Transactions<span class="fa arrow"></span></a> | ||||
|                 <ul class="nav nav-second-level"> | ||||
|                     <li> | ||||
|                         <a @if($r == 'transactions.expenses' || $r == 'transactions.index.withdrawal') class="active" @endif href="{{route('transactions.expenses')}}"><i class="fa fa-long-arrow-left fa-fw"></i> Expenses</a> | ||||
|                         <a href="{{route('transactions.index','withdrawal')}}"><i class="fa fa-long-arrow-left fa-fw"></i> Expenses</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a @if($r == 'transactions.revenue' || $r == 'transactions.index.deposit') class="active" @endif href="{{route('transactions.revenue')}}"><i class="fa fa-long-arrow-right fa-fw"></i> Revenue / income</a> | ||||
|                         <a href="{{route('transactions.index','deposit')}}"><i class="fa fa-long-arrow-right fa-fw"></i> Revenue / income</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a @if($r == 'transactions.transfers' || $r == 'transactions.index.transfer') class="active" @endif href="{{route('transactions.transfers')}}"><i class="fa fa-arrows-h fa-fw"></i> Transfers</a> | ||||
|                         <a href="{{route('transactions.index','transfers')}}"><i class="fa fa-arrows-h fa-fw"></i> Transfers</a> | ||||
|                     </li> | ||||
|                 </ul> | ||||
|  | ||||
|             </li> | ||||
|             <li | ||||
|             @if( | ||||
|             !(strpos($r,'piggybanks') === false) || | ||||
|             !(strpos($r,'recurring') === false) | ||||
|             ) | ||||
|             class="active" | ||||
|             @endif | ||||
|                 > | ||||
|             <li> | ||||
|                 <a href="#"><i class="fa fa-euro fa-fw"></i> Money management<span class="fa arrow"></span></a> | ||||
|                 <ul class="nav nav-second-level"> | ||||
|                     <li> | ||||
|                         <a @if($r == 'piggybanks.index') class="active" @endif href="{{route('piggybanks.index')}}"><i class="fa fa-sort-amount-asc fa-fw"></i> Piggy banks</a> | ||||
|                         <a href="{{route('piggybanks.index')}}"><i class="fa fa-sort-amount-asc fa-fw"></i> Piggy banks</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a @if($r == 'recurring.index') class="active" @endif href="{{route('recurring.index')}}"><i class="fa fa-rotate-right fa-fw"></i> Recurring transactions</a> | ||||
|                         <a href="{{route('recurring.index')}}"><i class="fa fa-rotate-right fa-fw"></i> Recurring transactions</a> | ||||
|                     </li> | ||||
|                     {{-- | ||||
|                     <li> | ||||
|                         <a @if($r == 'piggybanks.index.repeated') class="active" @endif href="{{route('piggybanks.index.repeated')}}"><i class="fa fa-rotate-left fa-fw"></i> Repeated expenses</a> | ||||
|                     </li> | ||||
|                     --}} | ||||
|                 </ul> | ||||
|                 <!-- /.nav-second-level --> | ||||
|             </li> | ||||
|             <li | ||||
|                 @if( !(strpos($r,'transactions.create') === false) ) | ||||
|                     class="active" | ||||
|                 @endif | ||||
|                 > | ||||
|             <li> | ||||
|                 <a href="#"><i class="fa fa-plus fa-fw"></i> Create new<span class="fa arrow"></span></a> | ||||
|                 <ul class="nav nav-second-level"> | ||||
|                     <li> | ||||
|                         <a @if($r == 'transactions.create' && isset($what) && $what == 'withdrawal') class="active" @endif href="{{route('transactions.create','withdrawal')}}"><i class="fa fa-long-arrow-left fa-fw"></i> Withdrawal</a> | ||||
|                         <a href="{{route('transactions.create','withdrawal')}}"><i class="fa fa-long-arrow-left fa-fw"></i> Withdrawal</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a @if($r == 'transactions.create' && isset($what) && $what == 'deposit') class="active" @endif href="{{route('transactions.create','deposit')}}"><i class="fa fa-long-arrow-right fa-fw"></i> Deposit</a> | ||||
|                         <a href="{{route('transactions.create','deposit')}}"><i class="fa fa-long-arrow-right fa-fw"></i> Deposit</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a @if($r == 'transactions.create' && isset($what) && $what == 'transfer') class="active" @endif href="{{route('transactions.create','transfer')}}"><i class="fa fa-arrows-h fa-fw"></i> Transfer</a> | ||||
|                         <a href="{{route('transactions.create','transfer')}}"><i class="fa fa-arrows-h fa-fw"></i> Transfer</a> | ||||
|                     </li> | ||||
|                     <!-- | ||||
|                     <li> | ||||
|                         <a href="#"><i class="fa fa-money fa-fw"></i> Account</a> | ||||
|                     </li> | ||||
|                     --> | ||||
|                     <li> | ||||
|                         <a href="#"><i class="fa fa-tasks fa-fw"></i> Budget</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a href="#"><i class="fa fa-bar-chart fa-fw"></i> Category</a> | ||||
|                     </li> | ||||
|                     {{-- | ||||
|                     <li> | ||||
|                         <a href="{{route('piggybanks.create.piggybank')}}"><i class="fa fa-envelope-o fa-fw"></i> Piggy bank</a> | ||||
|                     </li> | ||||
|                     --}} | ||||
|                     <li> | ||||
|                         <a href="{{route('recurring.create')}}"><i class="fa fa-rotate-right fa-fw"></i> Recurring transaction</a> | ||||
|                     </li> | ||||
|                     {{-- | ||||
|                     <li> | ||||
|                         <a href="{{route('piggybanks.create.repeated')}}"><i class="fa fa-rotate-left fa-fw"></i> Repeated expense</a> | ||||
|                     </li> | ||||
|                     --}} | ||||
|                 </ul> | ||||
|                 <!-- /.nav-second-level --> | ||||
|             </li> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user