mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-11-04 05:15:39 +00:00 
			
		
		
		
	Varioux fixes and cleaning up.
This commit is contained in:
		@@ -1,9 +1,6 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Firefly\Storage\Account\AccountRepositoryInterface as ARI;
 | 
					use Firefly\Helper\Controllers\JsonInterface as JI;
 | 
				
			||||||
use Firefly\Storage\Budget\BudgetRepositoryInterface as Bud;
 | 
					 | 
				
			||||||
use Firefly\Storage\Category\CategoryRepositoryInterface as Cat;
 | 
					 | 
				
			||||||
use Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface as TJRI;
 | 
					 | 
				
			||||||
use Illuminate\Support\Collection;
 | 
					use Illuminate\Support\Collection;
 | 
				
			||||||
use LaravelBook\Ardent\Builder;
 | 
					use LaravelBook\Ardent\Builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,226 +11,60 @@ use LaravelBook\Ardent\Builder;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
class JsonController extends BaseController
 | 
					class JsonController extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    protected $_accounts;
 | 
					    /** @var \Firefly\Helper\Controllers\JsonInterface $helper */
 | 
				
			||||||
    protected $_categories;
 | 
					    protected $helper;
 | 
				
			||||||
    protected $_budgets;
 | 
					 | 
				
			||||||
    /** @var TJRI $_journals */
 | 
					 | 
				
			||||||
    protected $_journals;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    public function __construct(JI $helper)
 | 
				
			||||||
     * @param ARI  $accounts
 | 
					 | 
				
			||||||
     * @param Cat  $categories
 | 
					 | 
				
			||||||
     * @param Bud  $budgets
 | 
					 | 
				
			||||||
     * @param TJRI $journals
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function __construct(ARI $accounts, Cat $categories, Bud $budgets, TJRI $journals)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->_accounts   = $accounts;
 | 
					        $this->helper = $helper;
 | 
				
			||||||
        $this->_categories = $categories;
 | 
					 | 
				
			||||||
        $this->_budgets    = $budgets;
 | 
					 | 
				
			||||||
        $this->_journals   = $journals;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function revenue()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $parameters                     = $this->_datatableParameters();
 | 
					 | 
				
			||||||
        $parameters['transactionTypes'] = ['Deposit'];
 | 
					 | 
				
			||||||
        $parameters['amount']           = 'positive';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $query = $this->_datatableQuery($parameters);
 | 
					 | 
				
			||||||
        $resultSet = $this->_datatableResultset($parameters, $query);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Build return data:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (Input::get('debug') == 'true') {
 | 
					 | 
				
			||||||
            echo '<pre>';
 | 
					 | 
				
			||||||
            print_r($parameters);
 | 
					 | 
				
			||||||
            echo '<hr>';
 | 
					 | 
				
			||||||
            print_r($resultSet);
 | 
					 | 
				
			||||||
            return '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return Response::json($resultSet);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns a list of categories.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\JsonResponse
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function transfers()
 | 
					    public function categories()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $parameters                     = $this->_datatableParameters();
 | 
					        /** @var \Firefly\Storage\Category\EloquentCategoryRepository $categories */
 | 
				
			||||||
        $parameters['transactionTypes'] = ['Transfer'];
 | 
					        $categories = App::make('Firefly\Storage\Category\CategoryRepositoryInterface');
 | 
				
			||||||
        $parameters['amount']           = 'positive';
 | 
					        $list       = $categories->get();
 | 
				
			||||||
 | 
					        $return     = [];
 | 
				
			||||||
        $query = $this->_datatableQuery($parameters);
 | 
					        foreach ($list as $entry) {
 | 
				
			||||||
        $resultSet = $this->_datatableResultset($parameters, $query);
 | 
					            $return[] = $entry->name;
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Build return data:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (Input::get('debug') == 'true') {
 | 
					 | 
				
			||||||
            echo '<pre>';
 | 
					 | 
				
			||||||
            print_r($parameters);
 | 
					 | 
				
			||||||
            echo '<hr>';
 | 
					 | 
				
			||||||
            print_r($resultSet);
 | 
					 | 
				
			||||||
            return '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return Response::json($resultSet);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Response::json($return);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @return array
 | 
					     * Returns a JSON list of all beneficiaries.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\JsonResponse
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected function _datatableParameters()
 | 
					    public function expenseAccounts()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /*
 | 
					        /** @var \Firefly\Storage\Account\EloquentAccountRepository $accounts */
 | 
				
			||||||
         * Process all parameters!
 | 
					        $accounts = App::make('Firefly\Storage\Account\AccountRepositoryInterface');
 | 
				
			||||||
         */
 | 
					        $list     = $accounts->getOfTypes(['Expense account', 'Beneficiary account']);
 | 
				
			||||||
        $parameters = [
 | 
					        $return   = [];
 | 
				
			||||||
            'start'  => intval(Input::get('start')),
 | 
					        foreach ($list as $entry) {
 | 
				
			||||||
            'length' => intval(Input::get('length')) < 0 ? 100000 : intval(Input::get('length')),
 | 
					            $return[] = $entry->name;
 | 
				
			||||||
            'draw'   => intval(Input::get('draw')),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Columns:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if (!is_null(Input::get('columns')) && is_array(Input::get('columns'))) {
 | 
					 | 
				
			||||||
            foreach (Input::get('columns') as $column) {
 | 
					 | 
				
			||||||
                $parameters['columns'][] = [
 | 
					 | 
				
			||||||
                    'data'       => $column['data'],
 | 
					 | 
				
			||||||
                    'name'       => $column['name'],
 | 
					 | 
				
			||||||
                    'searchable' => $column['searchable'] == 'true' ? true : false,
 | 
					 | 
				
			||||||
                    'orderable'  => $column['orderable'] == 'true' ? true : false,
 | 
					 | 
				
			||||||
                    'search'     => [
 | 
					 | 
				
			||||||
                        'value' => $column['search']['value'],
 | 
					 | 
				
			||||||
                        'regex' => $column['search']['regex'] == 'true' ? true : false,
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                ];
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Response::json($return);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Sorting.
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        $parameters['orderOnAccount'] = false;
 | 
					 | 
				
			||||||
        if (!is_null(Input::get('order')) && is_array(Input::get('order'))) {
 | 
					 | 
				
			||||||
            foreach (Input::get('order') as $order) {
 | 
					 | 
				
			||||||
                $columnIndex           = intval($order['column']);
 | 
					 | 
				
			||||||
                $columnName            = $parameters['columns'][$columnIndex]['name'];
 | 
					 | 
				
			||||||
                $parameters['order'][] = [
 | 
					 | 
				
			||||||
                    'name' => $columnName,
 | 
					 | 
				
			||||||
                    'dir'  => strtoupper($order['dir'])
 | 
					 | 
				
			||||||
                ];
 | 
					 | 
				
			||||||
                if ($columnName == 'to' || $columnName == 'from') {
 | 
					 | 
				
			||||||
                    $parameters['orderOnAccount'] = true;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Search parameters:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if (!is_null(Input::get('search')) && is_array(Input::get('search'))) {
 | 
					 | 
				
			||||||
            $search               = Input::get('search');
 | 
					 | 
				
			||||||
            $parameters['search'] = [
 | 
					 | 
				
			||||||
                'value' => $search['value'],
 | 
					 | 
				
			||||||
                'regex' => $search['regex'] == 'true' ? true : false
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return $parameters;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param array $parameters
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return Builder
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected function _datatableQuery(array $parameters)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * We need the following vars to fine tune the query:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if ($parameters['amount'] == 'negative') {
 | 
					 | 
				
			||||||
            $operator        = '<';
 | 
					 | 
				
			||||||
            $operatorNegated = '>';
 | 
					 | 
				
			||||||
            $function        = 'lessThan';
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            $operator        = '>';
 | 
					 | 
				
			||||||
            $operatorNegated = '<';
 | 
					 | 
				
			||||||
            $function        = 'moreThan';
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Build query:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        $query = \TransactionJournal::transactionTypes($parameters['transactionTypes'])->withRelevantData();
 | 
					 | 
				
			||||||
        $query->where('completed',1);
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * This is complex. Join `transactions` twice, once for the "to" account and once for the
 | 
					 | 
				
			||||||
         * "from" account. Then get the amount from one of these (depends on type).
 | 
					 | 
				
			||||||
         *
 | 
					 | 
				
			||||||
         * Only need to do this when there's a sort order for "from" or "to".
 | 
					 | 
				
			||||||
         *
 | 
					 | 
				
			||||||
         * Also need the table prefix for this to work.
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if ($parameters['orderOnAccount'] === true) {
 | 
					 | 
				
			||||||
            $connection = \Config::get('database.default');
 | 
					 | 
				
			||||||
            $prefix     = \Config::get('database.connections.' . $connection . '.prefix');
 | 
					 | 
				
			||||||
            // left join first table for "from" account:
 | 
					 | 
				
			||||||
            $query->leftJoin(
 | 
					 | 
				
			||||||
                'transactions AS ' . $prefix . 't1', function ($join) use ($operator) {
 | 
					 | 
				
			||||||
                    $join->on('t1.transaction_journal_id', '=', 'transaction_journals.id')
 | 
					 | 
				
			||||||
                        ->on('t1.amount', $operator, \DB::Raw(0));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            // left join second table for "to" account:
 | 
					 | 
				
			||||||
            $query->leftJoin(
 | 
					 | 
				
			||||||
                'transactions AS ' . $prefix . 't2', function ($join) use ($operatorNegated) {
 | 
					 | 
				
			||||||
                    $join->on('t2.transaction_journal_id', '=', 'transaction_journals.id')
 | 
					 | 
				
			||||||
                        ->on('t2.amount', $operatorNegated, \DB::Raw(0));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // also join accounts twice to get the account's name, which we need for sorting.
 | 
					 | 
				
			||||||
            $query->leftJoin('accounts as ' . $prefix . 'a1', 'a1.id', '=', 't1.account_id');
 | 
					 | 
				
			||||||
            $query->leftJoin('accounts as ' . $prefix . 'a2', 'a2.id', '=', 't2.account_id');
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            // less complex
 | 
					 | 
				
			||||||
            $query->$function(0);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Add sort parameters to query:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if (isset($parameters['order']) && count($parameters['order']) > 0) {
 | 
					 | 
				
			||||||
            foreach ($parameters['order'] as $order) {
 | 
					 | 
				
			||||||
                $query->orderBy($order['name'], $order['dir']);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            $query->defaultSorting();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return $query;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns a list of transactions, expenses only, using the given parameters.
 | 
					     * Returns a list of transactions, expenses only, using the given parameters.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\JsonResponse
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function expenses()
 | 
					    public function expenses()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -241,7 +72,7 @@ class JsonController extends BaseController
 | 
				
			|||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Gets most parameters from the Input::all() array:
 | 
					         * Gets most parameters from the Input::all() array:
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        $parameters = $this->_datatableParameters();
 | 
					        $parameters = $this->helper->dataTableParameters();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Add some more parameters to fine tune the query:
 | 
					         * Add some more parameters to fine tune the query:
 | 
				
			||||||
@@ -252,136 +83,57 @@ class JsonController extends BaseController
 | 
				
			|||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Get the query:
 | 
					         * Get the query:
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        $query = $this->_datatableQuery($parameters);
 | 
					        $query = $this->helper->journalQuery($parameters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Build result set:
 | 
					         * Build result set:
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        $resultSet = $this->_datatableResultset($parameters, $query);
 | 
					        $resultSet = $this->helper->journalDataset($parameters, $query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Build return data:
 | 
					         * Build return data:
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (Input::get('debug') == 'true') {
 | 
					 | 
				
			||||||
            echo '<pre>';
 | 
					 | 
				
			||||||
            print_r($parameters);
 | 
					 | 
				
			||||||
            echo '<hr>';
 | 
					 | 
				
			||||||
            print_r($resultSet);
 | 
					 | 
				
			||||||
            return '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
        return Response::json($resultSet);
 | 
					        return Response::json($resultSet);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function _datatableResultset(array $parameters, Builder $query)
 | 
					    public function recurring()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /*
 | 
					        $parameters = $this->helper->dataTableParameters();
 | 
				
			||||||
         * Count query:
 | 
					        $query = $this->helper->recurringTransactionsQuery($parameters);
 | 
				
			||||||
         */
 | 
					        $resultSet = $this->helper->recurringTransactionsDataset($parameters, $query);
 | 
				
			||||||
        $count = $query->count();
 | 
					        return Response::json($resultSet);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Update the selection:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $query->take($parameters['length']);
 | 
					 | 
				
			||||||
        $query->skip($parameters['start']);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Input search parameters:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        $filtered = $count;
 | 
					 | 
				
			||||||
        if(strlen($parameters['search']['value']) > 0) {
 | 
					 | 
				
			||||||
            $query->where('transaction_journals.description','LIKE','%'.e($parameters['search']['value']).'%');
 | 
					 | 
				
			||||||
            $filtered = $query->count();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Build return array:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        $data = [
 | 
					 | 
				
			||||||
            'draw'            => $parameters['draw'],
 | 
					 | 
				
			||||||
            'recordsTotal'    => $count,
 | 
					 | 
				
			||||||
            'recordsFiltered' => $filtered,
 | 
					 | 
				
			||||||
            'data'            => [],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Get paginated result set:
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if ($parameters['orderOnAccount'] === true) {
 | 
					 | 
				
			||||||
            /** @var Collection $set */
 | 
					 | 
				
			||||||
            $set = $query->get(
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'transaction_journals.*',
 | 
					 | 
				
			||||||
                    't1.amount',
 | 
					 | 
				
			||||||
                    't1.account_id AS from_id',
 | 
					 | 
				
			||||||
                    'a1.name AS from',
 | 
					 | 
				
			||||||
                    't2.account_id AS to_id',
 | 
					 | 
				
			||||||
                    'a2.name AS to',
 | 
					 | 
				
			||||||
                ]
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            /** @var Collection $set */
 | 
					 | 
				
			||||||
            $set = $query->get(
 | 
					 | 
				
			||||||
                [
 | 
					 | 
				
			||||||
                    'transaction_journals.*',
 | 
					 | 
				
			||||||
                    'transactions.amount',
 | 
					 | 
				
			||||||
                ]
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Loop set and create entries to return.
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        foreach ($set as $entry) {
 | 
					 | 
				
			||||||
            $from           = $entry->transactions[0]->account;
 | 
					 | 
				
			||||||
            $to             = $entry->transactions[1]->account;
 | 
					 | 
				
			||||||
            $data['data'][] = [
 | 
					 | 
				
			||||||
                'date'        => $entry->date->format('j F Y'),
 | 
					 | 
				
			||||||
                'description' => [
 | 
					 | 
				
			||||||
                    'description' => $entry->description,
 | 
					 | 
				
			||||||
                    'url'         => route('transactions.show', $entry->id)
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
                'amount'      => floatval($entry->amount),
 | 
					 | 
				
			||||||
                'from'        => ['name' => $from->name, 'url' => route('accounts.show', $from->id)],
 | 
					 | 
				
			||||||
                'to'          => ['name' => $to->name, 'url' => route('accounts.show', $to->id)],
 | 
					 | 
				
			||||||
                'id'          => [
 | 
					 | 
				
			||||||
                    'edit'   => route('transactions.edit', $entry->id),
 | 
					 | 
				
			||||||
                    'delete' => route('transactions.delete', $entry->id)
 | 
					 | 
				
			||||||
                ]
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return $data;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns a JSON list of all beneficiaries.
 | 
					     * @return \Illuminate\Http\JsonResponse|string
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function expenseAccounts()
 | 
					    public function revenue()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $list   = $this->_accounts->getOfTypes(['Expense account', 'Beneficiary account']);
 | 
					        $parameters                     = $this->helper->dataTableParameters();
 | 
				
			||||||
        $return = [];
 | 
					        $parameters['transactionTypes'] = ['Deposit'];
 | 
				
			||||||
        foreach ($list as $entry) {
 | 
					        $parameters['amount']           = 'positive';
 | 
				
			||||||
            $return[] = $entry->name;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return Response::json($return);
 | 
					        $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.
 | 
					     * Returns a JSON list of all revenue accounts.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\JsonResponse
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function revenueAccounts()
 | 
					    public function revenueAccounts()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $list   = $this->_accounts->getOfTypes(['Revenue account']);
 | 
					        /** @var \Firefly\Storage\Account\EloquentAccountRepository $accounts */
 | 
				
			||||||
 | 
					        $accounts = App::make('Firefly\Storage\Account\AccountRepositoryInterface');
 | 
				
			||||||
 | 
					        $list     = $accounts->getOfTypes(['Revenue account']);
 | 
				
			||||||
        $return   = [];
 | 
					        $return   = [];
 | 
				
			||||||
        foreach ($list as $entry) {
 | 
					        foreach ($list as $entry) {
 | 
				
			||||||
            $return[] = $entry->name;
 | 
					            $return[] = $entry->name;
 | 
				
			||||||
@@ -392,18 +144,23 @@ class JsonController extends BaseController
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Responds some JSON for typeahead fields.
 | 
					     * Returns a list of all transfers.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\JsonResponse
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function categories()
 | 
					    public function transfers()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $list   = $this->_categories->get();
 | 
					        $parameters                     = $this->helper->dataTableParameters();
 | 
				
			||||||
        $return = [];
 | 
					        $parameters['transactionTypes'] = ['Transfer'];
 | 
				
			||||||
        foreach ($list as $entry) {
 | 
					        $parameters['amount']           = 'positive';
 | 
				
			||||||
            $return[] = $entry->name;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return Response::json($return);
 | 
					        $query     = $this->helper->journalQuery($parameters);
 | 
				
			||||||
 | 
					        $resultSet = $this->helper->journalDataset($parameters, $query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Build return data:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        return Response::json($resultSet);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Firefly\Exception\FireflyException;
 | 
				
			||||||
use Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface as RTR;
 | 
					use Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface as RTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -51,7 +52,7 @@ class RecurringController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function destroy(RecurringTransaction $recurringTransaction)
 | 
					    public function destroy(RecurringTransaction $recurringTransaction)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Event::fire('recurring.destroy', [$recurringTransaction]);
 | 
					        //Event::fire('recurring.destroy', [$recurringTransaction]);
 | 
				
			||||||
        $result = $this->_repository->destroy($recurringTransaction);
 | 
					        $result = $this->_repository->destroy($recurringTransaction);
 | 
				
			||||||
        if ($result === true) {
 | 
					        if ($result === true) {
 | 
				
			||||||
            Session::flash('success', 'The recurring transaction was deleted.');
 | 
					            Session::flash('success', 'The recurring transaction was deleted.');
 | 
				
			||||||
@@ -84,11 +85,7 @@ class RecurringController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function index()
 | 
					    public function index()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $list = $this->_repository->get();
 | 
					        return View::make('recurring.index');
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return View::make('recurring.index')->with('list', $list);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -106,10 +103,18 @@ class RecurringController extends BaseController
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function store()
 | 
					    public function store()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (Input::get('post_submit_action')) {
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                throw new FireflyException('Method ' . Input::get('post_submit_action') . ' not implemented yet.');
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurringTransaction = $this->_repository->store(Input::all());
 | 
					        $recurringTransaction = $this->_repository->store(Input::all());
 | 
				
			||||||
        if ($recurringTransaction->validate()) {
 | 
					
 | 
				
			||||||
 | 
					        if ($recurringTransaction->errors()->count() == 0) {
 | 
				
			||||||
            Session::flash('success', 'Recurring transaction "' . $recurringTransaction->name . '" saved!');
 | 
					            Session::flash('success', 'Recurring transaction "' . $recurringTransaction->name . '" saved!');
 | 
				
			||||||
            Event::fire('recurring.store', [$recurringTransaction]);
 | 
					            //Event::fire('recurring.store', [$recurringTransaction]);
 | 
				
			||||||
            if (Input::get('create') == '1') {
 | 
					            if (Input::get('create') == '1') {
 | 
				
			||||||
                return Redirect::route('recurring.create')->withInput();
 | 
					                return Redirect::route('recurring.create')->withInput();
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
@@ -135,7 +140,7 @@ class RecurringController extends BaseController
 | 
				
			|||||||
        $recurringTransaction = $this->_repository->update($recurringTransaction, Input::all());
 | 
					        $recurringTransaction = $this->_repository->update($recurringTransaction, Input::all());
 | 
				
			||||||
        if ($recurringTransaction->errors()->count() == 0) {
 | 
					        if ($recurringTransaction->errors()->count() == 0) {
 | 
				
			||||||
            Session::flash('success', 'The recurring transaction has been updated.');
 | 
					            Session::flash('success', 'The recurring transaction has been updated.');
 | 
				
			||||||
            Event::fire('recurring.update', [$recurringTransaction]);
 | 
					            //Event::fire('recurring.update', [$recurringTransaction]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return Redirect::route('recurring.index');
 | 
					            return Redirect::route('recurring.index');
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										369
									
								
								app/lib/Firefly/Helper/Controllers/Json.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										369
									
								
								app/lib/Firefly/Helper/Controllers/Json.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,369 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Created by PhpStorm.
 | 
				
			||||||
 | 
					 * User: sander
 | 
				
			||||||
 | 
					 * Date: 27/09/14
 | 
				
			||||||
 | 
					 * Time: 07:39
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Firefly\Helper\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use LaravelBook\Ardent\Builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class Json
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @package Firefly\Helper\Controllers
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Json implements JsonInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Grabs all the parameters entered by the DataTables JQuery plugin and creates
 | 
				
			||||||
 | 
					     * a nice array to be used by the other methods. It's also cleaning up and what-not.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function dataTableParameters()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Process all parameters!
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if (intval(\Input::get('length')) < 0) {
 | 
				
			||||||
 | 
					            $length = 10000; // we get them all if no length is defined.
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $length = intval(\Input::get('length'));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $parameters = [
 | 
				
			||||||
 | 
					            'start'  => intval(\Input::get('start')),
 | 
				
			||||||
 | 
					            'length' => $length,
 | 
				
			||||||
 | 
					            'draw'   => intval(\Input::get('draw')),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Columns:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if (!is_null(\Input::get('columns')) && is_array(\Input::get('columns'))) {
 | 
				
			||||||
 | 
					            foreach (\Input::get('columns') as $column) {
 | 
				
			||||||
 | 
					                $parameters['columns'][] = [
 | 
				
			||||||
 | 
					                    'data'       => $column['data'],
 | 
				
			||||||
 | 
					                    'name'       => $column['name'],
 | 
				
			||||||
 | 
					                    'searchable' => $column['searchable'] == 'true' ? true : false,
 | 
				
			||||||
 | 
					                    'orderable'  => $column['orderable'] == 'true' ? true : false,
 | 
				
			||||||
 | 
					                    'search'     => [
 | 
				
			||||||
 | 
					                        'value' => $column['search']['value'],
 | 
				
			||||||
 | 
					                        'regex' => $column['search']['regex'] == 'true' ? true : false,
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Sorting.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        $parameters['orderOnAccount'] = false;
 | 
				
			||||||
 | 
					        if (!is_null(\Input::get('order')) && is_array(\Input::get('order'))) {
 | 
				
			||||||
 | 
					            foreach (\Input::get('order') as $order) {
 | 
				
			||||||
 | 
					                $columnIndex           = intval($order['column']);
 | 
				
			||||||
 | 
					                $columnName            = $parameters['columns'][$columnIndex]['name'];
 | 
				
			||||||
 | 
					                $parameters['order'][] = [
 | 
				
			||||||
 | 
					                    'name' => $columnName,
 | 
				
			||||||
 | 
					                    'dir'  => strtoupper($order['dir'])
 | 
				
			||||||
 | 
					                ];
 | 
				
			||||||
 | 
					                if ($columnName == 'to' || $columnName == 'from') {
 | 
				
			||||||
 | 
					                    $parameters['orderOnAccount'] = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Search parameters:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        $parameters['search'] = [
 | 
				
			||||||
 | 
					            'value' => '',
 | 
				
			||||||
 | 
					            'regex' => false
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        if (!is_null(\Input::get('search')) && is_array(\Input::get('search'))) {
 | 
				
			||||||
 | 
					            $search               = \Input::get('search');
 | 
				
			||||||
 | 
					            $parameters['search'] = [
 | 
				
			||||||
 | 
					                'value' => $search['value'],
 | 
				
			||||||
 | 
					                'regex' => $search['regex'] == 'true' ? true : false
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $parameters;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Do some sorting, counting and ordering on the query and return a nicely formatted array
 | 
				
			||||||
 | 
					     * that can be used by the DataTables JQuery plugin.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param array   $parameters
 | 
				
			||||||
 | 
					     * @param Builder $query
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function journalDataset(array $parameters, Builder $query)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Count query:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        $count = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Update the selection:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query->take($parameters['length']);
 | 
				
			||||||
 | 
					        if ($parameters['start'] > 0) {
 | 
				
			||||||
 | 
					            $query->skip($parameters['start']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Input search parameters:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        $filtered = $count;
 | 
				
			||||||
 | 
					        if (strlen($parameters['search']['value']) > 0) {
 | 
				
			||||||
 | 
					            $query->where('transaction_journals.description', 'LIKE', '%' . e($parameters['search']['value']) . '%');
 | 
				
			||||||
 | 
					            $filtered = $query->count();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Build return array:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'draw'            => $parameters['draw'],
 | 
				
			||||||
 | 
					            'recordsTotal'    => $count,
 | 
				
			||||||
 | 
					            'recordsFiltered' => $filtered,
 | 
				
			||||||
 | 
					            'data'            => [],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Get paginated result set:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if ($parameters['orderOnAccount'] === true) {
 | 
				
			||||||
 | 
					            /** @var Collection $set */
 | 
				
			||||||
 | 
					            $set = $query->get(
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'transaction_journals.*',
 | 
				
			||||||
 | 
					                    't1.amount',
 | 
				
			||||||
 | 
					                    't1.account_id AS from_id',
 | 
				
			||||||
 | 
					                    'a1.name AS from',
 | 
				
			||||||
 | 
					                    't2.account_id AS to_id',
 | 
				
			||||||
 | 
					                    'a2.name AS to',
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            /** @var Collection $set */
 | 
				
			||||||
 | 
					            $set = $query->get(
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    'transaction_journals.*',
 | 
				
			||||||
 | 
					                    'transactions.amount',
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Loop set and create entries to return.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        foreach ($set as $entry) {
 | 
				
			||||||
 | 
					            $from           = $entry->transactions[0]->account;
 | 
				
			||||||
 | 
					            $to             = $entry->transactions[1]->account;
 | 
				
			||||||
 | 
					            $data['data'][] = [
 | 
				
			||||||
 | 
					                'date'        => $entry->date->format('j F Y'),
 | 
				
			||||||
 | 
					                'description' => [
 | 
				
			||||||
 | 
					                    'description' => $entry->description,
 | 
				
			||||||
 | 
					                    'url'         => route('transactions.show', $entry->id)
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                'amount'      => floatval($entry->amount),
 | 
				
			||||||
 | 
					                'from'        => ['name' => $from->name, 'url' => route('accounts.show', $from->id)],
 | 
				
			||||||
 | 
					                'to'          => ['name' => $to->name, 'url' => route('accounts.show', $to->id)],
 | 
				
			||||||
 | 
					                'id'          => [
 | 
				
			||||||
 | 
					                    'edit'   => route('transactions.edit', $entry->id),
 | 
				
			||||||
 | 
					                    'delete' => route('transactions.delete', $entry->id)
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Builds most of the query required to grab transaction journals from the database.
 | 
				
			||||||
 | 
					     * This is useful because all three pages showing different kinds of transactions use
 | 
				
			||||||
 | 
					     * the exact same query with only slight differences.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param array $parameters
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function journalQuery(array $parameters)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * We need the following vars to fine tune the query:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if ($parameters['amount'] == 'negative') {
 | 
				
			||||||
 | 
					            $operator        = '<';
 | 
				
			||||||
 | 
					            $operatorNegated = '>';
 | 
				
			||||||
 | 
					            $function        = 'lessThan';
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $operator        = '>';
 | 
				
			||||||
 | 
					            $operatorNegated = '<';
 | 
				
			||||||
 | 
					            $function        = 'moreThan';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Build query:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        $query = \TransactionJournal::transactionTypes($parameters['transactionTypes'])->withRelevantData();
 | 
				
			||||||
 | 
					        $query->where('user_id', \Auth::user()->id);
 | 
				
			||||||
 | 
					        $query->where('completed', 1);
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * This is complex. Join `transactions` twice, once for the "to" account and once for the
 | 
				
			||||||
 | 
					         * "from" account. Then get the amount from one of these (depends on type).
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * Only need to do this when there's a sort order for "from" or "to".
 | 
				
			||||||
 | 
					         *
 | 
				
			||||||
 | 
					         * Also need the table prefix for this to work.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if ($parameters['orderOnAccount'] === true) {
 | 
				
			||||||
 | 
					            $connection = \Config::get('database.default');
 | 
				
			||||||
 | 
					            $prefix     = \Config::get('database.connections.' . $connection . '.prefix');
 | 
				
			||||||
 | 
					            // left join first table for "from" account:
 | 
				
			||||||
 | 
					            $query->leftJoin(
 | 
				
			||||||
 | 
					                'transactions AS ' . $prefix . 't1', function ($join) use ($operator) {
 | 
				
			||||||
 | 
					                    $join->on('t1.transaction_journal_id', '=', 'transaction_journals.id')
 | 
				
			||||||
 | 
					                        ->on('t1.amount', $operator, \DB::Raw(0));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            // left join second table for "to" account:
 | 
				
			||||||
 | 
					            $query->leftJoin(
 | 
				
			||||||
 | 
					                'transactions AS ' . $prefix . 't2', function ($join) use ($operatorNegated) {
 | 
				
			||||||
 | 
					                    $join->on('t2.transaction_journal_id', '=', 'transaction_journals.id')
 | 
				
			||||||
 | 
					                        ->on('t2.amount', $operatorNegated, \DB::Raw(0));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // also join accounts twice to get the account's name, which we need for sorting.
 | 
				
			||||||
 | 
					            $query->leftJoin('accounts as ' . $prefix . 'a1', 'a1.id', '=', 't1.account_id');
 | 
				
			||||||
 | 
					            $query->leftJoin('accounts as ' . $prefix . 'a2', 'a2.id', '=', 't2.account_id');
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // less complex
 | 
				
			||||||
 | 
					            $query->$function(0);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Add sort parameters to query:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        if (isset($parameters['order']) && count($parameters['order']) > 0) {
 | 
				
			||||||
 | 
					            foreach ($parameters['order'] as $order) {
 | 
				
			||||||
 | 
					                $query->orderBy($order['name'], $order['dir']);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $query->defaultSorting();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $query;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Do some sorting, counting and ordering on the query and return a nicely formatted array
 | 
				
			||||||
 | 
					     * that can be used by the DataTables JQuery plugin.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param array   $parameters
 | 
				
			||||||
 | 
					     * @param Builder $query
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function recurringTransactionsDataset(array $parameters, Builder $query)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					 * Count query:
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					        $count = $query->count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Update the selection:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $query->take($parameters['length']);
 | 
				
			||||||
 | 
					        if ($parameters['start'] > 0) {
 | 
				
			||||||
 | 
					            $query->skip($parameters['start']);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Input search parameters:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        $filtered = $count;
 | 
				
			||||||
 | 
					        if (strlen($parameters['search']['value']) > 0) {
 | 
				
			||||||
 | 
					            $query->where('recurring_transactions.description', 'LIKE', '%' . e($parameters['search']['value']) . '%');
 | 
				
			||||||
 | 
					            $filtered = $query->count();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Build return array:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'draw'            => $parameters['draw'],
 | 
				
			||||||
 | 
					            'recordsTotal'    => $count,
 | 
				
			||||||
 | 
					            'recordsFiltered' => $filtered,
 | 
				
			||||||
 | 
					            'data'            => [],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Get paginated result set:
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        /** @var Collection $set */
 | 
				
			||||||
 | 
					        $set = $query->get(
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					                'recurring_transactions.*',
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         * Loop set and create entries to return.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        foreach ($set as $entry) {
 | 
				
			||||||
 | 
					            $data['data'][] = [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                'name'        => ['name' => $entry->name,'url' => route('recurring.show',$entry->id)],
 | 
				
			||||||
 | 
					                'match'       => explode(' ',$entry->match),
 | 
				
			||||||
 | 
					                'amount_max'  => floatval($entry->amount_max),
 | 
				
			||||||
 | 
					                'amount_min'  => floatval($entry->amount_min),
 | 
				
			||||||
 | 
					                'date'        => $entry->date->format('j F Y'),
 | 
				
			||||||
 | 
					                'active'      => intval($entry->active),
 | 
				
			||||||
 | 
					                'automatch'   => intval($entry->automatch),
 | 
				
			||||||
 | 
					                'repeat_freq' => $entry->repeat_freq,
 | 
				
			||||||
 | 
					                'id'          => [
 | 
				
			||||||
 | 
					                    'edit'   => route('recurring.edit', $entry->id),
 | 
				
			||||||
 | 
					                    'delete' => route('recurring.delete', $entry->id)
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a query that will pick up all recurring transactions from the database.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param array $parameters
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function recurringTransactionsQuery(array $parameters)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $query = \RecurringTransaction::where('user_id', \Auth::user()->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (isset($parameters['order']) && count($parameters['order']) > 0) {
 | 
				
			||||||
 | 
					            foreach ($parameters['order'] as $order) {
 | 
				
			||||||
 | 
					                $query->orderBy($order['name'], $order['dir']);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $query->orderBy('name', 'ASC');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return $query;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					} 
 | 
				
			||||||
							
								
								
									
										64
									
								
								app/lib/Firefly/Helper/Controllers/JsonInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								app/lib/Firefly/Helper/Controllers/JsonInterface.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Firefly\Helper\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use LaravelBook\Ardent\Builder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Interface JsonInterface
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @package Firefly\Helper\Controllers
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					interface JsonInterface
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Grabs all the parameters entered by the DataTables JQuery plugin and creates
 | 
				
			||||||
 | 
					     * a nice array to be used by the other methods. It's also cleaning up and what-not.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function dataTableParameters();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Do some sorting, counting and ordering on the query and return a nicely formatted array
 | 
				
			||||||
 | 
					     * that can be used by the DataTables JQuery plugin.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param array   $parameters
 | 
				
			||||||
 | 
					     * @param Builder $query
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function journalDataset(array $parameters, Builder $query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Builds most of the query required to grab transaction journals from the database.
 | 
				
			||||||
 | 
					     * This is useful because all three pages showing different kinds of transactions use
 | 
				
			||||||
 | 
					     * the exact same query with only slight differences.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param array $parameters
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function journalQuery(array $parameters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Do some sorting, counting and ordering on the query and return a nicely formatted array
 | 
				
			||||||
 | 
					     * that can be used by the DataTables JQuery plugin.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param array   $parameters
 | 
				
			||||||
 | 
					     * @param Builder $query
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function recurringTransactionsDataset(array $parameters, Builder $query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a query that will pick up all recurring transactions from the database.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param array $parameters
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Builder
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function recurringTransactionsQuery(array $parameters);
 | 
				
			||||||
 | 
					} 
 | 
				
			||||||
@@ -247,7 +247,8 @@ class Transaction implements TransactionInterface
 | 
				
			|||||||
        /*
 | 
					        /*
 | 
				
			||||||
         * Add a custom error when they are the same.
 | 
					         * Add a custom error when they are the same.
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        if ($to->id == $from->id) {
 | 
					        if ($to->id ==
 | 
				
			||||||
 | 
					            $from->id) {
 | 
				
			||||||
            $bag = new MessageBag;
 | 
					            $bag = new MessageBag;
 | 
				
			||||||
            $bag->add('account_from_id', 'The account from cannot be the same as the account to.');
 | 
					            $bag->add('account_from_id', 'The account from cannot be the same as the account to.');
 | 
				
			||||||
            return $bag;
 | 
					            return $bag;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,11 @@ class HelperServiceProvider extends ServiceProvider
 | 
				
			|||||||
            'Firefly\Helper\Controllers\Chart'
 | 
					            'Firefly\Helper\Controllers\Chart'
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->app->bind(
 | 
				
			||||||
 | 
					            'Firefly\Helper\Controllers\JsonInterface',
 | 
				
			||||||
 | 
					            'Firefly\Helper\Controllers\Json'
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->app->bind(
 | 
					        $this->app->bind(
 | 
				
			||||||
            'Firefly\Helper\Controllers\SearchInterface',
 | 
					            'Firefly\Helper\Controllers\SearchInterface',
 | 
				
			||||||
            'Firefly\Helper\Controllers\Search'
 | 
					            'Firefly\Helper\Controllers\Search'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,26 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo
 | 
				
			|||||||
        $this->_user = \Auth::user();
 | 
					        $this->_user = \Auth::user();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param \RecurringTransaction $recurringTransaction
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return bool|mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function destroy(\RecurringTransaction $recurringTransaction)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $recurringTransaction->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function get()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->_user->recurringtransactions()->get();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @param Job   $job
 | 
					     * @param Job   $job
 | 
				
			||||||
     * @param array $payload
 | 
					     * @param array $payload
 | 
				
			||||||
@@ -115,25 +135,43 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function store($data)
 | 
					    public function store($data)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $recurringTransaction = new \RecurringTransaction;
 | 
					        $recurringTransaction = new \RecurringTransaction(
 | 
				
			||||||
        $recurringTransaction->user()->associate($this->_user);
 | 
					            [
 | 
				
			||||||
        $recurringTransaction->name       = $data['name'];
 | 
					                'user_id'     => $this->_user->id,
 | 
				
			||||||
        $recurringTransaction->match      = join(' ', explode(',', $data['match']));
 | 
					                'name'        => $data['name'],
 | 
				
			||||||
        $recurringTransaction->amount_max = floatval($data['amount_max']);
 | 
					                'match'       => join(' ', explode(',', $data['match'])),
 | 
				
			||||||
        $recurringTransaction->amount_min = floatval($data['amount_min']);
 | 
					                'amount_max'  => floatval($data['amount_max']),
 | 
				
			||||||
 | 
					                'amount_min'  => floatval($data['amount_min']),
 | 
				
			||||||
 | 
					                'date'        => new Carbon($data['date']),
 | 
				
			||||||
 | 
					                'active'      => isset($data['active']) ? intval($data['active']) : 0,
 | 
				
			||||||
 | 
					                'automatch'   => isset($data['automatch']) ? intval($data['automatch']) : 0,
 | 
				
			||||||
 | 
					                'skip'        => isset($data['skip']) ? intval($data['skip']) : 0,
 | 
				
			||||||
 | 
					                'repeat_freq' => $data['repeat_freq'],
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // both amounts zero:
 | 
					        // both amounts zero?:
 | 
				
			||||||
        if ($recurringTransaction->amount_max == 0 && $recurringTransaction->amount_min == 0) {
 | 
					        if ($recurringTransaction->amount_max == 0 && $recurringTransaction->amount_min == 0) {
 | 
				
			||||||
            $recurringTransaction->errors()->add('amount_max', 'Amount max and min cannot both be zero.');
 | 
					            $recurringTransaction->errors()->add('amount_max', 'Amount max and min cannot both be zero.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return $recurringTransaction;
 | 
					            return $recurringTransaction;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurringTransaction->date        = new Carbon($data['date']);
 | 
					        if ($recurringTransaction->amount_max < $recurringTransaction->amount_min) {
 | 
				
			||||||
        $recurringTransaction->active      = isset($data['active']) ? intval($data['active']) : 0;
 | 
					            $recurringTransaction->errors()->add('amount_max', 'Amount max must be more than amount min.');
 | 
				
			||||||
        $recurringTransaction->automatch   = isset($data['automatch']) ? intval($data['automatch']) : 0;
 | 
					            return $recurringTransaction;
 | 
				
			||||||
        $recurringTransaction->skip        = isset($data['skip']) ? intval($data['skip']) : 0;
 | 
					        }
 | 
				
			||||||
        $recurringTransaction->repeat_freq = $data['repeat_freq'];
 | 
					
 | 
				
			||||||
 | 
					        if ($recurringTransaction->amount_min > $recurringTransaction->amount_max) {
 | 
				
			||||||
 | 
					            $recurringTransaction->errors()->add('amount_max', 'Amount min must be less than amount max.');
 | 
				
			||||||
 | 
					            return $recurringTransaction;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if($recurringTransaction->date < Carbon::now()) {
 | 
				
			||||||
 | 
					            $recurringTransaction->errors()->add('date', 'Must be in the future.');
 | 
				
			||||||
 | 
					            return $recurringTransaction;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($recurringTransaction->validate()) {
 | 
					        if ($recurringTransaction->validate()) {
 | 
				
			||||||
            $recurringTransaction->save();
 | 
					            $recurringTransaction->save();
 | 
				
			||||||
@@ -142,26 +180,6 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo
 | 
				
			|||||||
        return $recurringTransaction;
 | 
					        return $recurringTransaction;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @param \RecurringTransaction $recurringTransaction
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool|mixed
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function destroy(\RecurringTransaction $recurringTransaction)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $recurringTransaction->delete();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * @return mixed
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function get()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $this->_user->recurringtransactions()->get();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @param \RecurringTransaction $recurringTransaction
 | 
					     * @param \RecurringTransaction $recurringTransaction
 | 
				
			||||||
     * @param                       $data
 | 
					     * @param                       $data
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,6 +51,7 @@ class RecurringTransaction extends Ardent
 | 
				
			|||||||
            'skip'        => 'required|between:0,31',
 | 
					            'skip'        => 'required|between:0,31',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $fillable = ['user_id','name','match','amount_min','amount_max','date','repeat_freq','skip','active','automatch'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @return array
 | 
					     * @return array
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -184,6 +184,7 @@ Route::group(['before' => 'auth'], function () {
 | 
				
			|||||||
        Route::get('/json/expenses', ['uses' => 'JsonController@expenses', 'as' => 'json.expenses']);
 | 
					        Route::get('/json/expenses', ['uses' => 'JsonController@expenses', 'as' => 'json.expenses']);
 | 
				
			||||||
        Route::get('/json/revenue', ['uses' => 'JsonController@revenue', 'as' => 'json.revenue']);
 | 
					        Route::get('/json/revenue', ['uses' => 'JsonController@revenue', 'as' => 'json.revenue']);
 | 
				
			||||||
        Route::get('/json/transfers', ['uses' => 'JsonController@transfers', 'as' => 'json.transfers']);
 | 
					        Route::get('/json/transfers', ['uses' => 'JsonController@transfers', 'as' => 'json.transfers']);
 | 
				
			||||||
 | 
					        Route::get('/json/recurring', ['uses' => 'JsonController@recurring', 'as' => 'json.recurring']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // limit controller:
 | 
					        // limit controller:
 | 
				
			||||||
        Route::get('/budgets/limits/create/{budget?}',['uses' => 'LimitController@create','as' => 'budgets.limits.create']);
 | 
					        Route::get('/budgets/limits/create/{budget?}',['uses' => 'LimitController@create','as' => 'budgets.limits.create']);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,20 +1,15 @@
 | 
				
			|||||||
@extends('layouts.default')
 | 
					@extends('layouts.default')
 | 
				
			||||||
@section('content')
 | 
					@section('content')
 | 
				
			||||||
<div class="row">
 | 
					 | 
				
			||||||
    <div class="col-lg-12 col-md-12 col-sm-12">
 | 
					 | 
				
			||||||
        <p class="lead">Use recurring transactions to track repeated expenses</p>
 | 
					 | 
				
			||||||
        <p class="text-info">
 | 
					 | 
				
			||||||
            Bla bla.
 | 
					 | 
				
			||||||
        </p>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{{Form::open(['class' => 'form-horizontal','url' => route('recurring.store')])}}
 | 
					{{Form::open(['class' => 'form-horizontal','url' => route('recurring.store')])}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="row">
 | 
					<div class="row">
 | 
				
			||||||
    <div class="col-lg-6 col-md-12 col-sm-6">
 | 
					    <div class="col-lg-6 col-md-12 col-sm-6">
 | 
				
			||||||
        <h4>Mandatory fields</h4>
 | 
					        <!-- panel for mandatory fields -->
 | 
				
			||||||
 | 
					        <div class="panel panel-primary">
 | 
				
			||||||
 | 
					            <div class="panel-heading">
 | 
				
			||||||
 | 
					                <i class="fa fa-exclamation-circle"></i> Mandatory fields
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="panel-body">
 | 
				
			||||||
                <!-- name -->
 | 
					                <!-- name -->
 | 
				
			||||||
                <div class="form-group">
 | 
					                <div class="form-group">
 | 
				
			||||||
                    <label for="name" class="col-sm-4 control-label">Name</label>
 | 
					                    <label for="name" class="col-sm-4 control-label">Name</label>
 | 
				
			||||||
@@ -22,8 +17,6 @@
 | 
				
			|||||||
                        <input type="text" name="name" class="form-control" id="name" value="{{Input::old('name')}}" placeholder="Name">
 | 
					                        <input type="text" name="name" class="form-control" id="name" value="{{Input::old('name')}}" placeholder="Name">
 | 
				
			||||||
                        @if($errors->has('name'))
 | 
					                        @if($errors->has('name'))
 | 
				
			||||||
                        <p class="text-danger">{{$errors->first('name')}}</p>
 | 
					                        <p class="text-danger">{{$errors->first('name')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">For example: rent, gas, insurance</span>
 | 
					 | 
				
			||||||
                        @endif
 | 
					                        @endif
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
@@ -33,9 +26,6 @@
 | 
				
			|||||||
                        <input type="text" name="match" class="form-control" id="match" value="{{Input::old('match')}}" data-role="tagsinput">
 | 
					                        <input type="text" name="match" class="form-control" id="match" value="{{Input::old('match')}}" data-role="tagsinput">
 | 
				
			||||||
                        @if($errors->has('match'))
 | 
					                        @if($errors->has('match'))
 | 
				
			||||||
                        <p class="text-danger">{{$errors->first('match')}}</p>
 | 
					                        <p class="text-danger">{{$errors->first('match')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">For example: rent, [company name]. All matches need to
 | 
					 | 
				
			||||||
                    be present for the recurring transaction to be recognized. This field is not case-sensitive. <em>Press enter after every match</em></span>
 | 
					 | 
				
			||||||
                        @endif
 | 
					                        @endif
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
@@ -50,9 +40,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                        @if($errors->has('amount_min'))
 | 
					                        @if($errors->has('amount_min'))
 | 
				
			||||||
                            <p class="text-danger">{{$errors->first('amount_min')}}</p>
 | 
					                            <p class="text-danger">{{$errors->first('amount_min')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">Firefly will only include transactions with a higher amount than this. If your rent
 | 
					 | 
				
			||||||
                is usually around € 500,-, enter <code>450</code> to be safe.</span>
 | 
					 | 
				
			||||||
                        @endif
 | 
					                        @endif
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
@@ -67,9 +54,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                        @if($errors->has('amount_max'))
 | 
					                        @if($errors->has('amount_max'))
 | 
				
			||||||
                        <p class="text-danger">{{$errors->first('amount_max')}}</p>
 | 
					                        <p class="text-danger">{{$errors->first('amount_max')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">Firefly will only include transactions with a lower amount than this. If your rent
 | 
					 | 
				
			||||||
                is usually around € 500,-, enter <code>550</code> to be safe.</span>
 | 
					 | 
				
			||||||
                        @endif
 | 
					                        @endif
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
@@ -77,12 +61,10 @@
 | 
				
			|||||||
                <div class="form-group">
 | 
					                <div class="form-group">
 | 
				
			||||||
                    {{ Form::label('date', 'Date', ['class' => 'col-sm-4 control-label'])}}
 | 
					                    {{ Form::label('date', 'Date', ['class' => 'col-sm-4 control-label'])}}
 | 
				
			||||||
                    <div class="col-sm-8">
 | 
					                    <div class="col-sm-8">
 | 
				
			||||||
                {{ Form::input('date','date', Input::old('date') ?: date('Y-m-d'), ['class'
 | 
					                        {{ Form::input('date','date', Input::old('date') ?: Carbon\Carbon::now()->addDay()->format('Y-m-d'), ['class'
 | 
				
			||||||
                        => 'form-control']) }}
 | 
					                        => 'form-control']) }}
 | 
				
			||||||
                        @if($errors->has('date'))
 | 
					                        @if($errors->has('date'))
 | 
				
			||||||
                        <p class="text-danger">{{$errors->first('date')}}</p>
 | 
					                        <p class="text-danger">{{$errors->first('date')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">Select the next date you expect the transaction to occur.</span>
 | 
					 | 
				
			||||||
                        @endif
 | 
					                        @endif
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
@@ -93,16 +75,24 @@
 | 
				
			|||||||
                        {{Form::select('repeat_freq',$periods,Input::old('repeat_freq') ?: 'monthly',['class' => 'form-control'])}}
 | 
					                        {{Form::select('repeat_freq',$periods,Input::old('repeat_freq') ?: 'monthly',['class' => 'form-control'])}}
 | 
				
			||||||
                        @if($errors->has('repeat_freq'))
 | 
					                        @if($errors->has('repeat_freq'))
 | 
				
			||||||
                        <p class="text-danger">{{$errors->first('repeat_freq')}}</p>
 | 
					                        <p class="text-danger">{{$errors->first('repeat_freq')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">Select the period over which this transaction repeats</span>
 | 
					 | 
				
			||||||
                        @endif
 | 
					                        @endif
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <p>
 | 
				
			||||||
 | 
					            <button type="submit" class="btn btn-lg btn-success">
 | 
				
			||||||
 | 
					                <i class="fa fa-plus-circle"></i> Store new recurring transaction
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					        </p>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="col-lg-6 col-md-12 col-sm-6">
 | 
					    <div class="col-lg-6 col-md-12 col-sm-6">
 | 
				
			||||||
        <h4>Optional fields</h4>
 | 
					        <!-- panel for optional fields -->
 | 
				
			||||||
 | 
					        <div class="panel panel-default">
 | 
				
			||||||
 | 
					            <div class="panel-heading">
 | 
				
			||||||
 | 
					                <i class="fa fa-smile-o"></i> Optional fields
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="panel-body">
 | 
				
			||||||
                <div class="form-group">
 | 
					                <div class="form-group">
 | 
				
			||||||
                    {{ Form::label('skip', 'Skip', ['class' => 'col-sm-4 control-label'])}}
 | 
					                    {{ Form::label('skip', 'Skip', ['class' => 'col-sm-4 control-label'])}}
 | 
				
			||||||
                    <div class="col-sm-8">
 | 
					                    <div class="col-sm-8">
 | 
				
			||||||
@@ -116,15 +106,6 @@
 | 
				
			|||||||
                        @endif
 | 
					                        @endif
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
        <!-- select budget -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <!-- select category -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <!-- select beneficiary -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                <div class="form-group">
 | 
					                <div class="form-group">
 | 
				
			||||||
                    <label for="automatch" class="col-sm-4 control-label">Auto-match</label>
 | 
					                    <label for="automatch" class="col-sm-4 control-label">Auto-match</label>
 | 
				
			||||||
                    <div class="col-sm-8">
 | 
					                    <div class="col-sm-8">
 | 
				
			||||||
@@ -137,7 +118,6 @@
 | 
				
			|||||||
                        <span class="help-block">Firefly will automatically match transactions.</span>
 | 
					                        <span class="help-block">Firefly will automatically match transactions.</span>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
                <div class="form-group">
 | 
					                <div class="form-group">
 | 
				
			||||||
                    <label for="active" class="col-sm-4 control-label">Active</label>
 | 
					                    <label for="active" class="col-sm-4 control-label">Active</label>
 | 
				
			||||||
                    <div class="col-sm-8">
 | 
					                    <div class="col-sm-8">
 | 
				
			||||||
@@ -150,34 +130,58 @@
 | 
				
			|||||||
                        <span class="help-block">This recurring transaction is actually active.</span>
 | 
					                        <span class="help-block">This recurring transaction is actually active.</span>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
</div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="row">
 | 
					        <!-- panel for options -->
 | 
				
			||||||
    <div class="col-lg-6 col-md-12 col-sm-6">
 | 
					        <div class="panel panel-default">
 | 
				
			||||||
 | 
					            <div class="panel-heading">
 | 
				
			||||||
        <!-- add another after this one? -->
 | 
					                <i class="fa fa-bolt"></i> Options
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="panel-body">
 | 
				
			||||||
                <div class="form-group">
 | 
					                <div class="form-group">
 | 
				
			||||||
            <label for="create" class="col-sm-4 control-label"> </label>
 | 
					                    <label for="default" class="col-sm-4 control-label">
 | 
				
			||||||
 | 
					                    Store
 | 
				
			||||||
 | 
					                    </label>
 | 
				
			||||||
                    <div class="col-sm-8">
 | 
					                    <div class="col-sm-8">
 | 
				
			||||||
                <div class="checkbox">
 | 
					                        <div class="radio">
 | 
				
			||||||
                        <label>
 | 
					                        <label>
 | 
				
			||||||
                        {{Form::checkbox('create',1,Input::old('create') == '1')}}
 | 
					                            {{Form::radio('post_submit_action','store',true)}}
 | 
				
			||||||
                        Create another (return to this form)
 | 
					                            Store the recurring transaction
 | 
				
			||||||
                        </label>
 | 
					                        </label>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
                <div class="form-group">
 | 
					                <div class="form-group">
 | 
				
			||||||
            <div class="col-sm-offset-4 col-sm-8">
 | 
					                    <label for="validate_only" class="col-sm-4 control-label">
 | 
				
			||||||
                <button type="submit" class="btn btn-default btn-success">Create the recurring transaction</button>
 | 
					                    Validate only
 | 
				
			||||||
 | 
					                    </label>
 | 
				
			||||||
 | 
					                    <div class="col-sm-8">
 | 
				
			||||||
 | 
					                        <div class="radio">
 | 
				
			||||||
 | 
					                        <label>
 | 
				
			||||||
 | 
					                            {{Form::radio('post_submit_action','validate_only')}}
 | 
				
			||||||
 | 
					                            Only validate, do not save
 | 
				
			||||||
 | 
					                        </label>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="form-group">
 | 
				
			||||||
 | 
					                <label for="return_to_form" class="col-sm-4 control-label">
 | 
				
			||||||
 | 
					                Return here
 | 
				
			||||||
 | 
					                </label>
 | 
				
			||||||
 | 
					                <div class="col-sm-8">
 | 
				
			||||||
 | 
					                    <div class="radio">
 | 
				
			||||||
 | 
					                    <label>
 | 
				
			||||||
 | 
					                        {{Form::radio('post_submit_action','create_another')}}
 | 
				
			||||||
 | 
					                        After storing, return here to create another one.
 | 
				
			||||||
 | 
					                    </label>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{Form::close()}}
 | 
					{{Form::close()}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,20 +1,15 @@
 | 
				
			|||||||
@extends('layouts.default')
 | 
					@extends('layouts.default')
 | 
				
			||||||
@section('content')
 | 
					@section('content')
 | 
				
			||||||
<div class="row">
 | 
					 | 
				
			||||||
    <div class="col-lg-12 col-md-12 col-sm-12">
 | 
					 | 
				
			||||||
        <p class="lead">Use recurring transactions to track repeated expenses</p>
 | 
					 | 
				
			||||||
        <p class="text-info">
 | 
					 | 
				
			||||||
            Bla bla.
 | 
					 | 
				
			||||||
        </p>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{{Form::open(['class' => 'form-horizontal','url' => route('recurring.update', $recurringTransaction->id)])}}
 | 
					{{Form::open(['class' => 'form-horizontal','url' => route('recurring.update', $recurringTransaction->id)])}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="row">
 | 
					<div class="row">
 | 
				
			||||||
    <div class="col-lg-6 col-md-12 col-sm-6">
 | 
					    <div class="col-lg-6 col-md-12 col-sm-6">
 | 
				
			||||||
        <h4>Mandatory fields</h4>
 | 
					        <!-- panel for mandatory fields -->
 | 
				
			||||||
 | 
					        <div class="panel panel-primary">
 | 
				
			||||||
 | 
					            <div class="panel-heading">
 | 
				
			||||||
 | 
					                <i class="fa fa-exclamation-circle"></i> Mandatory fields
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="panel-body">
 | 
				
			||||||
        <!-- name -->
 | 
					        <!-- name -->
 | 
				
			||||||
        <div class="form-group">
 | 
					        <div class="form-group">
 | 
				
			||||||
            <label for="name" class="col-sm-4 control-label">Name</label>
 | 
					            <label for="name" class="col-sm-4 control-label">Name</label>
 | 
				
			||||||
@@ -23,8 +18,6 @@
 | 
				
			|||||||
                       value="{{{Input::old('name') ?: $recurringTransaction->name}}}" placeholder="Name">
 | 
					                       value="{{{Input::old('name') ?: $recurringTransaction->name}}}" placeholder="Name">
 | 
				
			||||||
                @if($errors->has('name'))
 | 
					                @if($errors->has('name'))
 | 
				
			||||||
                <p class="text-danger">{{$errors->first('name')}}</p>
 | 
					                <p class="text-danger">{{$errors->first('name')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">For example: rent, gas, insurance</span>
 | 
					 | 
				
			||||||
                @endif
 | 
					                @endif
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
@@ -36,9 +29,6 @@
 | 
				
			|||||||
                       data-role="tagsinput">
 | 
					                       data-role="tagsinput">
 | 
				
			||||||
                @if($errors->has('match'))
 | 
					                @if($errors->has('match'))
 | 
				
			||||||
                <p class="text-danger">{{$errors->first('match')}}</p>
 | 
					                <p class="text-danger">{{$errors->first('match')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">For example: rent, [company name]. All matches need to
 | 
					 | 
				
			||||||
                    be present for the recurring transaction to be recognized. This field is not case-sensitive.</span>
 | 
					 | 
				
			||||||
                @endif
 | 
					                @endif
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
@@ -54,9 +44,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                @if($errors->has('amount_min'))
 | 
					                @if($errors->has('amount_min'))
 | 
				
			||||||
                <p class="text-danger">{{$errors->first('amount_min')}}</p>
 | 
					                <p class="text-danger">{{$errors->first('amount_min')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">Firefly will only include transactions with a higher amount than this. If your rent
 | 
					 | 
				
			||||||
                is usually around € 500,-, enter <code>450</code> to be safe.</span>
 | 
					 | 
				
			||||||
                @endif
 | 
					                @endif
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
@@ -72,9 +59,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                @if($errors->has('amount_max'))
 | 
					                @if($errors->has('amount_max'))
 | 
				
			||||||
                <p class="text-danger">{{$errors->first('amount_max')}}</p>
 | 
					                <p class="text-danger">{{$errors->first('amount_max')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">Firefly will only include transactions with a lower amount than this.
 | 
					 | 
				
			||||||
                    If your rent is usually around € 500,-, enter <code>550</code> to be safe.</span>
 | 
					 | 
				
			||||||
                @endif
 | 
					                @endif
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
@@ -86,8 +70,6 @@
 | 
				
			|||||||
                ['class' => 'form-control']) }}
 | 
					                ['class' => 'form-control']) }}
 | 
				
			||||||
                @if($errors->has('date'))
 | 
					                @if($errors->has('date'))
 | 
				
			||||||
                <p class="text-danger">{{$errors->first('date')}}</p>
 | 
					                <p class="text-danger">{{$errors->first('date')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">Select the next date you expect the transaction to occur.</span>
 | 
					 | 
				
			||||||
                @endif
 | 
					                @endif
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
@@ -99,16 +81,26 @@
 | 
				
			|||||||
                ['class' => 'form-control'])}}
 | 
					                ['class' => 'form-control'])}}
 | 
				
			||||||
                @if($errors->has('repeat_freq'))
 | 
					                @if($errors->has('repeat_freq'))
 | 
				
			||||||
                <p class="text-danger">{{$errors->first('repeat_freq')}}</p>
 | 
					                <p class="text-danger">{{$errors->first('repeat_freq')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">Select the period over which this transaction repeats</span>
 | 
					 | 
				
			||||||
                @endif
 | 
					                @endif
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="col-lg-6 col-md-12 col-sm-6">
 | 
					 | 
				
			||||||
        <h4>Optional fields</h4>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <p>
 | 
				
			||||||
 | 
					            <button type="submit" class="btn btn-lg btn-success">
 | 
				
			||||||
 | 
					                <i class="fa fa-plus-circle"></i> Update recurring transasction
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					        </p>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					    <div class="col-lg-6 col-md-12 col-sm-6">
 | 
				
			||||||
 | 
					        <!-- panel for optional fields -->
 | 
				
			||||||
 | 
					        <div class="panel panel-default">
 | 
				
			||||||
 | 
					            <div class="panel-heading">
 | 
				
			||||||
 | 
					                <i class="fa fa-smile-o"></i> Optional fields
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="panel-body">
 | 
				
			||||||
        <div class="form-group">
 | 
					        <div class="form-group">
 | 
				
			||||||
            {{ Form::label('skip', 'Skip', ['class' => 'col-sm-4 control-label'])}}
 | 
					            {{ Form::label('skip', 'Skip', ['class' => 'col-sm-4 control-label'])}}
 | 
				
			||||||
            <div class="col-sm-8">
 | 
					            <div class="col-sm-8">
 | 
				
			||||||
@@ -117,21 +109,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                @if($errors->has('skip'))
 | 
					                @if($errors->has('skip'))
 | 
				
			||||||
                <p class="text-danger">{{$errors->first('skip')}}</p>
 | 
					                <p class="text-danger">{{$errors->first('skip')}}</p>
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                <span class="help-block">Make Firefly skip every <em>n</em> times. Fill in <code>2</code>, and Firefly
 | 
					 | 
				
			||||||
                will match, skip, skip and match a transaction.</span>
 | 
					 | 
				
			||||||
                @endif
 | 
					                @endif
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <!-- select budget -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <!-- select category -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <!-- select beneficiary -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <div class="form-group">
 | 
					        <div class="form-group">
 | 
				
			||||||
            <label for="automatch" class="col-sm-4 control-label">Auto-match</label>
 | 
					            <label for="automatch" class="col-sm-4 control-label">Auto-match</label>
 | 
				
			||||||
            <div class="col-sm-8">
 | 
					            <div class="col-sm-8">
 | 
				
			||||||
@@ -159,25 +140,57 @@
 | 
				
			|||||||
                <span class="help-block">This recurring transaction is actually active.</span>
 | 
					                <span class="help-block">This recurring transaction is actually active.</span>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
<div class="row">
 | 
					            <!-- panel for options -->
 | 
				
			||||||
    <div class="col-lg-6 col-md-12 col-sm-6">
 | 
					            <div class="panel panel-default">
 | 
				
			||||||
 | 
					                <div class="panel-heading">
 | 
				
			||||||
 | 
					                    <i class="fa fa-bolt"></i> Options
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="panel-body">
 | 
				
			||||||
                    <div class="form-group">
 | 
					                    <div class="form-group">
 | 
				
			||||||
            <div class="col-sm-offset-4 col-sm-8">
 | 
					                        <label for="default" class="col-sm-4 control-label">
 | 
				
			||||||
                <button type="submit" class="btn btn-default btn-success">Update the recurring transaction</button>
 | 
					                        Update
 | 
				
			||||||
 | 
					                        </label>
 | 
				
			||||||
 | 
					                        <div class="col-sm-8">
 | 
				
			||||||
 | 
					                            <div class="radio">
 | 
				
			||||||
 | 
					                            <label>
 | 
				
			||||||
 | 
					                                {{Form::radio('post_submit_action','store',true)}}
 | 
				
			||||||
 | 
					                                Update the recurring transaction
 | 
				
			||||||
 | 
					                            </label>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                    <div class="form-group">
 | 
				
			||||||
 | 
					                        <label for="validate_only" class="col-sm-4 control-label">
 | 
				
			||||||
 | 
					                        Validate only
 | 
				
			||||||
 | 
					                        </label>
 | 
				
			||||||
 | 
					                        <div class="col-sm-8">
 | 
				
			||||||
 | 
					                            <div class="radio">
 | 
				
			||||||
 | 
					                            <label>
 | 
				
			||||||
 | 
					                                {{Form::radio('post_submit_action','validate_only')}}
 | 
				
			||||||
 | 
					                                Only validate, do not save changes
 | 
				
			||||||
 | 
					                            </label>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="form-group">
 | 
				
			||||||
 | 
					                    <label for="return_to_form" class="col-sm-4 control-label">
 | 
				
			||||||
 | 
					                    Return here
 | 
				
			||||||
 | 
					                    </label>
 | 
				
			||||||
 | 
					                    <div class="col-sm-8">
 | 
				
			||||||
 | 
					                        <div class="radio">
 | 
				
			||||||
 | 
					                        <label>
 | 
				
			||||||
 | 
					                            {{Form::radio('post_submit_action','return_to_edit')}}
 | 
				
			||||||
 | 
					                            After update, return here again.
 | 
				
			||||||
 | 
					                        </label>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
{{Form::close()}}
 | 
					{{Form::close()}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,73 +1,41 @@
 | 
				
			|||||||
@extends('layouts.default')
 | 
					@extends('layouts.default')
 | 
				
			||||||
@section('content')
 | 
					@section('content')
 | 
				
			||||||
<div class="row">
 | 
					 | 
				
			||||||
    <div class="col-lg-12 col-md-12 col-sm-12">
 | 
					 | 
				
			||||||
        <p class="lead">Use recurring transactions to track repeated withdrawals</p>
 | 
					 | 
				
			||||||
        <p class="text-info">We all have bills to pay. Firefly can help you organize those bills into recurring transactions,
 | 
					 | 
				
			||||||
        which are exactly what the name suggests. Firefly can match new (and existing) transactions to such a recurring transaction
 | 
					 | 
				
			||||||
        and help you organize these expenses into manageable groups. The front page of Firefly will show you which recurring
 | 
					 | 
				
			||||||
        transactions you have missed, which are yet to come and which have been paid.</p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div class="row">
 | 
					<div class="row">
 | 
				
			||||||
    <div class="col-lg-12 col-sm-12 col-md-12">
 | 
					    <div class="col-lg-12 col-sm-12 col-md-12">
 | 
				
			||||||
        <table class="table table-striped">
 | 
					    <div class="panel panel-default">
 | 
				
			||||||
            <tr>
 | 
					        <div class="panel-heading">
 | 
				
			||||||
                <th>Name</th>
 | 
					            <i class="fa {{$mainTitleIcon}}"></i> {{{$title}}}
 | 
				
			||||||
                <th>Matches on</th>
 | 
					 | 
				
			||||||
                <th>Amount between</th>
 | 
					 | 
				
			||||||
                <th>Expected every</th>
 | 
					 | 
				
			||||||
                <th>Next expected match</th>
 | 
					 | 
				
			||||||
                <th>Auto-match</th>
 | 
					 | 
				
			||||||
                <th>Active</th>
 | 
					 | 
				
			||||||
                <th></th>
 | 
					 | 
				
			||||||
            </tr>
 | 
					 | 
				
			||||||
            @foreach($list as $entry)
 | 
					 | 
				
			||||||
            <tr>
 | 
					 | 
				
			||||||
                <td><a href="{{route('recurring.show',$entry->id)}}">{{{$entry->name}}}</a></td>
 | 
					 | 
				
			||||||
                <td>
 | 
					 | 
				
			||||||
                    @foreach(explode(' ',$entry->match) as $word)
 | 
					 | 
				
			||||||
                    <span class="label label-info">{{{$word}}}</span>
 | 
					 | 
				
			||||||
                    @endforeach
 | 
					 | 
				
			||||||
                </td>
 | 
					 | 
				
			||||||
                <td>
 | 
					 | 
				
			||||||
                    {{mf($entry->amount_min)}} –
 | 
					 | 
				
			||||||
                    {{mf($entry->amount_max)}}
 | 
					 | 
				
			||||||
                </td>
 | 
					 | 
				
			||||||
                <td>
 | 
					 | 
				
			||||||
                    {{$entry->repeat_freq}}
 | 
					 | 
				
			||||||
                </td>
 | 
					 | 
				
			||||||
                <td>
 | 
					 | 
				
			||||||
                    {{$entry->next()->format('d-m-Y')}}
 | 
					 | 
				
			||||||
                </td>
 | 
					 | 
				
			||||||
                <td>
 | 
					 | 
				
			||||||
                    @if($entry->automatch)
 | 
					 | 
				
			||||||
                        <span class="glyphicon glyphicon-ok"></span>
 | 
					 | 
				
			||||||
                    @else
 | 
					 | 
				
			||||||
                        <span class="glyphicon glyphicon-remove"></span>
 | 
					 | 
				
			||||||
                    @endif
 | 
					 | 
				
			||||||
                </td>
 | 
					 | 
				
			||||||
                <td>
 | 
					 | 
				
			||||||
                    @if($entry->active)
 | 
					 | 
				
			||||||
                    <span class="glyphicon glyphicon-ok"></span>
 | 
					 | 
				
			||||||
                    @else
 | 
					 | 
				
			||||||
                    <span class="glyphicon glyphicon-remove"></span>
 | 
					 | 
				
			||||||
                    @endif
 | 
					 | 
				
			||||||
                </td>
 | 
					 | 
				
			||||||
                <td>
 | 
					 | 
				
			||||||
                    <div class="btn-group btn-group-xs">
 | 
					 | 
				
			||||||
                        <a href="{{route('recurring.edit',$entry->id)}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
 | 
					 | 
				
			||||||
                        <a href="{{route('recurring.delete',$entry->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
                </td>
 | 
					        <div class="panel-body">
 | 
				
			||||||
 | 
					            <table class="table table-striped" id="recurringTable">
 | 
				
			||||||
 | 
					            <thead>
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <th>name</th>
 | 
				
			||||||
 | 
					                    <th>match</th>
 | 
				
			||||||
 | 
					                    <th>amount_min</th>
 | 
				
			||||||
 | 
					                    <th>amount_max</th>
 | 
				
			||||||
 | 
					                    <th>date</th>
 | 
				
			||||||
 | 
					                    <th>active</th>
 | 
				
			||||||
 | 
					                    <th>automatch</th>
 | 
				
			||||||
 | 
					                    <th>repeat_freq</th>
 | 
				
			||||||
 | 
					                    <th>id</th>
 | 
				
			||||||
                </tr>
 | 
					                </tr>
 | 
				
			||||||
            @endforeach
 | 
					                </thead>
 | 
				
			||||||
            </table>
 | 
					            </table>
 | 
				
			||||||
        <p>
 | 
					        </div>
 | 
				
			||||||
            <a href="{{route('recurring.create')}}" class="btn btn-success btn-large">Create new recurring transaction</a>
 | 
					        </div>
 | 
				
			||||||
        </p>
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
@stop
 | 
					@stop
 | 
				
			||||||
 | 
					@section('scripts')
 | 
				
			||||||
 | 
					<script type="text/javascript">
 | 
				
			||||||
 | 
					var URL = '{{route('json.recurring')}}';
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					{{HTML::script('assets/javascript/typeahead/bootstrap3-typeahead.min.js')}}
 | 
				
			||||||
 | 
					{{HTML::script('assets/javascript/datatables/jquery.dataTables.min.js')}}
 | 
				
			||||||
 | 
					{{HTML::script('assets/javascript/datatables/dataTables.bootstrap.js')}}
 | 
				
			||||||
 | 
					{{HTML::script('assets/javascript/firefly/recurring.js')}}
 | 
				
			||||||
 | 
					@stop
 | 
				
			||||||
 | 
					@section('styles')
 | 
				
			||||||
 | 
					{{HTML::style('assets/stylesheets/datatables/dataTables.bootstrap.css')}}
 | 
				
			||||||
 | 
					@stop
 | 
				
			||||||
@@ -12,7 +12,7 @@
 | 
				
			|||||||
                    <tr>
 | 
					                    <tr>
 | 
				
			||||||
                        <th>Date</th>
 | 
					                        <th>Date</th>
 | 
				
			||||||
                        <th>Description</th>
 | 
					                        <th>Description</th>
 | 
				
			||||||
                        <th data-dynatable-column="amount">Amount (€)</th>
 | 
					                        <th>Amount (€)</th>
 | 
				
			||||||
                        <th>From</th>
 | 
					                        <th>From</th>
 | 
				
			||||||
                        <th>To</th>
 | 
					                        <th>To</th>
 | 
				
			||||||
                        <th>ID</th>
 | 
					                        <th>ID</th>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										112
									
								
								public/assets/javascript/firefly/recurring.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								public/assets/javascript/firefly/recurring.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
				
			|||||||
 | 
					$(document).ready(function () {
 | 
				
			||||||
 | 
					    $('#recurringTable').DataTable(
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            serverSide: true,
 | 
				
			||||||
 | 
					            ajax: URL,
 | 
				
			||||||
 | 
					            paging: true,
 | 
				
			||||||
 | 
					            processing: true,
 | 
				
			||||||
 | 
					            order: [],
 | 
				
			||||||
 | 
					            "lengthMenu": [[50, 100, 250, -1], [50, 100, 250, "All"]],
 | 
				
			||||||
 | 
					            columns: [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    name: 'name',
 | 
				
			||||||
 | 
					                    data: 'name',
 | 
				
			||||||
 | 
					                    searchable: true,
 | 
				
			||||||
 | 
					                    title: 'Name',
 | 
				
			||||||
 | 
					                    render: function (data) {
 | 
				
			||||||
 | 
					                        return '<a href="' + data.url + '" title="' + data.name + '">' + data.name + '</a>';
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    name: 'match',
 | 
				
			||||||
 | 
					                    data: 'match',
 | 
				
			||||||
 | 
					                    searchable: true,
 | 
				
			||||||
 | 
					                    title: 'Matches on',
 | 
				
			||||||
 | 
					                    render: function (data) {
 | 
				
			||||||
 | 
					                        var str = '';
 | 
				
			||||||
 | 
					                        for (x in data) {
 | 
				
			||||||
 | 
					                            str += '<span class="label label-info">' + data[x] + '</span> ';
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        return str;//return '<a href="' + data.url + '" title="' + data.name + '">' + data.name + '</a>';
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    name: 'amount_min',
 | 
				
			||||||
 | 
					                    data: 'amount_min',
 | 
				
			||||||
 | 
					                    searchable: false,
 | 
				
			||||||
 | 
					                    title: '→',
 | 
				
			||||||
 | 
					                    render: function (data) {
 | 
				
			||||||
 | 
					                        return '<span class="text-info">\u20AC ' + data.toFixed(2) + '</span>';
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    name: 'amount_max',
 | 
				
			||||||
 | 
					                    data: 'amount_max',
 | 
				
			||||||
 | 
					                    searchable: false,
 | 
				
			||||||
 | 
					                    title: '←',
 | 
				
			||||||
 | 
					                    render: function (data) {
 | 
				
			||||||
 | 
					                        return '<span class="text-info">\u20AC ' + data.toFixed(2) + '</span>';
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    name: 'date',
 | 
				
			||||||
 | 
					                    data: 'date',
 | 
				
			||||||
 | 
					                    title: 'Expected on',
 | 
				
			||||||
 | 
					                    searchable: false
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    name: 'active',
 | 
				
			||||||
 | 
					                    data: 'active',
 | 
				
			||||||
 | 
					                    searchable: false,
 | 
				
			||||||
 | 
					                    sortable: false,
 | 
				
			||||||
 | 
					                    render: function(data) {
 | 
				
			||||||
 | 
					                        if(data == 1) {
 | 
				
			||||||
 | 
					                            return '<i class="fa fa-check fa-faw"></i>';
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            return '<i class="fa fa-remove fa-faw"></i>';
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    title: 'Is active?'
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    name: 'automatch',
 | 
				
			||||||
 | 
					                    data: 'automatch',
 | 
				
			||||||
 | 
					                    sortable: false,
 | 
				
			||||||
 | 
					                    searchable: false,
 | 
				
			||||||
 | 
					                    render: function(data) {
 | 
				
			||||||
 | 
					                        if(data == 1) {
 | 
				
			||||||
 | 
					                            return '<i class="fa fa-check fa-faw"></i>';
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            return '<i class="fa fa-remove fa-faw"></i>';
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    title: 'Automatch?'
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    name: 'repeat_freq',
 | 
				
			||||||
 | 
					                    data: 'repeat_freq',
 | 
				
			||||||
 | 
					                    searchable: false,
 | 
				
			||||||
 | 
					                    sortable: false,
 | 
				
			||||||
 | 
					                    title: 'Repeat frequency'
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    name: 'id',
 | 
				
			||||||
 | 
					                    data: 'id',
 | 
				
			||||||
 | 
					                    searchable: false,
 | 
				
			||||||
 | 
					                    sortable: false,
 | 
				
			||||||
 | 
					                    title: '',
 | 
				
			||||||
 | 
					                    render: function (data, type, full, meta) {
 | 
				
			||||||
 | 
					                        return '<div class="btn-group btn-group-xs">' +
 | 
				
			||||||
 | 
					                        '<a class="btn btn-default btn-xs" href="' + data.edit + '">' +
 | 
				
			||||||
 | 
					                        '<span class="glyphicon glyphicon-pencil"</a>' +
 | 
				
			||||||
 | 
					                        '<a class="btn btn-danger btn-xs" href="' + data.delete + '">' +
 | 
				
			||||||
 | 
					                        '<span class="glyphicon glyphicon-trash"</a>' +
 | 
				
			||||||
 | 
					                        '</a></div>';
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -51,6 +51,7 @@ $(document).ready(function () {
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    name: 'amount',
 | 
					                    name: 'amount',
 | 
				
			||||||
                    data: 'amount',
 | 
					                    data: 'amount',
 | 
				
			||||||
 | 
					                    'title': 'Amount (\u20AC)',
 | 
				
			||||||
                    searchable: false,
 | 
					                    searchable: false,
 | 
				
			||||||
                    render: function (data, type, full, meta) {
 | 
					                    render: function (data, type, full, meta) {
 | 
				
			||||||
                        if (display == 'expenses') {
 | 
					                        if (display == 'expenses') {
 | 
				
			||||||
@@ -84,6 +85,8 @@ $(document).ready(function () {
 | 
				
			|||||||
                    name: 'id',
 | 
					                    name: 'id',
 | 
				
			||||||
                    data: 'id',
 | 
					                    data: 'id',
 | 
				
			||||||
                    searchable: false,
 | 
					                    searchable: false,
 | 
				
			||||||
 | 
					                    sortable: false,
 | 
				
			||||||
 | 
					                    title: '',
 | 
				
			||||||
                    render: function (data, type, full, meta) {
 | 
					                    render: function (data, type, full, meta) {
 | 
				
			||||||
                        return '<div class="btn-group btn-group-xs">' +
 | 
					                        return '<div class="btn-group btn-group-xs">' +
 | 
				
			||||||
                        '<a class="btn btn-default btn-xs" href="' + data.edit + '">' +
 | 
					                        '<a class="btn btn-default btn-xs" href="' + data.edit + '">' +
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user