diff --git a/app/controllers/GoogleChartController.php b/app/controllers/GoogleChartController.php index 16ab897861..c31c66c354 100644 --- a/app/controllers/GoogleChartController.php +++ b/app/controllers/GoogleChartController.php @@ -1,6 +1,7 @@ _chart->addColumn('Day of month', 'date'); $this->_chart->addColumn('Balance for ' . $account->name, 'number'); - $start = Session::get('start',Carbon::now()->startOfMonth()); + // TODO this can be combined in some method, it's + $start = Session::get('start', Carbon::now()->startOfMonth()); $end = Session::get('end'); $count = $account->transactions()->count(); @@ -59,150 +61,6 @@ class GoogleChartController extends BaseController return Response::json($this->_chart->getData()); } - /** - * @param Account $account - * @param string $view - * - * @return \Illuminate\Http\JsonResponse - */ - public function accountSankeyInChart(Account $account, $view = 'session') - { - // collect all relevant entries. - $set = []; - - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('From', 'string'); - $chart->addColumn('To', 'string', 'domain'); - $chart->addColumn('Weight', 'number'); - - switch ($view) { - default: - case 'session': - $start = Session::get('start',Carbon::now()->startOfMonth()); - $end = Session::get('end'); - break; - case 'all': - $first = $account->transactionjournals()->orderBy('date', 'DESC')->first(); - $last = $account->transactionjournals()->orderBy('date', 'ASC')->first(); - if (is_null($first)) { - $start = Session::get('start',Carbon::now()->startOfMonth()); - } else { - $start = clone $first->date; - } - if (is_null($last)) { - $end = Session::get('end'); - } else { - $end = clone $last->date; - } - break; - } - - - $transactions = $account->transactions()->with( - ['transactionjournal', 'transactionjournal.transactions' => function ($q) { - $q->where('amount', '<', 0); - }, 'transactionjournal.budgets', 'transactionjournal.transactiontype', 'transactionjournal.categories'] - )->before($end)->after($start)->get(); - - /** @var Transaction $transaction */ - foreach ($transactions as $transaction) { - $amount = floatval($transaction->amount); - $type = $transaction->transactionJournal->transactionType->type; - - if ($amount > 0 && $type != 'Transfer') { - - $otherAccount = $transaction->transactionJournal->transactions[0]->account->name; - $categoryName = isset($transaction->transactionJournal->categories[0]) ? $transaction->transactionJournal->categories[0]->name : '(no cat)'; - $set[] = [$otherAccount, $categoryName, $amount]; - $set[] = [$categoryName, $account->name, $amount]; - } - } - // loop the set, group everything together: - $grouped = []; - foreach ($set as $entry) { - $key = $entry[0] . $entry[1]; - if (isset($grouped[$key])) { - $grouped[$key][2] += $entry[2]; - } else { - $grouped[$key] = $entry; - } - } - - // add rows to the chart: - foreach ($grouped as $entry) { - $chart->addRow($entry[0], $entry[1], $entry[2]); - } - - $chart->generate(); - - return Response::json($chart->getData()); - - } - - /** - * @param Account $account - * @param string $view - * - * @return \Illuminate\Http\JsonResponse - */ - public function accountSankeyOutChart(Account $account, $view = 'session') - { - // collect all relevant entries. - $set = []; - - /** @var \Grumpydictator\Gchart\GChart $chart */ - $chart = App::make('gchart'); - $chart->addColumn('From', 'string'); - $chart->addColumn('To', 'string', 'domain'); - $chart->addColumn('Weight', 'number'); - - $transactions = $account->transactions()->with( - ['transactionjournal', 'transactionjournal.transactions', 'transactionjournal.budgets', 'transactionjournal.transactiontype', - 'transactionjournal.categories'] - )->before(Session::get('end'))->after( - Session::get('start',Carbon::now()->startOfMonth()) - )->get(); - - /** @var Transaction $transaction */ - foreach ($transactions as $transaction) { - $amount = floatval($transaction->amount); - $type = $transaction->transactionJournal->transactionType->type; - - if ($amount < 0 && $type != 'Transfer') { - - // from account to a budget (if present). - $budgetName = isset($transaction->transactionJournal->budgets[0]) ? $transaction->transactionJournal->budgets[0]->name : '(no budget)'; - $set[] = [$account->name, $budgetName, $amount * -1]; - - // from budget to category. - $categoryName = isset($transaction->transactionJournal->categories[0]) ? ' ' . $transaction->transactionJournal->categories[0]->name - : '(no cat)'; - $set[] = [$budgetName, $categoryName, $amount * -1]; - } - } - // loop the set, group everything together: - $grouped = []; - foreach ($set as $entry) { - $key = $entry[0] . $entry[1]; - if (isset($grouped[$key])) { - $grouped[$key][2] += $entry[2]; - } else { - $grouped[$key] = $entry; - } - } - - // add rows to the chart: - foreach ($grouped as $entry) { - $chart->addRow($entry[0], $entry[1], $entry[2]); - } - - $chart->generate(); - - return Response::json($chart->getData()); - - } - /** * This method renders the b */ @@ -235,7 +93,7 @@ class GoogleChartController extends BaseController /* * Loop the date, then loop the accounts, then add balance. */ - $start = Session::get('start',Carbon::now()->startOfMonth()); + $start = Session::get('start', Carbon::now()->startOfMonth()); $end = Session::get('end'); $current = clone $start; @@ -281,14 +139,14 @@ class GoogleChartController extends BaseController * Is there a repetition starting on this particular date? We can use that. */ /** @var \LimitRepetition $repetition */ - $repetition = $bdt->repetitionOnStartingOnDate($budget, Session::get('start',Carbon::now()->startOfMonth())); + $repetition = $bdt->repetitionOnStartingOnDate($budget, Session::get('start', Carbon::now()->startOfMonth())); /* * If there is, use it. Otherwise, forget it. */ if (is_null($repetition)) { // use the session start and end for our search query - $searchStart = Session::get('start',Carbon::now()->startOfMonth()); + $searchStart = Session::get('start', Carbon::now()->startOfMonth()); $searchEnd = Session::get('end'); // the limit is zero: $limit = 0; @@ -315,7 +173,7 @@ class GoogleChartController extends BaseController * Finally, get all transactions WITHOUT a budget and add those as well. * (yes this method is oddly specific). */ - $noBudgetSet = $bdt->transactionsWithoutBudgetInDateRange(Session::get('start',Carbon::now()->startOfMonth()), Session::get('end')); + $noBudgetSet = $bdt->transactionsWithoutBudgetInDateRange(Session::get('start', Carbon::now()->startOfMonth()), Session::get('end')); $sum = $noBudgetSet->sum('amount') * -1; $chart->addRow('No budget', 0, $sum); @@ -343,7 +201,7 @@ class GoogleChartController extends BaseController /* * Get the journals: */ - $journals = $tj->getInDateRange(Session::get('start',Carbon::now()->startOfMonth()), Session::get('end')); + $journals = $tj->getInDateRange(Session::get('start', Carbon::now()->startOfMonth()), Session::get('end')); /** @var \TransactionJournal $journal */ foreach ($journals as $journal) { @@ -627,7 +485,7 @@ class GoogleChartController extends BaseController /* * In the current session range? */ - if (\Session::get('end') >= $current and $currentEnd >= \Session::get('start',Carbon::now()->startOfMonth())) { + if (\Session::get('end') >= $current and $currentEnd >= \Session::get('start', Carbon::now()->startOfMonth())) { /* * Lets see if we've already spent money on this recurring transaction (it hath recurred). */ diff --git a/app/lib/Firefly/Database/SingleTableInheritanceEntity.php b/app/lib/Firefly/Database/SingleTableInheritanceEntity.php deleted file mode 100644 index 762ee14ad6..0000000000 --- a/app/lib/Firefly/Database/SingleTableInheritanceEntity.php +++ /dev/null @@ -1,121 +0,0 @@ -mapData((array)$attributes)->newInstance([], true); - $instance->setRawAttributes((array)$attributes, true); - - return $instance; - } - - - /** - * if no subclass is defined, function as normal - * - * @param array $attributes - * - * @return \Illuminate\Database\Eloquent\Model|static - */ - public function mapData(array $attributes) - { - if (!$this->subclassField) { - return $this->newInstance(); - } - - return new $attributes[$this->subclassField]; - } - - - /** - * - * instead of using $this->newInstance(), call - * newInstance() on the object from mapData - * - * @param bool $excludeDeleted - * - * @return \Illuminate\Database\Eloquent\Builder|static - */ - public function newQuery($excludeDeleted = true) - { - // If using Laravel 4.0.x then use the following commented version of this command - // $builder = new Builder($this->newBaseQueryBuilder()); - // newEloquentBuilder() was added in 4.1 - $builder = $this->newEloquentBuilder($this->newBaseQueryBuilder()); - - // Once Firefly has the query builders, it will set the model instances so the - // builder can easily access any information it may need from the model - // while it is constructing and executing various queries against it. - $builder->setModel($this)->with($this->with); - - if ($excludeDeleted && $this->softDelete) { - $builder->whereNull($this->getQualifiedDeletedAtColumn()); - } - - if ($this->subclassField && $this->isSubclass()) { - $builder->where($this->subclassField, '=', get_class($this)); - } - - return $builder; - } - - /** - * @return bool - */ - public function isSubclass() - { - return $this->isSubclass; - } - - /** - * ensure that the subclass field is assigned on save - * - * @param array $rules - * @param array $customMessages - * @param array $options - * @param callable $beforeSave - * @param callable $afterSave - * - * @return bool - */ - public function save( - array $rules = [], - array $customMessages = [], - array $options = [], - \Closure $beforeSave = null, - \Closure $afterSave = null - ) { - if ($this->subclassField) { - $this->attributes[$this->subclassField] = get_class($this); - } - - return parent::save($rules, $customMessages, $options, $beforeSave, $afterSave); - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Exception/FireflyException.php b/app/lib/Firefly/Exception/FireflyException.php deleted file mode 100644 index eb0f038fa3..0000000000 --- a/app/lib/Firefly/Exception/FireflyException.php +++ /dev/null @@ -1,14 +0,0 @@ - 'Amount (min)', - 'amount_max' => 'Amount (max)', - 'match' => 'Matches on', - 'repeat_freq' => 'Repetition', - 'account_from_id' => 'Account from', - 'account_to_id' => 'Account to', - 'account_id' => 'Asset account' - ]; - - return isset($labels[$name]) ? $labels[$name] : str_replace('_', ' ', ucfirst($name)); - - } - - /** - * Return buttons for update/validate/return. - * - * @param $type - * @param $name - */ - public static function ffOptionsList($type, $name) - { - $previousValue = \Input::old('post_submit_action'); - $previousValue = is_null($previousValue) ? 'store' : $previousValue; - /* - * Store. - */ - $store = ''; - switch ($type) { - case 'create': - $store = '
'; - $store .= '
'; - break; - case 'update': - $store = '
'; - $store .= '
'; - break; - default: - throw new FireflyException('Cannot create ffOptionsList for option (store) ' . $type); - break; - } - - /* - * validate is always the same: - */ - $validate = '
'; - - /* - * Store & return: - */ - switch ($type) { - case 'create': - $return = '
'; - break; - case 'update': - $return = '
'; - break; - default: - throw new FireflyException('Cannot create ffOptionsList for option (store+return) ' . $type); - break; - } - return $store . $validate . $return; - } - - /** - * @param $type - * @param $name - * @param null $value - * @param array $options - * @param array $list - * - * @return string - * @throws FireflyException - */ - public static function ffInput($type, $name, $value = null, array $options = array(), $list = []) - { - /* - * add some defaults to this method: - */ - $options['class'] = 'form-control'; - $options['id'] = 'ffInput_' . $name; - $options['autocomplete'] = 'off'; - $label = self::label($name, $options); - /* - * Make label and placeholder look nice. - */ - $options['placeholder'] = ucfirst($name); - - /* - * Get pre filled value: - */ - if (\Session::has('prefilled')) { - $preFilled = \Session::get('preFilled'); - $value = isset($prefilled[$name]) && is_null($value) ? $prefilled[$name] : $value; - } - - /* - * Get the value. - */ - if (!is_null(\Input::old($name))) { - /* - * Old value overrules $value. - */ - $value = \Input::old($name); - } - - /* - * Get errors, warnings and successes from session: - */ - /** @var MessageBag $errors */ - $errors = \Session::get('errors'); - - /** @var MessageBag $warnings */ - $warnings = \Session::get('warnings'); - - /** @var MessageBag $successes */ - $successes = \Session::get('successes'); - - - /* - * If errors, add some more classes. - */ - switch (true) { - case (!is_null($errors) && $errors->has($name)): - $classes = 'form-group has-error has-feedback'; - break; - case (!is_null($warnings) && $warnings->has($name)): - $classes = 'form-group has-warning has-feedback'; - break; - case (!is_null($successes) && $successes->has($name)): - $classes = 'form-group has-success has-feedback'; - break; - default: - $classes = 'form-group'; - break; - } - - /* - * Add some HTML. - */ - $html = '
'; - $html .= ''; - $html .= '
'; - - - /* - * Switch input type: - */ - unset($options['label']); - switch ($type) { - case 'text': - $html .= \Form::input('text', $name, $value, $options); - break; - case 'amount': - $html .= '
'; - $html .= \Form::input('number', $name, $value, $options); - $html .= '
'; - break; - case 'number': - $html .= \Form::input('number', $name, $value, $options); - break; - case 'checkbox': - $checked = $options['checked']; - unset($options['checked'], $options['placeholder'], $options['autocomplete'], $options['class']); - $html .= '
'; - - - break; - case 'date': - $html .= \Form::input('date', $name, $value, $options); - break; - case 'select': - $html .= \Form::select($name, $list, $value, $options); - break; - default: - throw new FireflyException('Cannot handle type "' . $type . '" in FFFormBuilder.'); - break; - } - - /* - * If errors, respond to them: - */ - - if (!is_null($errors)) { - if ($errors->has($name)) { - $html .= ''; - $html .= '

' . e($errors->first($name)) . '

'; - } - } - unset($errors); - /* - * If warnings, respond to them: - */ - - if (!is_null($warnings)) { - if ($warnings->has($name)) { - $html .= ''; - $html .= '

' . e($warnings->first($name)) . '

'; - } - } - unset($warnings); - - /* - * If successes, respond to them: - */ - - if (!is_null($successes)) { - if ($successes->has($name)) { - $html .= ''; - $html .= '

' . e($successes->first($name)) . '

'; - } - } - unset($successes); - - $html .= '
'; - $html .= '
'; - - return $html; - - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Controllers/Account.php b/app/lib/Firefly/Helper/Controllers/Account.php deleted file mode 100644 index 93dd3b12d7..0000000000 --- a/app/lib/Firefly/Helper/Controllers/Account.php +++ /dev/null @@ -1,154 +0,0 @@ -accountIs($account) - ->leftJoin( - 'transaction_types', 'transaction_types.id', '=', - 'transaction_journals.transaction_type_id' - ) - ->where('transaction_types.type', 'Opening balance') - ->first(['transaction_journals.*']); - } - - /** - * Since it is entirely possible the database is messed up somehow it might be that a transaction - * journal has only one transaction. This is mainly caused by wrong deletions and other artefacts from the past. - * - * If it is the case, Firefly removes $item and continues like nothing ever happened. This will however, - * mess up some statisics but it's decided everybody should learn to live with that. - * - * Firefly might be needing some cleanup routine in the future. - * - * For now, Firefly simply warns the user of this. - * - * @param \Account $account - * @param $perPage - * - * @return array|mixed - * @throws \Firefly\Exception\FireflyException - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - */ - public function show(\Account $account, $perPage) - { - $start = \Session::get('start'); - $end = \Session::get('end'); - $stats = [ - 'accounts' => [] - ]; - $items = []; - - // build a query: - $query = \TransactionJournal::withRelevantData() - ->defaultSorting() - ->accountIs($account) - ->after($start) - ->before($end); - // filter some: - switch (\Input::get('type')) { - case 'transactions': - $query->transactionTypes(['Deposit', 'Withdrawal']); - break; - case 'transfers': - $query->transactionTypes(['Transfer']); - break; - } - - switch (\Input::get('show')) { - case 'expenses': - case 'out': - $query->lessThan(0); - break; - case 'income': - case 'in': - $query->moreThan(0); - break; - } - - - // build paginator: - $totalItems = $query->count(); - $page = max(1, intval(\Input::get('page'))); - $skip = ($page - 1) * $perPage; - $result = $query->skip($skip)->take($perPage)->get(['transaction_journals.*']); - - - // get the relevant budgets, categories and accounts from this list: - /** @var $item \TransactionJournal */ - foreach ($result as $index => $item) { - - foreach ($item->components as $component) { - $stats[$component->class][$component->id] = $component; - } - - if (count($item->transactions) < 2) { - \Session::flash('warning', 'Some transactions are incomplete; they will not be shown.'); - unset($result[$index]); - continue; - } - $items[] = $item; - $fromAccount = $item->transactions[0]->account; - $toAccount = $item->transactions[1]->account; - $stats['accounts'][$fromAccount->id] = $fromAccount; - $stats['accounts'][$toAccount->id] = $toAccount; - } - $paginator = \Paginator::make($items, $totalItems, $perPage); - unset($result, $page, $item, $fromAccount, $toAccount); - - - // statistics (transactions) - $trIn = floatval( - \Transaction::before($end)->after($start)->accountIs($account)->moreThan(0) - ->transactionTypes(['Deposit', 'Withdrawal'])->sum('transactions.amount') - ); - $trOut = floatval( - \Transaction::before($end)->after($start)->accountIs($account)->lessThan(0) - ->transactionTypes(['Deposit', 'Withdrawal'])->sum('transactions.amount') - ); - $trDiff = $trIn + $trOut; - - // statistics (transfers) - $trfIn = floatval( - \Transaction::before($end)->after($start)->accountIs($account)->moreThan(0) - ->transactionTypes(['Transfer'])->sum('transactions.amount') - ); - $trfOut = floatval( - \Transaction::before($end)->after($start)->accountIs($account)->lessThan(0) - ->transactionTypes(['Transfer'])->sum('transactions.amount') - ); - $trfDiff = $trfIn + $trfOut; - - $stats['period'] = [ - 'in' => $trIn, - 'out' => $trOut, - 'diff' => $trDiff, - 't_in' => $trfIn, - 't_out' => $trfOut, - 't_diff' => $trfDiff - - ]; - - $return = [ - 'journals' => $paginator, - 'statistics' => $stats - ]; - - return $return; - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Controllers/AccountInterface.php b/app/lib/Firefly/Helper/Controllers/AccountInterface.php deleted file mode 100644 index 4c2e378845..0000000000 --- a/app/lib/Firefly/Helper/Controllers/AccountInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -limits as $limit) { - - /** @var \LimitRepetition $repetition */ - foreach ($limit->limitrepetitions as $repetition) { - $repetition->left = $repetition->leftInRepetition(); - $periodOrder = $repetition->periodOrder(); - $period = $repetition->periodShow(); - if (!isset($return[$periodOrder])) { - - $return[$periodOrder] = [ - 'date' => $period, - 'start' => $repetition->startdate, - 'end' => $repetition->enddate, - 'budget_id' => $budget->id, - 'limitrepetitions' => [$repetition] - ]; - } else { - $return[$periodOrder]['limitrepetitions'][] = $repetition; - } - - } - } - } - krsort($return); - - return $return; - } - - /** - * Get a repetition (complex because of user check) - * and then get the transactions in it. - * @param $repetitionId - * - * @return array - */ - public function organizeRepetition(\LimitRepetition $repetition) - { - $result = []; - // get transactions: - $set = $repetition->limit->budget - ->transactionjournals() - ->withRelevantData() - ->transactionTypes(['Withdrawal']) - ->after($repetition->startdate) - ->before($repetition->enddate) - ->defaultSorting() - ->get(['transaction_journals.*']); - - $result[0] = [ - 'date' => $repetition->periodShow(), - 'limit' => $repetition->limit, - 'limitrepetition' => $repetition, - 'journals' => $set, - 'paginated' => false - ]; - - return $result; - } - - /** - * - * - * @param \Budget $budget - * @param bool $useSessionDates - * - * @return array|mixed - * @throws \Firefly\Exception\FireflyException - */ - public function organizeRepetitions(\Budget $budget, $useSessionDates = false) - { - $sessionStart = \Session::get('start'); - $sessionEnd = \Session::get('end'); - - $result = []; - $inRepetition = []; - - // get the limits: - if ($useSessionDates) { - $limits = $budget->limits()->where('startdate', '>=', $sessionStart->format('Y-m-d'))->where( - 'startdate', '<=', $sessionEnd->format('Y-m-d') - )->get(); - } else { - $limits = $budget->limits; - } - - /** @var \Limit $limit */ - foreach ($limits as $limit) { - foreach ($limit->limitrepetitions as $repetition) { - $order = $repetition->periodOrder(); - $result[$order] = [ - 'date' => $repetition->periodShow(), - 'limitrepetition' => $repetition, - 'limit' => $limit, - 'journals' => [], - 'paginated' => false - ]; - $transactions = []; - $set = $budget->transactionjournals() - ->withRelevantData() - ->transactionTypes(['Withdrawal']) - ->after($repetition->startdate) - ->before($repetition->enddate) - ->defaultSorting() - ->get(['transaction_journals.*']); - foreach ($set as $entry) { - $transactions[] = $entry; - $inRepetition[] = $entry->id; - } - $result[$order]['journals'] = $transactions; - } - - } - if ($useSessionDates === false) { - $query = $budget->transactionjournals()->withRelevantData()->defaultSorting(); - if (count($inRepetition) > 0) { - $query->whereNotIn('transaction_journals.id', $inRepetition); - } - - // build paginator: - $perPage = 25; - $totalItems = $query->count(); - $page = intval(\Input::get('page')) > 1 ? intval(\Input::get('page')) : 1; - $skip = ($page - 1) * $perPage; - $set = $query->skip($skip)->take($perPage)->get(); - - // stupid paginator! - $items = []; - /** @var $item \TransactionJournal */ - foreach ($set as $item) { - $items[] = $item; - } - $paginator = \Paginator::make($items, $totalItems, $perPage); - $result['0000'] = [ - 'date' => 'Not in an envelope', - 'limit' => null, - 'paginated' => true, - 'journals' => $paginator]; - } - krsort($result); - - return $result; - } - - /** - * @param \Budget $budget - * - * @return mixed|void - */ - public function outsideRepetitions(\Budget $budget) - { - $inRepetitions = []; - foreach ($budget->limits as $limit) { - foreach ($limit->limitrepetitions as $repetition) { - $set = $budget->transactionjournals() - ->transactionTypes(['Withdrawal']) - ->after($repetition->startdate) - ->before($repetition->enddate) - ->defaultSorting() - ->get(['transaction_journals.id']); - foreach ($set as $item) { - $inRepetitions[] = $item->id; - } - } - - } - - $query = $budget->transactionjournals() - ->withRelevantData() - ->whereNotIn('transaction_journals.id', $inRepetitions) - ->defaultSorting(); - - // build paginator: - $perPage = 25; - $totalItems = $query->count(); - $page = intval(\Input::get('page')) > 1 ? intval(\Input::get('page')) : 1; - $skip = ($page - 1) * $perPage; - $set = $query->skip($skip)->take($perPage)->get(); - - // stupid paginator! - $items = []; - /** @var $item \TransactionJournal */ - foreach ($set as $item) { - $items[] = $item; - } - $paginator = \Paginator::make($items, $totalItems, $perPage); - $result = [0 => [ - 'date' => 'Not in an envelope', - 'limit' => null, - 'paginated' => true, - 'journals' => $paginator - ]]; - - return $result; - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Controllers/BudgetInterface.php b/app/lib/Firefly/Helper/Controllers/BudgetInterface.php deleted file mode 100644 index 8fc25c10f8..0000000000 --- a/app/lib/Firefly/Helper/Controllers/BudgetInterface.php +++ /dev/null @@ -1,44 +0,0 @@ -transactionjournals()->with( - ['transactions', 'transactions.account', 'transactiontype', 'components'] - )->orderBy('date', 'DESC')->orderBy('id', 'DESC')->before($end)->after($start)->get(); - - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Controllers/CategoryInterface.php b/app/lib/Firefly/Helper/Controllers/CategoryInterface.php deleted file mode 100644 index 6e95583bd7..0000000000 --- a/app/lib/Firefly/Helper/Controllers/CategoryInterface.php +++ /dev/null @@ -1,25 +0,0 @@ - $account->name, - 'id' => $account->id, - 'type' => 'spline', - 'pointStart' => $start->timestamp * 1000, - 'pointInterval' => 24 * 3600 * 1000, // one day - 'data' => [] - ]; - - while ($current <= $end) { - if ($current > $today) { - $return['data'][] = $account->predict(clone $current); - } else { - $return['data'][] = $account->balance(clone $current); - } - - $current->addDay(); - } - - return $return; - } - - /** - * @param \Account $account - * @param Carbon $date - * - * @return array - */ - public function accountDailySummary(\Account $account, Carbon $date) - { - $result = [ - 'rows' => [], - 'sum' => 0 - ]; - if ($account) { - // get journals in range: - $journals = \Auth::user()->transactionjournals()->with( - [ - 'transactions', - 'transactions.account', - 'transactioncurrency', - 'transactiontype' - ] - ) - ->distinct() - ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') - ->where('transactions.account_id', $account->id) - ->where('transaction_journals.date', $date->format('Y-m-d')) - ->orderBy('transaction_journals.date', 'DESC') - ->orderBy('transaction_journals.id', 'DESC') - ->get(['transaction_journals.*']); - - // loop all journals: - foreach ($journals as $journal) { - foreach ($journal->transactions as $transaction) { - $name = $transaction->account->name; - if ($transaction->account->id != $account->id) { - if (!isset($result['rows'][$name])) { - $result['rows'][$name] = [ - 'name' => $name, - 'id' => $transaction->account->id, - 'amount' => floatval($transaction->amount) - ]; - } else { - $result['rows'][$name]['amount'] += floatval($transaction->amount); - } - $result['sum'] += floatval($transaction->amount); - } - } - } - } - - return $result; - - } - - /** - * @param Carbon $start - * @param Carbon $end - * - * @return array - * @throws \Firefly\Exception\FireflyException - */ - public function categories(Carbon $start, Carbon $end) - { - - $result = []; - // grab all transaction journals in this period: - $journals = \TransactionJournal:: - with( - ['components', 'transactions' => function ($q) { - $q->where('amount', '>', 0); - }] - ) - ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') - ->where('transaction_types.type', 'Withdrawal') - ->after($start)->before($end) - ->where('completed', 1) - ->get(['transaction_journals.*']); - foreach ($journals as $journal) { - // has to be one: - - if (!isset($journal->transactions[0])) { - throw new FireflyException('Journal #' . $journal->id . ' has ' . count($journal->transactions) - . ' transactions!'); - } - $transaction = $journal->transactions[0]; - $amount = floatval($transaction->amount); - - // get budget from journal: - $category = $journal->categories()->first(); - $categoryName = is_null($category) ? '(no category)' : $category->name; - - $result[$categoryName] = isset($result[$categoryName]) ? $result[$categoryName] + floatval($amount) - : $amount; - - } - unset($journal, $transaction, $category, $amount); - - // sort - arsort($result); - $chartData = []; - foreach ($result as $name => $value) { - $chartData[] = [$name, $value]; - } - - - return $chartData; - } - - /** - * @param \Category $category - * @param $range - * @param Carbon $start - * @param Carbon $end - * - * @return array - * @throws \Firefly\Exception\FireflyException - */ - public function categoryShowChart(\Category $category, $range, Carbon $start, Carbon $end) - { - $data = ['name' => $category->name . ' per ' . $range, 'data' => []]; - // go back twelve periods. Skip if empty. - $beginning = clone $start; - switch ($range) { - default: - throw new FireflyException('No beginning for range ' . $range); - break; - case '1D': - $beginning->subDays(12); - break; - case '1W': - $beginning->subWeeks(12); - break; - case '1M': - $beginning->subYear(); - break; - case '3M': - $beginning->subYears(3); - break; - case '6M': - $beginning->subYears(6); - break; - case 'custom': - $diff = $start->diff($end); - $days = $diff->days; - $beginning->subDays(12 * $days); - break; - } - - // loop over the periods: - while ($beginning <= $start) { - // increment currentEnd to fit beginning: - $currentEnd = clone $beginning; - // increase beginning for next round: - switch ($range) { - default: - throw new FireflyException('No currentEnd incremental for range ' . $range); - break; - case '1D': - break; - case '1W': - $currentEnd->addWeek()->subDay(); - break; - case '1M': - $currentEnd->addMonth()->subDay(); - break; - case '3M': - $currentEnd->addMonths(3)->subDay(); - break; - case '6M': - $currentEnd->addMonths(6)->subDay(); - break; - case 'custom': - $diff = $start->diff($end); - $days = $diff->days; - $days = $days == 1 ? 2 : $days; - $currentEnd->addDays($days)->subDay(); - break; - } - - - // now format the current range: - $title = ''; - switch ($range) { - default: - throw new FireflyException('No date formats for frequency "' . $range . '"!'); - break; - case '1D': - $title = $beginning->format('j F Y'); - break; - case '1W': - $title = $beginning->format('\W\e\e\k W, Y'); - break; - case '1M': - $title = $beginning->format('F Y'); - break; - case '3M': - case '6M': - $title = $beginning->format('M Y') . ' - ' . $currentEnd->format('M Y'); - break; - case 'custom': - $title = $beginning->format('d-m-Y') . ' - ' . $currentEnd->format('d-m-Y'); - break; - case 'yearly': -// return $this->startdate->format('Y'); - break; - } - - - // get sum for current range: - $journals = \TransactionJournal:: - with( - ['transactions' => function ($q) { - $q->where('amount', '>', 0); - }] - ) - ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') - ->where('transaction_types.type', 'Withdrawal') - ->leftJoin( - 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', - 'transaction_journals.id' - ) - ->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id') - ->where('components.id', '=', $category->id) - //->leftJoin() - ->after($beginning)->before($currentEnd) - ->where('completed', 1) - ->get(['transaction_journals.*']); - $currentSum = 0; - foreach ($journals as $journal) { - if (!isset($journal->transactions[0])) { - throw new FireflyException('Journal #' . $journal->id . ' has ' . count($journal->transactions) - . ' transactions!'); - } - $transaction = $journal->transactions[0]; - $amount = floatval($transaction->amount); - $currentSum += $amount; - - } - $data['data'][] = [$title, $currentSum]; - - // increase beginning for next round: - switch ($range) { - default: - throw new FireflyException('No incremental for range ' . $range); - break; - case '1D': - $beginning->addDay(); - break; - case '1W': - $beginning->addWeek(); - break; - case '1M': - $beginning->addMonth(); - break; - case '3M': - $beginning->addMonths(3); - break; - case '6M': - $beginning->addMonths(6); - break; - case 'custom': - $diff = $start->diff($end); - $days = $diff->days; - - $beginning->addDays($days); - break; - - } - } - - return $data; - - - } - - /** - * @param \Budget $budget - * @param Carbon $date - * - * @return float|null - */ - public function spentOnDay(\Budget $budget, Carbon $date) - { - return floatval( - \Transaction:: - leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin( - 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', - 'transaction_journals.id' - )->where('component_transaction_journal.component_id', '=', $budget->id)->where( - 'transaction_journals.date', $date->format('Y-m-d') - )->where('amount', '>', 0)->sum('amount') - ); - } - - /** - * @param \Budget $budget - * - * @return int[] - */ - public function allJournalsInBudgetEnvelope(\Budget $budget) - { - $inRepetitions = []; - - foreach ($budget->limits as $limit) { - foreach ($limit->limitrepetitions as $repetition) { - $set = $budget - ->transactionjournals() - ->transactionTypes(['Withdrawal']) - ->after($repetition->startdate) - ->before($repetition->enddate) - ->get(['transaction_journals.id']); - - foreach ($set as $item) { - $inRepetitions[] = $item->id; - } - } - } - return $inRepetitions; - } - - /** - * @param \Budget $budget - * @param array $ids - * - * @return mixed|void - */ - public function journalsNotInSet(\Budget $budget, array $ids) - { - $query = $budget->transactionjournals() - ->whereNotIn('transaction_journals.id', $ids) - ->orderBy('date', 'DESC') - ->orderBy('transaction_journals.id', 'DESC'); - - $result = $query->get(['transaction_journals.id']); - $set = []; - foreach ($result as $entry) { - $set[] = $entry->id; - } - return $set; - } - - /** - * @param array $set - * - * @return mixed - */ - public function transactionsByJournals(array $set) - { - $transactions = \Transaction::whereIn('transaction_journal_id', $set) - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->groupBy('transaction_journals.date') - ->where('amount', '>', 0)->get(['transaction_journals.date', \DB::Raw('SUM(`amount`) as `aggregate`')]); - return $transactions; - } - - /** - * Get all limit (LimitRepetitions) for a budget falling in a certain date range. - * - * @param \Budget $budget - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - public function limitsInRange(\Budget $budget, Carbon $start, Carbon $end) - { - $reps = new Collection; - /** @var \Limit $limit */ - foreach ($budget->limits as $limit) { - $set = $limit->limitrepetitions()->where( - function ($q) use ($start, $end) { - // startdate is between range - $q->where( - function ($q) use ($start, $end) { - $q->where('startdate', '>=', $start->format('Y-m-d')); - $q->where('startdate', '<=', $end->format('Y-m-d')); - } - ); - - // or enddate is between range. - $q->orWhere( - function ($q) use ($start, $end) { - $q->where('enddate', '>=', $start->format('Y-m-d')); - $q->where('enddate', '<=', $end->format('Y-m-d')); - } - ); - } - )->get(); - - $reps = $reps->merge($set); - } - return $reps; - } - - /** - * Firefly checks how much money has been spend on the limitrepetition (aka: the current envelope) in - * the period denoted. Aka, the user has a certain amount of money in an envelope and wishes to know how - * much he has spent between the dates entered. This date range can be a partial match with the date range - * of the envelope or no match at all. - * - * @param \LimitRepetition $repetition - * @param Carbon $start - * @param Carbon $end - * - * @return mixed - */ - public function spentOnLimitRepetitionBetweenDates(\LimitRepetition $repetition, Carbon $start, Carbon $end) - { - return floatval( - \Transaction:: - leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin( - 'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', - 'transaction_journals.id' - )->where('component_transaction_journal.component_id', '=', $repetition->limit->budget->id)->where( - 'transaction_journals.date', '>=', $start->format('Y-m-d') - )->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->where( - 'amount', '>', 0 - )->sum('amount') - ); - } - - -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Controllers/ChartInterface.php b/app/lib/Firefly/Helper/Controllers/ChartInterface.php deleted file mode 100644 index 1706fde96f..0000000000 --- a/app/lib/Firefly/Helper/Controllers/ChartInterface.php +++ /dev/null @@ -1,108 +0,0 @@ - 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. - */ - /** @var \TransactionJournal $entry */ - foreach ($set as $entry) { - $from = $entry->transactions[0]->account; - $to = $entry->transactions[1]->account; - $budget = $entry->budgets()->first(); - $category = $entry->categories()->first(); - $recurring = $entry->recurringTransaction()->first(); - $arr = [ - '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)], - 'components' => [ - 'budget_id' => 0, - 'budget_url' => '', - 'budget_name' => '', - 'category_id' => 0, - 'category_url' => '', - 'category_name' => '' - ], - 'id' => [ - 'edit' => route('transactions.edit', $entry->id), - 'delete' => route('transactions.delete', $entry->id) - ] - ]; - if ($budget) { - $arr['components']['budget_id'] = $budget->id; - $arr['components']['budget_name'] = $budget->name; - $arr['components']['budget_url'] = route('budgets.show', $budget->id); - } - if ($category) { - $arr['components']['category_id'] = $category->id; - $arr['components']['category_name'] = $category->name; - $arr['components']['category_url'] = route('categories.show', $category->id); - } - if ($recurring) { - $arr['components']['recurring_id'] = $recurring->id; - $arr['components']['recurring_name'] = e($recurring->name); - $arr['components']['recurring_url'] = route('recurring.show', $recurring->id); - } - - $data['data'][] = $arr; - - } - 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) { - $set = [ - - '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) - ] - ]; - if (intval($entry->skip) > 0) { - $set['repeat_freq'] = $entry->repeat_freq . ' (skip ' . $entry->skip . ')'; - } - $data['data'][] = $set; - - - } - 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; - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Controllers/JsonInterface.php b/app/lib/Firefly/Helper/Controllers/JsonInterface.php deleted file mode 100644 index 4e05d2f02e..0000000000 --- a/app/lib/Firefly/Helper/Controllers/JsonInterface.php +++ /dev/null @@ -1,64 +0,0 @@ -add('name', 'The name should not be this short.'); - } - if (strlen($data['name']) > 250) { - $errors->add('name', 'The name should not be this long.'); - } - if (! isset($data['id'])) { - $count = \Auth::user()->recurringtransactions()->whereName($data['name'])->count(); - } else { - $count = \Auth::user()->recurringtransactions()->whereName($data['name'])->where('id', '!=', $data['id'])->count(); - } - if ($count > 0) { - $errors->add('name', 'A recurring transaction with this name already exists.'); - } - if (count($errors->get('name')) == 0) { - $successes->add('name', 'OK!'); - } - - /* - * Match - */ - if (count(explode(',', $data['match'])) > 10) { - $warnings->add('match', 'This many matches is pretty pointless'); - } - if (strlen($data['match']) == 0) { - $errors->add('match', 'Cannot match on nothing.'); - } - if (count($errors->get('match')) == 0) { - $successes->add('match', 'OK!'); - } - - /* - * Amount - */ - if (floatval($data['amount_max']) == 0 && floatval($data['amount_min']) == 0) { - $errors->add('amount_min', 'Amount max and min cannot both be zero.'); - $errors->add('amount_max', 'Amount max and min cannot both be zero.'); - } - - if (floatval($data['amount_max']) < floatval($data['amount_min'])) { - $errors->add('amount_max', 'Amount max must be more than amount min.'); - } - - if (floatval($data['amount_min']) > floatval($data['amount_max'])) { - $errors->add('amount_max', 'Amount min must be less than amount max.'); - } - if (count($errors->get('amount_min')) == 0) { - $successes->add('amount_min', 'OK!'); - } - if (count($errors->get('amount_max')) == 0) { - $successes->add('amount_max', 'OK!'); - } - - - /* - * Date - */ - try { - $date = new Carbon($data['date']); - } catch (Exception $e) { - $errors->add('date', 'The date entered was invalid'); - } - if (strlen($data['date']) == 0) { - $errors->add('date', 'The date entered was invalid'); - } - if (!$errors->has('date')) { - $successes->add('date', 'OK!'); - } - - $successes->add('active', 'OK!'); - $successes->add('automatch', 'OK!'); - - if (intval($data['skip']) < 0) { - $errors->add('skip', 'Cannot be below zero.'); - } else if (intval($data['skip']) > 31) { - $errors->add('skip', 'Cannot be above 31.'); - } - if (count($errors->get('skip')) == 0) { - $successes->add('skip', 'OK!'); - } - - $set = \Config::get('firefly.budget_periods'); - if (!in_array($data['repeat_freq'], $set)) { - $errors->add('repeat_freq', 'Invalid value.'); - } - if (count($errors->get('repeat_freq')) == 0) { - $successes->add('repeat_freq', 'OK!'); - } - - return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; - - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Controllers/RecurringInterface.php b/app/lib/Firefly/Helper/Controllers/RecurringInterface.php deleted file mode 100644 index b14183201c..0000000000 --- a/app/lib/Firefly/Helper/Controllers/RecurringInterface.php +++ /dev/null @@ -1,15 +0,0 @@ -transactionjournals()->withRelevantData()->where( - function ($q) use ($words) { - foreach ($words as $word) { - $q->orWhere('description', 'LIKE', '%' . e($word) . '%'); - } - } - )->get(); - } - - /** - * @param array $words - * - * @return Collection - */ - public function searchAccounts(array $words) - { - return \Auth::user()->accounts()->with('accounttype')->where( - function ($q) use ($words) { - foreach ($words as $word) { - $q->orWhere('name', 'LIKE', '%' . e($word) . '%'); - } - } - )->get(); - } - - /** - * @param array $words - * - * @return Collection - */ - public function searchCategories(array $words) - { - /** @var Collection $set */ - $set = \Auth::user()->categories()->get(); - $newSet = $set->filter( - function (\Category $c) use ($words) { - $found = 0; - foreach ($words as $word) { - if (!(strpos(strtolower($c->name), strtolower($word)) === false)) { - $found++; - } - } - return $found > 0; - } - ); - return $newSet; - } - - /** - * @param array $words - * - * @return Collection - */ - public function searchBudgets(array $words) - { - /** @var Collection $set */ - $set = \Auth::user()->budgets()->get(); - $newSet = $set->filter( - function (\Budget $b) use ($words) { - $found = 0; - foreach ($words as $word) { - if (!(strpos(strtolower($b->name), strtolower($word)) === false)) { - $found++; - } - } - return $found > 0; - } - ); - return $newSet; - } - - /** - * @param array $words - * - * @return Collection - */ - public function searchTags(array $words) - { - return new Collection; - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Controllers/SearchInterface.php b/app/lib/Firefly/Helper/Controllers/SearchInterface.php deleted file mode 100644 index 2af4e8918f..0000000000 --- a/app/lib/Firefly/Helper/Controllers/SearchInterface.php +++ /dev/null @@ -1,36 +0,0 @@ -_journals = $journals; - $this->_categories = $categories; - $this->_budgets = $budgets; - $this->_piggybanks = $piggybanks; - $this->_accounts = $accounts; - $this->overruleUser(\Auth::user()); - } - - /** - * @param \User $user - * - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - $this->_journals->overruleUser($user); - $this->_categories->overruleUser($user); - $this->_budgets->overruleUser($user); - $this->_piggybanks->overruleUser($user); - $this->_accounts->overruleUser($user); - return true; - } - - /** - * @param \TransactionJournal $journal - * @param array $data - * - * @return MessageBag|\TransactionJournal - */ - public function update(\TransactionJournal $journal, array $data) - { - /* - * Update the journal using the repository. - */ - $journal = $this->_journals->update($journal, $data); - - /* - * If invalid, return the message bag: - */ - if (!$journal->validate()) { - return $journal->errors(); - } - - /* - * find budget using repository - */ - - if (isset($data['budget_id'])) { - $budget = $this->_budgets->find($data['budget_id']); - } - - /* - * find category using repository - */ - $category = $this->_categories->firstOrCreate($data['category']); - - /* - * Find piggy bank using repository: - */ - $piggybank = null; - if (isset($data['piggybank_id'])) { - $piggybank = $this->_piggybanks->find($data['piggybank_id']); - } - - /* - * save accounts using repositories - * this depends on the kind of transaction and i've yet to fix this. - */ - - if (isset($data['account_id'])) { - $from = $this->_accounts->findAssetAccountById($data['account_id']); - } - if (isset($data['expense_account'])) { - $to = $this->_accounts->findExpenseAccountByName($data['expense_account']); - } - if (isset($data['revenue_account'])) { - $from = $this->_accounts->findRevenueAccountByName($data['revenue_account']); - $to = $this->_accounts->findAssetAccountById($data['account_id']); - } - if (isset($data['account_from_id'])) { - $from = $this->_accounts->findAssetAccountById($data['account_from_id']); - } - if (isset($data['account_to_id'])) { - $to = $this->_accounts->findAssetAccountById($data['account_to_id']); - } - - - /* - * Add a custom error when they are the same. - */ - if ($to->id == $from->id) { - $bag = new MessageBag; - $bag->add('account_from_id', 'The account from cannot be the same as the account to.'); - return $bag; - } - - /* - * Check if the transactions need new data: - */ - $transactions = $journal->transactions()->orderBy('amount', 'ASC')->get(); - /** @var \Transaction $transaction */ - foreach ($transactions as $index => $transaction) { - switch (true) { - case ($index == 0): // FROM account - $transaction->account()->associate($from); - $transaction->amount = floatval($data['amount']) * -1; - break; - case ($index == 1): // TO account. - $transaction->account()->associate($to); - $transaction->amount = floatval($data['amount']); - break; - } - $transaction->save(); - // either way, try to attach the piggy bank: - if (!is_null($piggybank)) { - if ($piggybank->account_id == $transaction->account_id) { - $transaction->piggybank()->associate($piggybank); - } - } - } - - /* - * Connect budget and category: - */ - $budgetids = !isset($budget) || (isset($budget) && is_null($budget)) ? [] : [$budget->id]; - $catids = is_null($category) ? [] : [$category->id]; - $components = array_merge($budgetids,$catids); - $journal->components()->sync($components); - $journal->save(); - - if (isset($data['return_journal']) && $data['return_journal'] == true) { - return $journal; - } - return $journal->errors(); - - } - - /** - * Returns messages about the validation. - * - * @param array $data - * @return array - * @throws FireflyException - */ - public function validate(array $data) - { - $errors = new MessageBag; - $warnings = new MessageBag; - $successes = new MessageBag; - - /* - * Description: - */ - if (strlen($data['description']) == 0) { - $errors->add('description', 'The description should not be this short.'); - } - if (strlen($data['description']) > 250) { - $errors->add('description', 'The description should not be this long.'); - } - - /* - * Amount - */ - if (floatval($data['amount']) <= 0) { - $errors->add('amount', 'The amount cannot be zero or less than zero.'); - } - if (floatval($data['amount']) > 10000) { - $warnings->add('amount', 'OK, but that\'s a lot of money dude.'); - } - - /* - * Date - */ - try { - $date = new Carbon($data['date']); - } catch (Exception $e) { - $errors->add('date', 'The date entered was invalid'); - } - if (strlen($data['date']) == 0) { - $errors->add('date', 'The date entered was invalid'); - } - if (!$errors->has('date')) { - $successes->add('date', 'OK!'); - } - - /* - * Category - */ - $category = $this->_categories->findByName($data['category']); - if (strlen($data['category']) == 0) { - $warnings->add('category', 'No category will be created.'); - } else { - if (is_null($category)) { - $warnings->add('category', 'Will have to be created.'); - } else { - $successes->add('category', 'OK!'); - } - } - - switch ($data['what']) { - default: - throw new FireflyException('Cannot validate a ' . $data['what']); - break; - case 'deposit': - /* - * Tests for deposit - */ - // asset account - $accountId = isset($data['account_id']) ? intval($data['account_id']) : 0; - $account = $this->_accounts->find($accountId); - if (is_null($account)) { - $errors->add('account_id', 'Cannot find this asset account.'); - } else { - $successes->add('account_id', 'OK!'); - } - - // revenue account: - if (strlen($data['revenue_account']) == 0) { - $warnings->add('revenue_account', 'Revenue account will be "cash".'); - } else { - $exp = $this->_accounts->findRevenueAccountByName($data['revenue_account'], false); - if (is_null($exp)) { - $warnings->add('revenue_account', 'Expense account will be created.'); - } else { - $successes->add('revenue_account', 'OK!'); - } - } - - break; - case 'transfer': - // account from - $accountId = isset($data['account_from_id']) ? intval($data['account_from_id']) : 0; - $account = $this->_accounts->find($accountId); - if (is_null($account)) { - $errors->add('account_from_id', 'Cannot find this asset account.'); - } else { - $successes->add('account_from_id', 'OK!'); - } - unset($accountId); - // account to - $accountId = isset($data['account_to_id']) ? intval($data['account_to_id']) : 0; - $account = $this->_accounts->find($accountId); - if (is_null($account)) { - $errors->add('account_to_id', 'Cannot find this asset account.'); - } else { - $successes->add('account_to_id', 'OK!'); - } - unset($accountId); - - // piggy bank - $piggybankId = isset($data['piggybank_id']) ? intval($data['piggybank_id']) : 0; - $piggybank = $this->_piggybanks->find($piggybankId); - if (is_null($piggybank)) { - $warnings->add('piggybank_id', 'No piggy bank will be modified.'); - } else { - $successes->add('piggybank_id', 'OK!'); - } - - break; - case 'withdrawal': - /* - * Tests for withdrawal - */ - // asset account - $accountId = isset($data['account_id']) ? intval($data['account_id']) : 0; - $account = $this->_accounts->find($accountId); - if (is_null($account)) { - $errors->add('account_id', 'Cannot find this asset account.'); - } else { - $successes->add('account_id', 'OK!'); - } - - // expense account - if (strlen($data['expense_account']) == 0) { - $warnings->add('expense_account', 'Expense account will be "cash".'); - } else { - $exp = $this->_accounts->findExpenseAccountByName($data['expense_account'], false); - if (is_null($exp)) { - $warnings->add('expense_account', 'Expense account will be created.'); - } else { - $successes->add('expense_account', 'OK!'); - } - } - - // budget - if (!isset($data['budget_id']) || (isset($data['budget_id']) && intval($data['budget_id']) == 0)) { - $warnings->add('budget_id', 'No budget selected.'); - } else { - $budget = $this->_budgets->find(intval($data['budget_id'])); - if (is_null($budget)) { - $errors->add('budget_id', 'This budget does not exist'); - } else { - $successes->add('budget_id', 'OK!'); - } - } - - break; - } - - if (count($errors->get('description')) == 0) { - $successes->add('description', 'OK!'); - } - - if (count($errors->get('amount')) == 0) { - $successes->add('amount', 'OK!'); - } - - return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes]; - /* - * Tests for deposit - */ - /* - * Tests for transfer - */ - - } - - /** - * Store a full transaction journal and associated stuff - * - * @param array $data - * - * @return MessageBag|\TransactionJournal - * - * @SuppressWarnings(PHPMD.ShortVariable) - */ - public function store(array $data) - { - /* - * save journal using repository - */ - $journal = $this->_journals->store($data); - - /* - * If invalid, return the message bag: - */ - if (!$journal->validate()) { - return $journal->errors(); - } - - /* - * find budget using repository - */ - if (isset($data['budget_id'])) { - $budget = $this->_budgets->find($data['budget_id']); - } - - /* - * find category using repository - */ - $category = $this->_categories->firstOrCreate($data['category']); - - /* - * Find piggy bank using repository: - */ - $piggybank = null; - if (isset($data['piggybank_id'])) { - $piggybank = $this->_piggybanks->find($data['piggybank_id']); - } - - /* - * save accounts using repositories - * this depends on the kind of transaction and i've yet to fix this. - */ - if (isset($data['account_id'])) { - $from = $this->_accounts->findAssetAccountById($data['account_id']); - } - if (isset($data['expense_account'])) { - $to = $this->_accounts->findExpenseAccountByName($data['expense_account']); - - } - if (isset($data['revenue_account'])) { - $from = $this->_accounts->findRevenueAccountByName($data['revenue_account']); - $to = $this->_accounts->findAssetAccountById($data['account_id']); - } - if (isset($data['account_from_id'])) { - $from = $this->_accounts->findAssetAccountById($data['account_from_id']); - } - if (isset($data['account_to_id'])) { - $to = $this->_accounts->findAssetAccountById($data['account_to_id']); - } - - /* - * Add a custom error when they are the same. - */ - if ($to->id == $from->id) { - $bag = new MessageBag; - $bag->add('account_from_id', 'The account from cannot be the same as the account to.'); - return $bag; - } - - /* - * Save transactions using repository. We try to connect the (possibly existing) - * piggy bank to either transaction, knowing it will only work with one of them. - */ - /** @var \Transaction $one */ - $one = $this->_journals->saveTransaction($journal, $from, floatval($data['amount']) * -1); - $one->connectPiggybank($piggybank); - $two = $this->_journals->saveTransaction($journal, $to, floatval($data['amount'])); - $two->connectPiggybank($piggybank); - /* - * Count for $journal is zero? Then there were errors! - */ - if ($journal->transactions()->count() < 2) { - /* - * Join message bags and return them: - */ - $bag = $one->errors(); - $bag->merge($two->errors()); - return $bag; - } - - /* - * Connect budget, category and piggy bank: - */ - if (isset($budget) && !is_null($budget)) { - $journal->budgets()->save($budget); - } - if (!is_null($category)) { - $journal->categories()->save($category); - } - $journal->completed = true; - $journal->save(); - - /* - * Trigger recurring transaction event. - */ - \Event::fire('journals.store',[$journal]); - - if (isset($data['return_journal']) && $data['return_journal'] == true) { - return ['journal' => $journal, 'messagebag' => $journal->errors()]; - } - return $journal->errors(); - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Controllers/TransactionInterface.php b/app/lib/Firefly/Helper/Controllers/TransactionInterface.php deleted file mode 100644 index 0c481b1494..0000000000 --- a/app/lib/Firefly/Helper/Controllers/TransactionInterface.php +++ /dev/null @@ -1,48 +0,0 @@ -reset = $reset; - $user->forceSave(); - $email = $user->email; - $data = ['reset' => $reset]; - - \Mail::send( - ['emails.user.verify-html', 'emails.user.verify-text'], $data, function ($message) use ($email) { - $message->to($email, $email)->subject('Verify your e-mail address.'); - } - ); - } - - /** - * @param \User $user - * - * @return mixed|void - */ - public function sendPasswordMail(\User $user) - { - - $password = \Str::random(12); - $user->password = $password; - $user->reset = \Str::random(32); // new one. - $user->forceSave(); - $email = $user->email; - - - $data = ['password' => $password]; - \Mail::send( - ['emails.user.register-html', 'emails.user.register-text'], $data, function ($message) use ($email) { - $message->to($email, $email)->subject('Welcome to Firefly!'); - } - ); - } - - /** - * @param \User $user - * - * @return mixed|void - */ - public function sendResetVerification(\User $user) - { - $reset = \Str::random(32); - $user->reset = $reset; - $user->forceSave(); - $email = $user->email; - - $data = ['reset' => $reset]; - \Mail::send( - ['emails.user.remindme-html', 'emails.user.remindme-text'], $data, function ($message) use ($email) { - $message->to($email, $email)->subject('Forgot your password?'); - } - ); - - - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Email/EmailHelperInterface.php b/app/lib/Firefly/Helper/Email/EmailHelperInterface.php deleted file mode 100644 index 48a49d0d02..0000000000 --- a/app/lib/Firefly/Helper/Email/EmailHelperInterface.php +++ /dev/null @@ -1,34 +0,0 @@ -app->bind( - 'Firefly\Helper\Controllers\AccountInterface', - 'Firefly\Helper\Controllers\Account' - ); - $this->app->bind( - 'Firefly\Helper\Controllers\ChartInterface', - 'Firefly\Helper\Controllers\Chart' - ); - - $this->app->bind( - 'Firefly\Helper\Controllers\JsonInterface', - 'Firefly\Helper\Controllers\Json' - ); - - $this->app->bind( - 'Firefly\Helper\Controllers\RecurringInterface', - 'Firefly\Helper\Controllers\Recurring' - ); - - $this->app->bind( - 'Firefly\Helper\Controllers\SearchInterface', - 'Firefly\Helper\Controllers\Search' - ); - - $this->app->bind( - 'Firefly\Helper\Controllers\TransactionInterface', - 'Firefly\Helper\Controllers\Transaction' - ); - - $this->app->bind( - 'Firefly\Helper\Controllers\CategoryInterface', - 'Firefly\Helper\Controllers\Category' - ); - - $this->app->bind( - 'Firefly\Helper\Controllers\BudgetInterface', - 'Firefly\Helper\Controllers\Budget' - ); - - // mail: - $this->app->bind( - 'Firefly\Helper\Email\EmailHelperInterface', - 'Firefly\Helper\Email\EmailHelper' - ); - - // settings: - $this->app->bind( - 'Firefly\Helper\Preferences\PreferencesHelperInterface', - 'Firefly\Helper\Preferences\PreferencesHelper' - ); - // settings: - $this->app->bind( - 'Firefly\Helper\Toolkit\ToolkitInterface', - 'Firefly\Helper\Toolkit\Toolkit' - ); - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Preferences/PreferencesHelper.php b/app/lib/Firefly/Helper/Preferences/PreferencesHelper.php deleted file mode 100644 index e212fca757..0000000000 --- a/app/lib/Firefly/Helper/Preferences/PreferencesHelper.php +++ /dev/null @@ -1,58 +0,0 @@ -id)->where('name', $name)->first(); - if (is_null($default) && is_null($pref)) { - // return NULL - return null; - } - if (!is_null($pref)) { - return $pref; - } - if (!is_null($default) && is_null($pref)) { - // create preference, return that: - return $this->set($name, $default); - } - - return null; - - } - - /** - * @param $name - * @param $value - * - * @return mixed|\Preference - */ - public function set($name, $value) - { - $pref = \Preference::where('user_id', \Auth::user()->id)->where('name', $name)->first(); - if (is_null($pref)) { - $pref = new \Preference; - $pref->name = $name; - $pref->user()->associate(\Auth::user()); - - } - $pref->data = $value; - $pref->save(); - - - return $pref; - - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Preferences/PreferencesHelperInterface.php b/app/lib/Firefly/Helper/Preferences/PreferencesHelperInterface.php deleted file mode 100644 index cb6d279825..0000000000 --- a/app/lib/Firefly/Helper/Preferences/PreferencesHelperInterface.php +++ /dev/null @@ -1,29 +0,0 @@ -_getRange(); - #\Log::debug('Range is: ' . $range); - $start = \Session::has('start') ? \Session::get('start') : new Carbon; - - #\Log::debug('Session start is: ' . $start->format('Y-m-d')); - $end = \Session::has('end') ? \Session::get('end') : new Carbon; - #\Log::debug('Session end is : ' . $end->format('Y-m-d')); - - /* - * Force start date to at the start of the $range. - * Ie. the start of the week, month, year. - */ - $start = $this->_updateStartDate($range, $start); - #\Log::debug('After update, session start is: ' . $start->format('Y-m-d')); - - /* - * Force end date to at the END of the $range. Always based on $start. - * Ie. the END of the week, month, year. - */ - $end = $this->_updateEndDate($range, $start); - #\Log::debug('After update, session end is : ' . $end->format('Y-m-d')); - - /* - * get the name of the month, depending on the range. Purely for astetics - */ - $period = $this->_periodName($range, $start); - - /* - * Get the date for the previous and next period. - * Ie. next week, next month, etc. - */ - $prev = $this->_previous($range, clone $start); - $next = $this->_next($range, clone $start); - - /* - * Save everything in the session: - */ - \Session::put('start', $start); - \Session::put('end', $end); - \Session::put('range', $range); - \Session::put('period', $period); - \Session::put('prev', $this->_periodName($range, $prev)); - \Session::put('next', $this->_periodName($range, $next)); - return null; - - } - - /** - * - */ - public function checkImportJobs() - { - /* - * Get all jobs. - */ - /** @var \Importmap $importJob */ - $importJob = \Importmap::where('user_id', \Auth::user()->id) - ->where('totaljobs', '>', \DB::Raw('`jobsdone`')) - ->orderBy('created_at', 'DESC') - ->first(); - if (!is_null($importJob)) { - $diff = intval($importJob->totaljobs) - intval($importJob->jobsdone); - $date = new Carbon; - $today = new Carbon; - $date->addSeconds($diff); - \Session::put('job_pct', $importJob->pct()); - \Session::put('job_text', $date->diffForHumans()); - } else { - \Session::forget('job_pct'); - \Session::forget('job_text'); - } - } - - protected function _getRange() - { - if (!is_null(\Session::get('range'))) { - $range = \Session::get('range'); - } else { - /** @noinspection PhpUndefinedClassInspection */ - $preferences = \App::make('Firefly\Helper\Preferences\PreferencesHelperInterface'); - $viewRange = $preferences->get('viewRange', '1M'); - - // default range: - $range = $viewRange->data; - \Session::put('range', $range); - } - return $range; - - } - - /** - * @param $range - * @param Carbon $start - * - * @return Carbon - */ - protected function _updateStartDate($range, Carbon $start) - { - switch ($range) { - case '1D': - $start->startOfDay(); - break; - case '1W': - $start->startOfWeek(); - break; - case '1M': - $start->startOfMonth(); - break; - case '3M': - $start->firstOfQuarter(); - break; - case '6M': - if (intval($start->format('m')) >= 7) { - $start->startOfYear()->addMonths(6); - } else { - $start->startOfYear(); - } - break; - case '1Y': - $start->startOfYear(); - break; - } - - return $start; - - } - - /** - * @param $range - * @param Carbon $start - * @param Carbon $end - * - * @return Carbon - */ - protected function _updateEndDate($range, Carbon $start) - { - $end = clone $start; - switch ($range) { - default: - throw new FireflyException('_updateEndDate cannot handle $range ' . $range); - break; - case '1D': - $end->endOfDay(); - break; - case '1W': - $end->endOfWeek(); - break; - case '1M': - $end->endOfMonth(); - break; - case '3M': - $end->lastOfQuarter(); - break; - case '6M': - if (intval($start->format('m')) >= 7) { - $end->endOfYear(); - } else { - $end->startOfYear()->addMonths(6); - } - break; - case '1Y': - $end->endOfYear(); - break; - - } - - return $end; - } - - protected function _periodName($range, Carbon $date) - { - switch ($range) { - default: - throw new FireflyException('No _periodName() for range "' . $range . '"'); - break; - case '1D': - return $date->format('jS F Y'); - break; - case '1W': - return 'week ' . $date->format('W, Y'); - break; - case '1M': - return $date->format('F Y'); - break; - case '3M': - $month = intval($date->format('m')); - return 'Q' . ceil(($month / 12) * 4) . ' ' . $date->format('Y'); - break; - case '6M': - $month = intval($date->format('m')); - $half = ceil(($month / 12) * 2); - $halfName = $half == 1 ? 'first' : 'second'; - return $halfName . ' half of ' . $date->format('d-m-Y'); - break; - case '1Y': - return $date->format('Y'); - break; - - - } - } - - protected function _previous($range, Carbon $date) - { - switch ($range) { - default: - throw new FireflyException('Cannot do _previous() on ' . $range); - break; - case '1D': - $date->startOfDay()->subDay(); - break; - case '1W': - $date->startOfWeek()->subWeek(); - break; - case '1M': - $date->startOfMonth()->subMonth(); - break; - case '3M': - $date->firstOfQuarter()->subMonths(3)->firstOfQuarter(); - break; - case '6M': - $month = intval($date->format('m')); - if ($month <= 6) { - $date->startOfYear()->subMonths(6); - } else { - $date->startOfYear(); - } - break; - case '1Y': - $date->startOfYear()->subYear(); - break; - - } - return $date; - } - - protected function _next($range, Carbon $date) - { - switch ($range) { - case '1D': - $date->endOfDay()->addDay(); - break; - case '1W': - $date->endOfWeek()->addDay()->startOfWeek(); - break; - case '1M': - $date->endOfMonth()->addDay()->startOfMonth(); - break; - case '3M': - $date->lastOfQuarter()->addDay(); - break; - case '6M': - if (intval($date->format('m')) >= 7) { - $date->startOfYear()->addYear(); - } else { - $date->startOfYear()->addMonths(6); - } - break; - case '1Y': - $date->startOfYear()->addYear(); - break; - default: - throw new FireflyException('Cannot do _next() on ' . $range); - break; - } - return $date; - } - - public function next() - { - /* - * Get the start date and the range from the session - */ - $range = $this->_getRange(); - $start = \Session::get('start'); - - /* - * Add some period to $start. - */ - $next = $this->_next($range, clone $start); - - /* - * Save in session: - */ - \Session::put('start', $next); - return true; - } - - public function prev() - { - /* - * Get the start date and the range from the session - */ - $range = $this->_getRange(); - $start = \Session::get('start'); - - /* - * Substract some period to $start. - */ - $prev = $this->_previous($range, clone $start); - - /* - * Save in session: - */ - \Session::put('start', $prev); - return true; - } - - /** - * Takes any collection and tries to make a sensible select list compatible array of it. - * - * @param Collection $set - * @param null $titleField - * - * @return mixed - */ - public function makeSelectList(Collection $set, $titleField = null) - { - $selectList = []; - /** @var Model $entry */ - foreach ($set as $entry) { - $id = intval($entry->id); - $title = null; - if (is_null($titleField)) { - // try 'title' field. - if (isset($entry->title)) { - $title = $entry->title; - } - // try 'name' field - if (is_null($title)) { - $title = $entry->name; - } - - // try 'description' field - if (is_null($title)) { - $title = $entry->description; - } - } else { - $title = $entry->$titleField; - } - $selectList[$id] = $title; - } - return $selectList; - } - - /** - * @param string $start - * @param string $end - * @param int $steps - */ - public function colorRange($start, $end, $steps = 5) - { - if (strlen($start) != 6) { - throw new FireflyException('Start, ' . e($start) . ' should be a six character HTML colour.'); - } - if (strlen($end) != 6) { - throw new FireflyException('End, ' . e($end) . ' should be a six character HTML colour.'); - } - if ($steps < 1) { - throw new FireflyException('Steps must be > 1'); - } - - $start = '#' . $start; - $end = '#' . $end; - /* - * Split html colours. - */ - list($rs, $gs, $bs) = sscanf($start, "#%02x%02x%02x"); - list($re, $ge, $be) = sscanf($end, "#%02x%02x%02x"); - - $stepr = ($re - $rs) / $steps; - $stepg = ($ge - $gs) / $steps; - $stepb = ($be - $bs) / $steps; - - $return = []; - for ($i = 0; $i <= $steps; $i++) { - $cr = $rs + ($stepr * $i); - $cg = $gs + ($stepg * $i); - $cb = $bs + ($stepb * $i); - - $return[] = $this->rgb2html($cr, $cg, $cb); - } - - return $return; - } - - protected function rgb2html($r, $g = -1, $b = -1) - { - $r = dechex($r < 0 ? 0 : ($r > 255 ? 255 : $r)); - $g = dechex($g < 0 ? 0 : ($g > 255 ? 255 : $g)); - $b = dechex($b < 0 ? 0 : ($b > 255 ? 255 : $b)); - - $color = (strlen($r) < 2 ? '0' : '') . $r; - $color .= (strlen($g) < 2 ? '0' : '') . $g; - $color .= (strlen($b) < 2 ? '0' : '') . $b; - return '#' . $color; - } - - /** - * @param Carbon $currentEnd - * @param $repeatFreq - * @throws FireflyException - */ - public function endOfPeriod(Carbon $currentEnd, $repeatFreq) - { - switch ($repeatFreq) { - default: - throw new FireflyException('Cannot do getFunctionForRepeatFreq for $repeat_freq ' . $repeatFreq); - break; - case 'daily': - $currentEnd->addDay(); - break; - case 'weekly': - $currentEnd->addWeek()->subDay(); - break; - case 'monthly': - $currentEnd->addMonth()->subDay(); - break; - case 'quarterly': - $currentEnd->addMonths(3)->subDay(); - break; - case 'half-year': - $currentEnd->addMonths(6)->subDay(); - break; - case 'yearly': - $currentEnd->addYear()->subDay(); - break; - } - } - - /** - * @param Carbon $date - * @param $repeatFreq - * @param $skip - * @return Carbon - * @throws FireflyException - */ - public function addPeriod(Carbon $date, $repeatFreq, $skip) - { - $add = ($skip + 1); - switch ($repeatFreq) { - default: - throw new FireflyException('Cannot do getFunctionForRepeatFreq for $repeat_freq ' . $repeatFreq); - break; - case 'daily': - $date->addDays($add); - break; - case 'weekly': - $date->addWeeks($add); - break; - case 'monthly': - $date->addMonths($add); - break; - case 'quarterly': - $months = $add * 3; - $date->addMonths($months); - break; - case 'half-year': - $months = $add * 6; - $date->addMonths($months); - break; - case 'yearly': - $date->addYears($add); - break; - } - return $date; - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Helper/Toolkit/ToolkitInterface.php b/app/lib/Firefly/Helper/Toolkit/ToolkitInterface.php deleted file mode 100644 index aa02c9bca9..0000000000 --- a/app/lib/Firefly/Helper/Toolkit/ToolkitInterface.php +++ /dev/null @@ -1,52 +0,0 @@ -_accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); - $this->_repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - $this->_piggybanks = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface'); - - - } - - /** - * The final step in the import routine is to get all transactions which have one of their accounts - * still set to "import", which means it is a cash transaction. This routine will set them all to cash instead. - * - * If there was no account present for these accounts in the import routine (no beneficiary set), Firefly - * II would fall back to the import account. - * - * @param Job $job - * @param array $payload - */ - public function cleanImportAccount(Job $job, array $payload) - { - - /** @var \Importmap $importMap */ - $importMap = $this->_repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - // two import account types. - $importAccountType = $this->_accounts->findAccountType('Import account'); - $cashAccountType = $this->_accounts->findAccountType('Cash account'); - - // find or create import account: - $importAccount = $this->_accounts->firstOrCreate( - [ - 'name' => 'Import account', - 'account_type_id' => $importAccountType->id, - 'active' => 1, - 'user_id' => $user->id, - ] - ); - - // find or create cash account: - $cashAccount = $this->_accounts->firstOrCreate( - [ - 'name' => 'Cash account', - 'account_type_id' => $cashAccountType->id, - 'active' => 1, - 'user_id' => $user->id, - ] - ); - - // update all users transactions: - $count = \DB::table('transactions') - ->where('account_id', $importAccount->id)->count(); - - \DB::table('transactions') - ->where('account_id', $importAccount->id) - ->update(['account_id' => $cashAccount->id]); - - \Log::debug('Updated ' . $count . ' transactions from Import Account to cash.'); - $job->delete(); // no count fix - } - - /** - * @param \User $user - */ - protected function overruleUser(\User $user) - { - $this->_accounts->overruleUser($user); - $this->_repository->overruleUser($user); - $this->_piggybanks->overruleUser($user); - } - - /** - * This job queues new jobs that will connect components to their proper transactions and updates the - * expense account: categories, budgets an beneficiaries used to be components. - * - * @param Job $job - * @param array $payload - */ - public function importComponentTransaction(Job $job, array $payload) - { - /** @var \Importmap $importMap */ - $importMap = $this->_repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - /* - * Took too long to fix this: - */ - if ($job->attempts() > 10) { - \Log::error('Could not map transaction to component after 10 tries. KILL'); - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - return; - } - - - /* - * Prep some vars from the payload - */ - $transactionId = intval($payload['data']['transaction_id']); - $componentId = intval($payload['data']['component_id']); - - /* - * We don't know what kind of component we have. So we search for it. We have a specific function - * for this: - */ - $oldComponentMap = $this->_repository->findImportComponentMap($importMap, $componentId); - - /* - * If the map is null, the component (whatever it is) is not imported yet, and we release the job. - */ - if (is_null($oldComponentMap)) { - \Log::notice('No map for this component, release transaction/component import.'); - - /* - * When in sync, its pointless to release jobs. Simply remove them. - */ - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - - return; - } - - /* - * Switch on the class found in the map, and push a new job to update the transaction journal: - */ - switch ($oldComponentMap->class) { - default: - \Log::error('Cannot handle "' . $oldComponentMap->class . '" in component<>transaction routine!'); - $job->delete(); - break; - case 'Budget': - \Log::debug('Push job to connect budget to transaction #' . $transactionId); - \Queue::push( // count fixed - 'Firefly\Storage\Budget\BudgetRepositoryInterface@importUpdateTransaction', $payload - ); - $importMap->totaljobs++; - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - break; - case 'Category': - \Log::debug('Push job to connect category to transaction #' . $transactionId); - \Queue::push( // count fixed - 'Firefly\Storage\Category\CategoryRepositoryInterface@importUpdateTransaction', $payload - ); - - $importMap->totaljobs++; - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - break; - case 'Account': - \Log::debug('Push job to connect account to transaction #' . $transactionId); - \Queue::push( // count fixed - 'Firefly\Storage\Account\AccountRepositoryInterface@importUpdateTransaction', $payload - ); - - $importMap->totaljobs++; - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - break; - } - return; - - - } - - /** - * This job queues new jobs that will connect components to their proper transfers and updates the - * expense account: categories, budgets an beneficiaries used to be components. Even though not all - * of the transfers used to have these components, we check for them all. - * - * @param Job $job - * @param array $payload - */ - public function importComponentTransfer(Job $job, array $payload) - { - /** @var \Importmap $importMap */ - $importMap = $this->_repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - /* - * Took too long to fix this: - */ - if ($job->attempts() > 10) { - \Log::error('Could not map transaction to component after 10 tries. KILL'); - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - return; - } - - /* - * Prep some vars from the payload - */ - $transferId = intval($payload['data']['transfer_id']); - $componentId = intval($payload['data']['component_id']); - - /* - * We don't know what kind of component we have. So we search for it. We have a specific function - * for this: - */ - $oldComponentMap = $this->_repository->findImportComponentMap($importMap, $componentId); - - /* - * If the map is null, the component (whatever it is) is not imported yet, and we release the job. - */ - if (is_null($oldComponentMap)) { - \Log::notice('No map for this component, release transfer/component import.'); - /* - * When in sync, its pointless to release jobs. Simply remove them. - */ - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Switch on the class found in the map, and push a new job to update the transaction journal: - */ - switch ($oldComponentMap->class) { - default: - \Log::error('Cannot handle "' . $oldComponentMap->class . '" in component<>transfer routine!'); - $job->delete(); - break; - case 'Category': - \Log::debug('Push job to connect category to transfer #' . $transferId); - \Queue::push( // count fixed - 'Firefly\Storage\Category\CategoryRepositoryInterface@importUpdateTransfer', $payload - ); - - $importMap->totaljobs++; - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - break; - case 'Budget': - \Log::debug('Push job to connect budget to transfer #' . $transferId); - \Queue::push( // count fixed - 'Firefly\Storage\Budget\BudgetRepositoryInterface@importUpdateTransfer', $payload - ); - $importMap->totaljobs++; - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - break; - } - - - } - - /** - * This job will see if the particular setting is a 'piggyAccount' setting, - * one we need to fix all imported piggy banks. - * - * @param Job $job - * @param array $payload - */ - public function importSetting(Job $job, array $payload) - { - /** @var \Importmap $importMap */ - $importMap = $this->_repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - if ($job->attempts() > 10) { - \Log::error('No account found for piggyAccount setting after 10 tries. KILL!'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - $name = $payload['data']['name']; - switch ($name) { - default: - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed. - return; - break; - case 'piggyAccount': - - /* - * If user has this account, update all piggy banks: - */ - $accountID = intval($payload['data']['value']); - - /* - * Is account imported already? - */ - $importEntry = $this->_repository->findImportEntry($importMap, 'Account', $accountID); - - /* - * We imported this account already. - */ - if ($importEntry) { - $all = $this->_piggybanks->get(); - $account = $this->_accounts->find($importEntry->new); - /* - * Update all piggy banks. - */ - if (!is_null($account)) { - \Log::debug('Updating all piggybanks, found the right setting.'); - foreach ($all as $piggy) { - $piggy->account()->associate($account); - unset($piggy->leftInAccount); - $piggy->save(); - } - } - } else { - \Log::notice('Account not yet imported, hold or 5 minutes.'); - /* - * When in sync, its pointless to release jobs. Simply remove them. - */ - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - } - break; - } - - // update map: - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed. - - } - - /** - * This job will loop and queue jobs for the import file; almost every set of records will be imported. - * - * @param Job $job - * @param $payload - * - * @SuppressWarnings(PHPMD.CamelCasePropertyName) - */ - public function start(Job $job, array $payload) - { - \Log::debug('Start with job "start"'); - $user = \User::find($payload['user']); - $filename = $payload['file']; - if (file_exists($filename) && !is_null($user)) { - /* - * Make an import map. Need it to refer back to import. - */ - $importMap = new \Importmap; - $importMap->user()->associate($user); - $importMap->file = $filename; - $importMap->totaljobs = 0; - $importMap->jobsdone = 0; - $importMap->save(); - - $totalJobs = 0; - - /* - * Loop over all data in the JSON file, then create jobs. - */ - $raw = file_get_contents($filename); - $JSON = json_decode($raw); - - // first import all asset accounts: - foreach ($JSON->accounts as $entry) { - \Log::debug('Create job to import asset account'); - \Queue::push( // count fixed - 'Firefly\Storage\Account\AccountRepositoryInterface@importAccount', [ - 'data' => $entry, - 'class' => 'Account', - 'account_type' => 'Asset account', - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - - // then import all beneficiaries: - foreach ($JSON->components as $entry) { - if ($entry->type->type == 'beneficiary') { - \Log::debug('Create job to import expense account'); - \Queue::push( // count fixed - 'Firefly\Storage\Account\AccountRepositoryInterface@importAccount', [ - 'data' => $entry, - 'class' => 'Account', - 'account_type' => 'Expense account', - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - } - - // then import all categories. - foreach ($JSON->components as $entry) { - if ($entry->type->type == 'category') { - \Log::debug('Create job to import category'); - \Queue::push( // count fixed - 'Firefly\Storage\Category\CategoryRepositoryInterface@importCategory', [ - 'data' => $entry, - 'class' => 'Category', - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - } - - // then import all budgets: - foreach ($JSON->components as $entry) { - if ($entry->type->type == 'budget') { - \Log::debug('Create job to import budget'); - \Queue::push( // count fixed - 'Firefly\Storage\Budget\BudgetRepositoryInterface@importBudget', [ - 'data' => $entry, - 'class' => 'Budget', - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - } - - // then import all limits. - foreach ($JSON->limits as $entry) { - \Log::debug('Create job to import limit'); - \Queue::push( // count fixed - 'Firefly\Storage\Limit\LimitRepositoryInterface@importLimit', [ - 'data' => $entry, - 'class' => 'Limit', - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - - // all piggy banks - foreach ($JSON->piggybanks as $entry) { - \Log::debug('Create job to import piggy bank'); - \Queue::push( // count fixed - 'Firefly\Storage\Piggybank\PiggybankRepositoryInterface@importPiggybank', [ - 'data' => $entry, - 'class' => 'Piggybank', - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - - // all predictables. - foreach ($JSON->predictables as $entry) { - \Log::debug('Create job to import predictable'); - \Queue::push( // count fixed - 'Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface@importPredictable', [ - 'data' => $entry, - 'class' => 'Predictable', - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - - // all settings (to fix the piggy banks) - foreach ($JSON->settings as $entry) { - \Log::debug('Create job to import setting'); - \Queue::push( // count fixed - 'Firefly\Queue\Import@importSetting', [ - 'data' => $entry, - 'class' => 'Setting', - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - - // all transactions - foreach ($JSON->transactions as $entry) { - - \Log::debug('Create job to import transaction'); - \Queue::push( // count fixed - 'Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface@importTransaction', [ - 'data' => $entry, - 'class' => 'Transaction', - 'mapID' => $importMap->id - ] - ); - - $totalJobs++; - } - - // all transfers - foreach ($JSON->transfers as $entry) { - \Log::debug('Create job to import transfer'); - \Queue::push( // count fixed - 'Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface@importTransfer', [ - 'data' => $entry, - 'class' => 'Transfer', - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - - // then, fix all component <> transaction links - foreach ($JSON->component_transaction as $entry) { - \Log::debug('Create job to import components_transaction'); - \Queue::push( // count fixed - 'Firefly\Queue\Import@importComponentTransaction', - [ - 'data' => $entry, - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - - - // then, fix all component <> transfer links - foreach ($JSON->component_transfer as $entry) { - \Log::debug('Create job to import components_transfer'); - \Queue::push( // count fixed - 'Firefly\Queue\Import@importComponentTransfer', - [ - 'data' => $entry, - 'mapID' => $importMap->id - ] - ); - $totalJobs++; - } - - $importMap->totaljobs = $totalJobs; - $importMap->save(); - /* - * We save the import map which now holds the number of jobs we've got planned. - */ - - \Queue::push('Firefly\Queue\Import@cleanImportAccount', ['mapID' => $importMap->id]); - - $job->delete(); // count fixed - - \Log::debug('Done with job "start"'); - } - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php b/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php deleted file mode 100644 index 147aacaaff..0000000000 --- a/app/lib/Firefly/Storage/Account/AccountRepositoryInterface.php +++ /dev/null @@ -1,146 +0,0 @@ -_user = \Auth::user(); - } - - /** - * @return mixed - */ - public function count() - { - return $this->_user->accounts()->count(); - - } - - /** - * @param \Account $account - * - * @return bool|mixed - */ - public function destroy(\Account $account) - { - // find all transaction journals related to this account: - $journals = \TransactionJournal::withRelevantData()->accountIs($account)->get(['transaction_journals.*']); - $accountIDs = []; - - /** @var \TransactionJournal $journal */ - foreach ($journals as $journal) { - // remember the account id's of the transactions involved: - foreach ($journal->transactions as $t) { - $accountIDs[] = $t->account_id; - } - $journal->delete(); - - } - $accountIDs = array_unique($accountIDs); - if (count($accountIDs) > 0) { - // find the "initial balance" type accounts in this list. Should be just 1. - $query = $this->_user->accounts()->accountTypeIn(['Initial balance account']) - ->whereIn('accounts.id', $accountIDs); - if ($query->count() == 1) { - $iba = $query->first(['accounts.*']); - $iba->delete(); - } - } - $account->delete(); - - /** - * - * - * Also delete: initial balance, initial balance account, and transactions - */ - - return true; - } - - /** - * @param $id - * - * @return |Account|null - */ - public function findAssetAccountById($id) - { - return $this->_user->accounts()->find($id); - } - - /** - * This method finds the expense account mentioned by name. This method is a sneaky little hobbits, - * because when you feed it "Import account" it will always return an import account of that type. - * - * @param $name - * @param $create - * - * @return null|\Account - */ - public function findExpenseAccountByName($name, $create = true) - { - $cashType = $this->findAccountType('Cash account'); - $importType = $this->findAccountType('Import account'); - // catch Import account: - if ($name == 'Import account') { - - $import = $this->firstOrCreate( - [ - 'name' => 'Import account', - 'user_id' => $this->_user->id, - 'account_type_id' => $importType->id, - 'active' => 1 - ] - ); - return $import; - } - - // find account: - - $account = $this->_user->accounts()->where('name', $name)->accountTypeIn( - ['Expense account', 'Beneficiary account'] - )->first(['accounts.*']); - - // create if not found: - if (strlen($name) > 0 && is_null($account) && $create === true) { - $type = $this->findAccountType('Expense account'); - $set = [ - 'name' => $name, - 'user_id' => $this->_user->id, - 'active' => 1, - 'account_type_id' => $type->id - ]; - $account = $this->firstOrCreate($set); - } else if (strlen($name) > 0 && is_null($account) && $create === false) { - return null; - } - - - // find cash account as fall back: - if (is_null($account)) { - - $account = $this->_user->accounts()->where('account_type_id', $cashType->id)->first(); - } - - // create cash account as ultimate fall back: - if (is_null($account)) { - $set = [ - 'name' => 'Cash account', - 'user_id' => $this->_user->id, - 'active' => 1, - 'account_type_id' => $cashType->id - ]; - $account = $this->firstOrCreate($set); - } - - if ($account->active == 0 && $account->account_type_id != $cashType->id) { - return null; - } - - return $account; - } - - /** - * @param $type - * - * @return \AccountType|null - */ - public function findAccountType($type) - { - return \AccountType::where('type', $type)->first(); - } - - public function firstOrCreate(array $data) - { - return \Account::firstOrCreate($data); - } - - /** - * @param $name - * @param $create - * - * @return |Account|null - */ - public function findRevenueAccountByName($name, $create = true) - { - // catch Import account: - if ($name == 'Import account') { - $importType = $this->findAccountType('Import account'); - $import = $this->firstOrCreate( - [ - 'name' => 'Import account', - 'user_id' => $this->_user->id, - 'account_type_id' => $importType->id, - 'active' => 1 - ] - ); - return $import; - } - - // find account: - $type = $this->findAccountType('Revenue account'); - $account = $this->_user->accounts()->where('name', $name)->where('account_type_id', $type->id)->first(); - - // create if not found: - if (strlen($name) > 0 && is_null($account) && $create === true) { - $set = [ - 'name' => $name, - 'user_id' => $this->_user->id, - 'active' => 1, - 'account_type_id' => $type->id - ]; - $account = $this->firstOrCreate($set); - } else if (strlen($name) > 0 && is_null($account) && $create === false) { - return null; - } - - // find cash account as fall back: - if (is_null($account)) { - $cashType = $this->findAccountType('Cash account'); - $account = $this->_user->accounts()->where('account_type_id', $cashType->id)->first(); - } - - // create cash account as ultimate fall back: - if (is_null($account)) { - $set = [ - 'name' => 'Cash account', - 'user_id' => $this->_user->id, - 'active' => 1, - 'account_type_id' => $cashType->id - ]; - $account = $this->firstOrCreate($set); - } - - if ($account->active == 0) { - return null; - } - - return $account; - } - - public function getByAccountType(\AccountType $type) - { - return $this->_user->accounts()->with('accounttype')->orderBy('name', 'ASC') - ->where('account_type_id', $type->id)->get(); - } - - /** - * @param $ids - * - * @return array|mixed - */ - public function getByIds(array $ids) - { - if (count($ids) > 0) { - return $this->_user->accounts()->with('accounttype')->whereIn('id', $ids)->orderBy('name', 'ASC')->get(); - } else { - return $this->getActiveDefault(); - } - } -// -// /** -// * @param $name -// * -// * @return \Account|mixed|null -// */ -// public function createOrFindBeneficiary($name) -// { -// if (is_null($name) || strlen($name) == 0) { -// return null; -// } -// $type = \AccountType::where('type', 'Expense account')->first(); -// return $this->createOrFind($name, $type); -// } -// -// /** -// * @param $name -// * @param \AccountType $type -// * -// * @return \Account|mixed -// */ -// public function createOrFind($name, \AccountType $type = null) -// { -// $account = $this->findByName($name, $type); -// if (!$account) { -// $data = [ -// 'name' => $name, -// 'account_type' => $type -// ]; -// -// return $this->store($data); -// } -// -// return $account; -// } -// -// /** -// * @param $name -// * @param \AccountType $type -// * -// * @return mixed -// */ -// public function findByName($name, \AccountType $type = null) -// { -// $type = is_null($type) ? \AccountType::where('type', 'Asset account')->first() : $type; -// -// return $this->_user->accounts()->where('account_type_id', $type->id) -// ->where('name', 'like', '%' . $name . '%') -// ->first(); -// } - - /** - * @return mixed - */ - public function getActiveDefault() - { - return $this->_user->accounts()->accountTypeIn(['Default account', 'Asset account'])->where( - 'accounts.active', 1 - ) - ->get(['accounts.*']); - } - - /** - * @return mixed - */ - public function getDefault() - { - return $this->_user->accounts()->accountTypeIn(['Default account', 'Asset account']) - ->orderBy('accounts.name', 'ASC')->get(['accounts.*']); - } - - /** - * Gets a list of accounts that have the mentioned type. Will automatically convert - * strings in this array to actual (model) account types. - * - * @param array $types - * - * @return Collection - */ - public function getOfTypes(array $types) - { - $accounts = $this->_user->accounts()->accountTypeIn($types)->get(['accounts.*']); - return $accounts; - } - - /** - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importAccount(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - /* - * maybe Account is already imported: - */ - $importEntry = $repository->findImportEntry($importMap, 'Account', intval($payload['data']['id'])); - - /* - * if so, delete job and return: - */ - if (!is_null($importEntry)) { - \Log::debug('Already imported ' . $payload['data']['name'] . ' of type ' . $payload['account_type']); - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - return; - } - - /* - * find the payload's account type: - */ - $payload['account_type'] = isset($payload['account_type']) ? $payload['account_type'] : 'Expense account'; - $type = $this->findAccountType($payload['account_type']); - - /* - * Create data array for store() procedure. - */ - $data = [ - 'account_type' => $type, - 'name' => $payload['data']['name'], - ]; - if (isset($payload['data']['openingbalance'])) { - $data['openingbalance'] = floatval($payload['data']['openingbalance']); - $data['openingbalancedate'] = $payload['data']['openingbalancedate']; - } - if (isset($payload['data']['inactive'])) { - $data['active'] = intval($payload['data']['inactive']) == 0 ? 1 : 0; - } - - /* - * Try to store: - */ - $account = $this->store($data); - - /* - * Check for failure. - */ - if (count($account->errors()) > 0) { - \Log::error('Account creation error: ' . $account->errors()->first()); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - \Log::debug('Imported ' . $payload['account_type'] . ': ' . $payload['data']['name']); - - /* - * Save meta data - */ - $repository->store($importMap, 'Account', intval($payload['data']['id']), $account->id); - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed. - return; - } - -// /** -// * Used for import -// * -// * @param $name -// * -// * @return mixed -// */ -// public function findByNameAny($name) -// { -// return $this->_user->accounts() -// ->where('name', 'like', '%' . $name . '%') -// ->first(); -// } - - /** - * @param $data - * - * @return \Account - * @throws \Firefly\Exception\FireflyException - */ - public function store($data) - { - /** - * If the AccountType has been passed through, use it: - */ - if (isset($data['account_type']) && is_object($data['account_type']) - && get_class($data['account_type']) == 'AccountType' - ) { - $accountType = $data['account_type']; - } else if (isset($data['account_type']) && is_string($data['account_type'])) { - // if it isnt but set as string, find it: - $accountType = \AccountType::where('type', $data['account_type'])->first(); - - } else { - $accountType = \AccountType::where('type', 'Asset account')->first(); - } - $active = isset($data['active']) && intval($data['active']) >= 0 && intval($data['active']) <= 1 ? intval( - $data['active'] - ) : 1; - - /** - * Create new account: - */ - $account = new \Account; - $account->accountType()->associate($accountType); - $account->user()->associate($this->_user); - - $account->name = $data['name']; - $account->active - = isset($data['active']) && intval($data['active']) >= 0 && intval($data['active']) <= 1 ? intval( - $data['active'] - ) : 1; - - // try to save it: - try { - if ($account->save()) { - // create initial balance, if necessary: - if (isset($data['openingbalance']) && isset($data['openingbalancedate'])) { - $amount = floatval($data['openingbalance']); - $date = new Carbon($data['openingbalancedate']); - if ($amount != 0) { - $this->_createInitialBalance($account, $amount, $date); - } - } - } - } catch (QueryException $e) { - // do nothing - } - - - // whatever the result, return the account. - return $account; - } - - /** - * @param \Account $account - * @param int $amount - * @param Carbon $date - * - * @return bool - * @SuppressWarnings(PHPMD.CamelCaseMethodName) - */ - protected function _createInitialBalance(\Account $account, $amount = 0, Carbon $date) - { - /* - * The repositories we need: - */ - /** @var \Firefly\Helper\Controllers\TransactionInterface $transactions */ - $transactions = \App::make('Firefly\Helper\Controllers\TransactionInterface'); - $transactions->overruleUser($this->_user); - - - /* - * get account type: - */ - $initialBalanceAT = $this->findAccountType('Initial balance account'); - - /* - * create new account - */ - $initial = new \Account; - $initial->accountType()->associate($initialBalanceAT); - $initial->user()->associate($this->_user); - $initial->name = $account->name . ' initial balance'; - $initial->active = 0; - if ($initial->validate()) { - $initial->save(); - /* - * create new transaction journal (and transactions): - */ - - $set = [ - 'account_from_id' => $initial->id, - 'account_to_id' => $account->id, - 'description' => 'Initial Balance for ' . $account->name, - 'what' => 'Opening balance', - 'amount' => $amount, - 'category' => '', - 'date' => $date->format('Y-m-d') - ]; - $transactions->store($set); - - return true; - } - - return false; - } - - /** - * Takes a transaction/account component and updates the transaction journal to match. - * - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importUpdateTransaction(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - if ($job->attempts() > 10) { - \Log::error('Never found budget/account combination "' . $payload['data']['transaction_id'] . '"'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed. - return; - } - - /** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */ - $journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); - $journals->overruleUser($user); - - /* - * Prep some vars from the payload - */ - $transactionId = intval($payload['data']['transaction_id']); - $componentId = intval($payload['data']['component_id']); - - /* - * Find the import map for both: - */ - $accountMap = $repository->findImportEntry($importMap, 'Account', $componentId); - $transactionMap = $repository->findImportEntry($importMap, 'Transaction', $transactionId); - - /* - * Either may be null: - */ - if (is_null($accountMap) || is_null($transactionMap)) { - \Log::notice('No map found in account/transaction mapper. Release.'); - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Find the account and the transaction: - */ - $account = $this->find($accountMap->new); - /** @var \TransactionJournal $journal */ - $journal = $journals->find($transactionMap->new); - - /* - * If either is null, release: - */ - if (is_null($account) || is_null($journal)) { - \Log::notice('Map is incorrect in account/transaction mapper. Release.'); - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Update one of the journal's transactions to have the right account: - */ - $importType = $this->findAccountType('Import account'); - /** @var \Transaction $transaction */ - $updated = false; - \Log::debug( - 'Connect "' . $account->name . '" (#' . $account->id . ') to "' . $journal->description . '" (#' - . $journal->id . ')' - ); - foreach ($journal->transactions as $index => $transaction) { - /* - * If it's of the right type, update it! - */ - \Log::debug( - 'Transaction ' . $index . ' (#' . $transaction->id . '): [' . $transaction->account->account_type_id - . ' vs. ' . $importType->id . ']' - ); - if ($transaction->account->account_type_id == $importType->id) { - $transaction->account()->associate($account); - $transaction->save(); - $updated = true; - \Log::debug( - 'Connected expense account "' . $account->name . '" to journal "' . $journal->description . '"' - ); - } - } - if ($updated === false) { - \Log::error( - 'Did not connect transactions of journal #' . $journal->id . ' to expense account ' . $account->id - ); - - } - - $journal->save(); - - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - - } - - /** - * @param \User $user - * - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - return true; - } - - /** - * @param $accountId - * - * @return mixed - */ - public function find($accountId) - { - return $this->_user->accounts()->where('id', $accountId)->first(); - } - - /** - * @param \Account $account - * @param $data - * - * @return \Account|mixed - */ - public function update(\Account $account, $data) - { - // update account accordingly: - $account->name = $data['name']; - if ($account->validate()) { - $account->save(); - } - // update initial balance if necessary: - if (isset($data['openingbalance']) && floatval($data['openingbalance']) != 0) { - - /** @var \Firefly\Helper\Controllers\AccountInterface $interface */ - $interface = \App::make('Firefly\Helper\Controllers\AccountInterface'); - - if ($account->accounttype->type == 'Default account' || $account->accounttype->type == 'Asset account') { - - - $journal = $interface->openingBalanceTransaction($account); - if ($journal) { - $journal->date = new Carbon($data['openingbalancedate']); - $journal->transactions[0]->amount = floatval($data['openingbalance']) * -1; - $journal->transactions[1]->amount = floatval($data['openingbalance']); - $journal->transactions[0]->save(); - $journal->transactions[1]->save(); - $journal->save(); - } - } - } - - return $account; - } - - -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Budget/BudgetRepositoryInterface.php b/app/lib/Firefly/Storage/Budget/BudgetRepositoryInterface.php deleted file mode 100644 index 87de3a6ed9..0000000000 --- a/app/lib/Firefly/Storage/Budget/BudgetRepositoryInterface.php +++ /dev/null @@ -1,88 +0,0 @@ -_user = \Auth::user(); - } - - /** - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importBudget(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - /* - * maybe Budget is already imported: - */ - $importEntry = $repository->findImportEntry($importMap, 'Budget', intval($payload['data']['id'])); - - /* - * if so, delete job and return: - */ - if (!is_null($importEntry)) { - \Log::debug('Already imported budget ' . $payload['data']['name']); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - /* - * maybe Budget is already imported. - */ - $budget = $this->findByName($payload['data']['name']); - - if (is_null($budget)) { - /* - * Not imported yet. - */ - $budget = $this->store($payload['data']); - $repository->store($importMap, 'Budget', $payload['data']['id'], $budget->id); - \Log::debug('Imported budget "' . $payload['data']['name'] . '".'); - } else { - /* - * already imported. - */ - $repository->store($importMap, 'Budget', $payload['data']['id'], $budget->id); - \Log::debug('Already had budget "' . $payload['data']['name'] . '".'); - } - - // update map: - $importMap->jobsdone++; - $importMap->save(); - - // delete job. - $job->delete(); // count fixed - } - - /** - * @param \User $user - * - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - return true; - } - - /** - * @param $budgetName - * - * @return \Budget|null - */ - public function findByName($budgetName) - { - - return $this->_user->budgets()->whereName($budgetName)->first(); - } - - /** - * @param $data - * - * @return \Budget - */ - public function store($data) - { - $budget = new \Budget; - $budget->name = $data['name']; - $budget->user()->associate($this->_user); - $budget->save(); - - // if limit, create limit (repetition itself will be picked up elsewhere). - if (isset($data['amount']) && floatval($data['amount']) > 0) { - $startDate = new Carbon; - $limitData = [ - 'budget_id' => $budget->id, - 'startdate' => $startDate->format('Y-m-d'), - 'period' => $data['repeat_freq'], - 'amount' => floatval($data['amount']), - 'repeats' => 0 - ]; - /** @var \Firefly\Storage\Limit\LimitRepositoryInterface $limitRepository */ - $limitRepository = \App::make('Firefly\Storage\Limit\LimitRepositoryInterface'); - $limitRepository->overruleUser($this->_user); - $limit = $limitRepository->store($limitData); - \Event::fire('limits.store', [$limit]); - } - - if ($budget->validate()) { - $budget->save(); - } - - return $budget; - } - - /** - * Takes a transfer/budget component and updates the transaction journal to match. - * - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importUpdateTransfer(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - if ($job->attempts() > 10) { - \Log::error('Never found budget/transfer combination "' . $payload['data']['transfer_id'] . '"'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - - /** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */ - $journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); - $journals->overruleUser($user); - - /* - * Prep some vars from the payload - */ - $transferId = intval($payload['data']['transfer_id']); - $componentId = intval($payload['data']['component_id']); - - /* - * Find the import map for both: - */ - $budgetMap = $repository->findImportEntry($importMap, 'Budget', $componentId); - $transferMap = $repository->findImportEntry($importMap, 'Transfer', $transferId); - - /* - * Either may be null: - */ - if (is_null($budgetMap) || is_null($transferMap)) { - \Log::notice('No map found in budget/transfer mapper. Release.'); - if(\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Find the budget and the transaction: - */ - $budget = $this->find($budgetMap->new); - /** @var \TransactionJournal $journal */ - $journal = $journals->find($transferMap->new); - - /* - * If either is null, release: - */ - if (is_null($budget) || is_null($journal)) { - \Log::notice('Map is incorrect in budget/transfer mapper. Release.'); - if(\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Update journal to have budget: - */ - $journal->budgets()->save($budget); - $journal->save(); - \Log::debug('Connected budget "' . $budget->name . '" to journal "' . $journal->description . '"'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - - - return; - } - - /** - * Takes a transaction/budget component and updates the transaction journal to match. - * - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importUpdateTransaction(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - if ($job->attempts() > 10) { - \Log::error('Never found budget/transaction combination "' . $payload['data']['transaction_id'] . '"'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - - /** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */ - $journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); - $journals->overruleUser($user); - - /* - * Prep some vars from the payload - */ - $transactionId = intval($payload['data']['transaction_id']); - $componentId = intval($payload['data']['component_id']); - - /* - * Find the import map for both: - */ - $budgetMap = $repository->findImportEntry($importMap, 'Budget', $componentId); - $transactionMap = $repository->findImportEntry($importMap, 'Transaction', $transactionId); - - /* - * Either may be null: - */ - if (is_null($budgetMap) || is_null($transactionMap)) { - \Log::notice('No map found in budget/transaction mapper. Release.'); - if(\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Find the budget and the transaction: - */ - $budget = $this->find($budgetMap->new); - /** @var \TransactionJournal $journal */ - $journal = $journals->find($transactionMap->new); - - /* - * If either is null, release: - */ - if (is_null($budget) || is_null($journal)) { - \Log::notice('Map is incorrect in budget/transaction mapper. Release.'); - if(\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Update journal to have budget: - */ - $journal->budgets()->save($budget); - $journal->save(); - \Log::debug('Connected budget "' . $budget->name . '" to journal "' . $journal->description . '"'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - - - return; - } - - /** - * @param $budgetId - * - * @return \Budget|null - */ - public function find($budgetId) - { - - return $this->_user->budgets()->find($budgetId); - } - - /** - * @param \Budget $budget - * - * @return bool - */ - public function destroy(\Budget $budget) - { - $budget->delete(); - - return true; - } - - /** - * @return Collection - */ - public function get() - { - $set = $this->_user->budgets()->with( - ['limits' => function ($q) { - $q->orderBy('limits.startdate', 'DESC'); - }, 'limits.limitrepetitions' => function ($q) { - $q->orderBy('limit_repetitions.startdate', 'ASC'); - }] - )->orderBy('name', 'ASC')->get(); - return $set; - } - - /** - * @param \Budget $budget - * @param $data - * - * @return \Budget|mixed - */ - public function update(\Budget $budget, $data) - { - // update account accordingly: - $budget->name = $data['name']; - if ($budget->validate()) { - $budget->save(); - } - - return $budget; - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Category/CategoryRepositoryInterface.php b/app/lib/Firefly/Storage/Category/CategoryRepositoryInterface.php deleted file mode 100644 index 15c6785548..0000000000 --- a/app/lib/Firefly/Storage/Category/CategoryRepositoryInterface.php +++ /dev/null @@ -1,95 +0,0 @@ -_user = \Auth::user(); - } - - /** - * Takes a transfer/category component and updates the transaction journal to match. - * - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importUpdateTransfer(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - - if ($job->attempts() > 10) { - \Log::error('Never found category/transfer combination "' . $payload['data']['transfer_id'] . '"'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed. - return; - } - - - /** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */ - $journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); - $journals->overruleUser($user); - - /* - * Prep some vars from the payload - */ - $transferId = intval($payload['data']['transfer_id']); - $componentId = intval($payload['data']['component_id']); - - /* - * Find the import map for both: - */ - $categoryMap = $repository->findImportEntry($importMap, 'Category', $componentId); - $transferMap = $repository->findImportEntry($importMap, 'Transfer', $transferId); - - /* - * Either may be null: - */ - if (is_null($categoryMap) || is_null($transferMap)) { - \Log::notice('No map found in category/transfer mapper. Release.'); - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Find the budget and the transaction: - */ - $category = $this->find($categoryMap->new); - /** @var \TransactionJournal $journal */ - $journal = $journals->find($transferMap->new); - - /* - * If either is null, release: - */ - if (is_null($category) || is_null($journal)) { - \Log::notice('Map is incorrect in category/transfer mapper. Release.'); - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Update journal to have budget: - */ - $journal->categories()->save($category); - $journal->save(); - \Log::debug('Connected category "' . $category->name . '" to journal "' . $journal->description . '"'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - - - return; - } - - /** - * @param \User $user - * - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - return true; - } - - /** - * @param $categoryId - * - * @return mixed - */ - public function find($categoryId) - { - return $this->_user->categories()->find($categoryId); - } - - /** - * Takes a transaction/category component and updates the transaction journal to match. - * - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importUpdateTransaction(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - - if ($job->attempts() > 10) { - \Log::error('Never found category/transaction combination "' . $payload['data']['transaction_id'] . '"'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed. - return; - } - - - /** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */ - $journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); - $journals->overruleUser($user); - - /* - * Prep some vars from the payload - */ - $transactionId = intval($payload['data']['transaction_id']); - $componentId = intval($payload['data']['component_id']); - - /* - * Find the import map for both: - */ - $categoryMap = $repository->findImportEntry($importMap, 'Category', $componentId); - $transactionMap = $repository->findImportEntry($importMap, 'Transaction', $transactionId); - - /* - * Either may be null: - */ - if (is_null($categoryMap) || is_null($transactionMap)) { - \Log::notice('No map found in category/transaction mapper. Release.'); - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Find the budget and the transaction: - */ - $category = $this->find($categoryMap->new); - /** @var \TransactionJournal $journal */ - $journal = $journals->find($transactionMap->new); - - /* - * If either is null, release: - */ - if (is_null($category) || is_null($journal)) { - \Log::notice('Map is incorrect in category/transaction mapper. Release.'); - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Update journal to have budget: - */ - $journal->categories()->save($category); - $journal->save(); - \Log::debug('Connected category "' . $category->name . '" to journal "' . $journal->description . '"'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - - - return; - } - - /** - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importCategory(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - /* - * Maybe the category has already been imported - */ - $importEntry = $repository->findImportEntry($importMap, 'Category', intval($payload['data']['id'])); - - /* - * if so, delete job and return: - */ - if (!is_null($importEntry)) { - \Log::debug('Already imported category ' . $payload['data']['name']); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - /* - * try to find category first - */ - $current = $this->findByName($payload['data']['name']); - - /* - * If not found, create it: - */ - if (is_null($current)) { - $category = $this->store($payload['data']); - $repository->store($importMap, 'Category', $payload['data']['id'], $category->id); - \Log::debug('Imported category "' . $payload['data']['name'] . '".'); - } else { - $repository->store($importMap, 'Category', $payload['data']['id'], $current->id); - \Log::debug('Already had category "' . $payload['data']['name'] . '".'); - } - - // update map: - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - /** - * @param $name - * - * @return mixed - */ - public function findByName($name) - { - if ($name == '' || strlen($name) == 0) { - return null; - } - - return $this->_user->categories()->where('name', $name)->first(); - - } - - /** - * @param $data - * - * @return \Category|mixed - */ - public function store($data) - { - $category = new \Category; - $category->name = $data['name']; - - $category->user()->associate($this->_user); - $category->save(); - - return $category; - } - - /** - * @param $name - * - * @return \Category|mixed - */ - public function firstOrCreate($name) - { - if (strlen($name) == 0) { - return null; - } - $data = [ - 'name' => $name, - 'user_id' => $this->_user->id, - ]; - return \Category::firstOrCreate($data); - - } - - /** - * @param $category - * - * @return bool|mixed - */ - public function destroy($category) - { - $category->delete(); - - return true; - } - - /** - * @return mixed - */ - public function get() - { - return $this->_user->categories()->orderBy('name', 'ASC')->get(); - } - - /** - * @param $category - * @param $data - * - * @return mixed - */ - public function update($category, $data) - { - // update account accordingly: - $category->name = $data['name']; - if ($category->validate()) { - $category->save(); - } - - return $category; - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Import/EloquentImportRepository.php b/app/lib/Firefly/Storage/Import/EloquentImportRepository.php deleted file mode 100644 index 2cc1139fa1..0000000000 --- a/app/lib/Firefly/Storage/Import/EloquentImportRepository.php +++ /dev/null @@ -1,58 +0,0 @@ -_user = \Auth::user(); - } - - public function findImportComponentMap(\Importmap $map, $oldComponentId) - { - $entry = \Importentry::where('importmap_id', $map->id) - ->whereIn('class', ['Budget', 'Category', 'Account', 'Component']) - ->where('old', intval($oldComponentId))->first(); - - return $entry; - } - - public function findImportEntry(\Importmap $map, $class, $oldID) - { - - return \Importentry::where('importmap_id', $map->id)->where('class', $class)->where('old', $oldID)->first(); - } - - public function findImportMap($id) - { - return \Importmap::find($id); - } - - /** - * @param \User $user - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - return true; - } - - public function store(\Importmap $map, $class, $oldID, $newID) - { - $entry = new \Importentry; - $entry->importmap()->associate($map); - $entry->class = $class; - $entry->old = intval($oldID); - $entry->new = intval($newID); - $entry->save(); - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Import/ImportRepositoryInterface.php b/app/lib/Firefly/Storage/Import/ImportRepositoryInterface.php deleted file mode 100644 index e5a12eeb48..0000000000 --- a/app/lib/Firefly/Storage/Import/ImportRepositoryInterface.php +++ /dev/null @@ -1,51 +0,0 @@ -_user = \Auth::user(); - } - - /** - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importLimit(Job $job, array $payload) - { - - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - if ($job->attempts() > 10) { - \Log::error( - 'No budget found for limit #' . $payload['data']['id'] . '. Prob. for another component. KILL!' - ); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed. - return; - } - - /** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budgets */ - $budgets = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface'); - $budgets->overruleUser($user); - - /* - * Find the budget this limit is part of: - */ - $importEntry = $repository->findImportEntry($importMap, 'Budget', intval($payload['data']['component_id'])); - - /* - * There is no budget (yet?) - */ - if (is_null($importEntry)) { - $componentId = intval($payload['data']['component_id']); - \Log::warning('Budget #' . $componentId . ' not found. Requeue import job.'); - if(\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * Find budget import limit is for: - */ - $budget = $budgets->find($importEntry->new); - if (!is_null($budget)) { - /* - * Is actual limit already imported? - */ - $limit = $this->findByBudgetAndDate($budget, new Carbon($payload['data']['date'])); - if (is_null($limit)) { - /* - * It isn't imported yet. - */ - $payload['data']['budget_id'] = $budget->id; - $payload['data']['startdate'] = $payload['data']['date']; - $payload['data']['period'] = 'monthly'; - /* - * Store limit, and fire event for LimitRepetition. - */ - $limit = $this->store($payload['data']); - $repository->store($importMap, 'Limit', $payload['data']['id'], $limit->id); - \Event::fire('limits.store', [$limit]); - \Log::debug('Imported limit for budget ' . $budget->name); - } else { - /* - * Limit already imported: - */ - $repository->store($importMap, 'Budget', $payload['data']['id'], $limit->id); - } - } else { - \Log::error(print_r($importEntry,true)); - \Log::error('Cannot import limit! Big bad error!'); - } - - // update map: - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - } - - /** - * @param \User $user - * - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - return true; - } - - public function findByBudgetAndDate(\Budget $budget, Carbon $date) - { - return \Limit::whereComponentId($budget->id)->where('startdate', $date->format('Y-m-d'))->first(); - } - - /** - * @param $data - * - * @return \Limit - */ - public function store($data) - { - $budget = \Budget::find($data['budget_id']); - if (is_null($budget)) { - \Session::flash('error', 'No such budget.'); - - return new \Limit; - } - // set the date to the correct start period: - $date = new Carbon($data['startdate']); - switch ($data['period']) { - case 'daily': - $date->startOfDay(); - break; - case 'weekly': - $date->startOfWeek(); - break; - case 'monthly': - $date->startOfMonth(); - break; - case 'quarterly': - $date->firstOfQuarter(); - break; - case 'half-year': - - if (intval($date->format('m')) >= 7) { - $date->startOfYear(); - $date->addMonths(6); - } else { - $date->startOfYear(); - } - break; - case 'yearly': - $date->startOfYear(); - break; - } - // find existing: - $count = \Limit:: - leftJoin('components', 'components.id', '=', 'limits.component_id')->where( - 'components.user_id', $this->_user->id - )->where('startdate', $date->format('Y-m-d'))->where('component_id', $data['budget_id'])->where( - 'repeat_freq', $data['period'] - )->count(); - if ($count > 0) { - \Session::flash('error', 'There already is an entry for these parameters.'); - - return new \Limit; - } - // create new limit: - $limit = new \Limit; - $limit->budget()->associate($budget); - $limit->startdate = $date; - $limit->amount = floatval($data['amount']); - $limit->repeats = isset($data['repeats']) ? intval($data['repeats']) : 0; - $limit->repeat_freq = $data['period']; - if (!$limit->save()) { - \Session::flash('error', 'Could not save: ' . $limit->errors()->first()); - } - - return $limit; - } - - /** - * @param \Limit $limit - * - * @return bool - */ - public function destroy(\Limit $limit) - { - $limit->delete(); - - return true; - } - - /** - * @param \Budget $budget - * @param Carbon $start - * @param Carbon $end - * - * @return mixed - */ - public function getTJByBudgetAndDateRange(\Budget $budget, Carbon $start, Carbon $end) - { - $result = $budget->transactionjournals()->with('transactions')->after($start)->before($end)->get(); - - return $result; - - } - - /** - * @param \Limit $limit - * @param $data - * - * @return mixed|void - */ - public function update(\Limit $limit, $data) - { - $limit->startdate = new Carbon($data['startdate']); - $limit->repeat_freq = $data['period']; - $limit->repeats = isset($data['repeats']) && $data['repeats'] == '1' ? 1 : 0; - $limit->amount = floatval($data['amount']); - - $limit->save(); - - return $limit; - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Limit/LimitRepositoryInterface.php b/app/lib/Firefly/Storage/Limit/LimitRepositoryInterface.php deleted file mode 100644 index 92a88a3279..0000000000 --- a/app/lib/Firefly/Storage/Limit/LimitRepositoryInterface.php +++ /dev/null @@ -1,70 +0,0 @@ -_user = \Auth::user(); - } - - /** - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importPiggybank(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - if ($job->attempts() > 10) { - \Log::error('No account available for piggy bank "' . $payload['data']['name'] . '". KILL!'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - - - /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ - $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); - $accounts->overruleUser($user); - - /* - * Maybe the piggy bank has already been imported - */ - $importEntry = $repository->findImportEntry($importMap, 'Piggybank', intval($payload['data']['id'])); - - /* - * if so, delete job and return: - */ - if (!is_null($importEntry)) { - \Log::debug('Already imported piggy bank ' . $payload['data']['name']); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - /* - * Try to find related piggybank: - */ - $piggyBank = $this->findByName($payload['data']['name']); - - /* - * Find an account (any account, really, at this point). - */ - $accountType = $accounts->findAccountType('Asset account'); - - /** @var Collection $set */ - $set = $accounts->getByAccountType($accountType); - - /* - * If there is an account to attach to this piggy bank, simply use that one. - */ - if ($set->count() > 0) { - /** @var \Account $account */ - $account = $set->first(); - $payload['data']['account_id'] = $account->id; - } else { - \Log::notice('No account available yet for piggy bank "' . $payload['data']['name'] . '".'); - if(\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - /* - * No existing piggy bank, create it: - */ - if (is_null($piggyBank)) { - $payload['data']['targetamount'] = floatval($payload['data']['target']); - $payload['data']['repeats'] = 0; - $payload['data']['rep_every'] = 1; - $payload['data']['reminder_skip'] = 1; - $payload['data']['rep_times'] = 1; - $piggyBank = $this->store($payload['data']); - /* - * Store and fire event. - */ - $repository->store($importMap, 'Piggybank', intval($payload['data']['id']), $piggyBank->id); - \Log::debug('Imported piggy "' . $payload['data']['name'] . '".'); - \Event::fire('piggybanks.store', [$piggyBank]); - } else { - /* - * Already have a piggy bank with this name, we skip it. - */ - $repository->store($importMap, 'Piggybank', $payload['data']['id'], $piggyBank->id); - \Log::debug('Already imported piggy "' . $payload['data']['name'] . '".'); - } - // update map: - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - - } - - /** - * @param \User $user - * - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - return true; - } - - public function findByName($piggyBankName) - { - return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where( - 'accounts.user_id', $this->_user->id - )->where('piggybanks.name', $piggyBankName)->first(['piggybanks.*']); - } - - public function countNonrepeating() - { - return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where( - 'accounts.user_id', $this->_user->id - )->where('repeats', 0)->count(); - - } - - public function countRepeating() - { - return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where( - 'accounts.user_id', $this->_user->id - )->where('repeats', 1)->count(); - } - - /** - * @param \Piggybank $piggyBank - * - * @return mixed|void - */ - public function destroy(\Piggybank $piggyBank) - { - $piggyBank->delete(); - - return true; - } - - /** - * @param $piggyBankId - * - * @return mixed - */ - public function find($piggyBankId) - { - return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where( - 'accounts.user_id', $this->_user->id - )->where('piggybanks.id', $piggyBankId)->first(['piggybanks.*']); - } - - /** - * @return mixed - */ - public function get() - { - $piggies = $this->_user->piggybanks()->with(['account', 'piggybankrepetitions'])->get(); - - return $piggies; - } - - /** - * @param \Account $account - * - * @return mixed|void - */ - public function leftOnAccount(\Account $account) - { - $balance = $account->balance(); - /** @var \Piggybank $p */ - foreach ($account->piggybanks()->get() as $p) { - $balance -= $p->currentRelevantRep()->currentamount; - } - - return $balance; - - } - - /** - * @param \Piggybank $piggyBank - * @param $amount - * - * @return bool|mixed - */ - public function modifyAmount(\Piggybank $piggyBank, $amount) - { - $rep = $piggyBank->currentRelevantRep(); - if (!is_null($rep)) { - $rep->currentamount += $amount; - $rep->save(); - } - - - return true; - - } - - /** - * @param $data - * - * @return \Piggybank - */ - public function store($data) - { - if (isset($data['targetdate']) && $data['targetdate'] == '') { - unset($data['targetdate']); - } - if (isset($data['reminder']) && $data['reminder'] == 'none') { - unset($data['reminder']); - } - if (isset($data['startdate']) && $data['startdate'] == '') { - unset($data['startdate']); - } - - /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ - $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); - $accounts->overruleUser($this->_user); - $account = isset($data['account_id']) ? $accounts->find($data['account_id']) : null; - - - $piggyBank = new \Piggybank($data); - - if (!is_null($piggyBank->reminder) && is_null($piggyBank->startdate) && is_null($piggyBank->targetdate)) { - - $piggyBank->errors()->add('reminder', 'Cannot create reminders without start ~ AND target date.'); - \Log::error('PiggyBank create-error: ' . $piggyBank->errors()->first()); - return $piggyBank; - - } - - - if ($piggyBank->repeats && !isset($data['targetdate'])) { - $piggyBank->errors()->add('targetdate', 'Target date is mandatory!'); - \Log::error('PiggyBank create-error: ' . $piggyBank->errors()->first()); - - return $piggyBank; - } - if (!is_null($account)) { - $piggyBank->account()->associate($account); - } - $today = new Carbon; - - if ($piggyBank->validate()) { - if (!is_null($piggyBank->targetdate) && $piggyBank->targetdate < $today) { - $piggyBank->errors()->add('targetdate', 'Target date cannot be in the past.'); - \Log::error('PiggyBank create-error: ' . $piggyBank->errors()->first()); - - return $piggyBank; - } - - if (!is_null($piggyBank->reminder) && !is_null($piggyBank->targetdate)) { - // first period for reminder is AFTER target date. - $reminderSkip = $piggyBank->reminder_skip < 1 ? 1 : intval($piggyBank->reminder_skip); - $firstReminder = new Carbon; - switch ($piggyBank->reminder) { - case 'day': - $firstReminder->addDays($reminderSkip); - break; - case 'week': - $firstReminder->addWeeks($reminderSkip); - break; - case 'month': - $firstReminder->addMonths($reminderSkip); - break; - case 'year': - $firstReminder->addYears($reminderSkip); - break; - default: - throw new FireflyException('Invalid reminder period'); - break; - } - if ($firstReminder > $piggyBank->targetdate) { - $piggyBank->errors()->add( - 'reminder', 'The reminder has been set to remind you after the piggy bank will expire.' - ); - \Log::error('PiggyBank create-error: ' . $piggyBank->errors()->first()); - - return $piggyBank; - } - } - $piggyBank->save(); - } - - - return $piggyBank; - } - - /** - * @param \Piggybank $piggy - * @param $data - * - * @return mixed - */ - public function update(\Piggybank $piggy, $data) - { - /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ - $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); - $accounts->overruleUser($this->_user); - $account = isset($data['account_id']) ? $accounts->find($data['account_id']) : null; - - if (!is_null($account)) { - $piggy->account()->associate($account); - } - - $piggy->name = $data['name']; - $piggy->targetamount = floatval($data['targetamount']); - $piggy->reminder = isset($data['reminder']) && $data['reminder'] != 'none' ? $data['reminder'] : null; - $piggy->reminder_skip = $data['reminder_skip']; - $piggy->targetdate = strlen($data['targetdate']) > 0 ? new Carbon($data['targetdate']) : null; - $piggy->startdate - = - isset($data['startdate']) && strlen($data['startdate']) > 0 ? new Carbon($data['startdate']) : null; - - - foreach ($piggy->piggybankrepetitions()->get() as $rep) { - $rep->delete(); - } - - if ($piggy->repeats == 1) { - $piggy->rep_every = intval($data['rep_every']); - $piggy->rep_length = $data['rep_length']; - } - - if ($piggy->validate()) { - // check the things we check for new piggies - $piggy->save(); - } - - - return $piggy; - - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Piggybank/PiggybankRepositoryInterface.php b/app/lib/Firefly/Storage/Piggybank/PiggybankRepositoryInterface.php deleted file mode 100644 index 5e9af3409c..0000000000 --- a/app/lib/Firefly/Storage/Piggybank/PiggybankRepositoryInterface.php +++ /dev/null @@ -1,95 +0,0 @@ -_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 array $payload - * - * @return mixed - */ - public function importPredictable(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - /* - * maybe the recurring transaction is already imported: - */ - $oldId = intval($payload['data']['id']); - $description = $payload['data']['description']; - $importEntry = $repository->findImportEntry($importMap, 'RecurringTransaction', $oldId); - - /* - * if so, delete job and return: - */ - if (!is_null($importEntry)) { - \Log::debug('Already imported recurring transaction #' . $payload['data']['id']); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - // try to find related recurring transaction: - $recurringTransaction = $this->findByName($payload['data']['description']); - if (is_null($recurringTransaction)) { - $amount = floatval($payload['data']['amount']); - $pct = intval($payload['data']['pct']); - - $set = [ - 'name' => $description, - 'match' => join(',', explode(' ', $description)), - 'amount_min' => $amount * ($pct / 100) * -1, - 'amount_max' => $amount * (1 + ($pct / 100)) * -1, - 'date' => date('Y-m-') . $payload['data']['dom'], - 'repeat_freq' => 'monthly', - 'active' => intval($payload['data']['inactive']) == 1 ? 0 : 1, - 'automatch' => 1, - ]; - - $recurringTransaction = $this->store($set); - $this->store($importMap, 'RecurringTransaction', $oldId, $recurringTransaction->id); - \Log::debug('Imported predictable ' . $description); - } else { - $this->store($importMap, 'RecurringTransaction', $oldId, $recurringTransaction->id); - \Log::debug('Already had predictable ' . $description); - } - // update map: - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - - } - - /** - * @param \User $user - * - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - return true; - } - - public function findByName($name) - { - return $this->_user->recurringtransactions()->where('name', 'LIKE', '%' . $name . '%')->first(); - } - - /** - * @param $data - * - * @return MessageBag - */ - public function store($data) - { - $messageBag = new MessageBag; - $recurringTransaction = new \RecurringTransaction( - [ - 'user_id' => $this->_user->id, - 'name' => $data['name'], - 'match' => join(' ', explode(',', $data['match'])), - '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'], - ] - ); - - // unique name? - $count = $this->_user->recurringtransactions()->whereName($data['name'])->count(); - if ($count > 0) { - $messageBag->add('name', 'A recurring transaction with this name already exists.'); - return $messageBag; - } - - // both amounts zero?: - if ($recurringTransaction->amount_max == 0 && $recurringTransaction->amount_min == 0) { - $messageBag->add('amount_max', 'Amount max and min cannot both be zero.'); - return $messageBag; - } - - if ($recurringTransaction->amount_max < $recurringTransaction->amount_min) { - $messageBag->add('amount_max', 'Amount max must be more than amount min.'); - return $messageBag; - } - - if ($recurringTransaction->amount_min > $recurringTransaction->amount_max) { - $messageBag->add('amount_max', 'Amount min must be less than amount max.'); - return $messageBag; - } - - if ($recurringTransaction->validate()) { - $recurringTransaction->save(); - } else { - $messageBag = $recurringTransaction->errors(); - } - - return $messageBag; - } - - /** - * @param \RecurringTransaction $recurringTransaction - * @param $data - * - * @return MessageBag - */ - public function update(\RecurringTransaction $recurringTransaction, $data) - { - $messageBag = new MessageBag; - $recurringTransaction->name = $data['name']; - $recurringTransaction->match = join(' ', explode(',', $data['match'])); - $recurringTransaction->amount_max = floatval($data['amount_max']); - $recurringTransaction->amount_min = floatval($data['amount_min']); - - // both amounts zero: - if ($recurringTransaction->amount_max == 0 && $recurringTransaction->amount_min == 0) { - $messageBag->add('amount_max', 'Amount max and min cannot both be zero.'); - - return $messageBag; - } - $recurringTransaction->date = new Carbon($data['date']); - $recurringTransaction->active = isset($data['active']) ? intval($data['active']) : 0; - $recurringTransaction->automatch = isset($data['automatch']) ? intval($data['automatch']) : 0; - $recurringTransaction->skip = isset($data['skip']) ? intval($data['skip']) : 0; - $recurringTransaction->repeat_freq = $data['repeat_freq']; - - if ($recurringTransaction->validate()) { - $recurringTransaction->save(); - } else { - $messageBag = $recurringTransaction->errors(); - } - - return $messageBag; - - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/RecurringTransaction/RecurringTransactionRepositoryInterface.php b/app/lib/Firefly/Storage/RecurringTransaction/RecurringTransactionRepositoryInterface.php deleted file mode 100644 index 0e753f3e3d..0000000000 --- a/app/lib/Firefly/Storage/RecurringTransaction/RecurringTransactionRepositoryInterface.php +++ /dev/null @@ -1,64 +0,0 @@ -_user = $user; - return true; - } - - protected $_user = null; - - /** - * - */ - public function __construct() - { - $this->_user = \Auth::user(); - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Reminder/ReminderRepositoryInterface.php b/app/lib/Firefly/Storage/Reminder/ReminderRepositoryInterface.php deleted file mode 100644 index 05e6c77a54..0000000000 --- a/app/lib/Firefly/Storage/Reminder/ReminderRepositoryInterface.php +++ /dev/null @@ -1,19 +0,0 @@ -app->bind( - 'Firefly\Storage\User\UserRepositoryInterface', - 'Firefly\Storage\User\EloquentUserRepository' - ); - $this->app->bind( - 'Firefly\Storage\Transaction\TransactionRepositoryInterface', - 'Firefly\Storage\Transaction\EloquentTransactionRepository' - ); - $this->app->bind( - 'Firefly\Storage\Import\ImportRepositoryInterface', - 'Firefly\Storage\Import\EloquentImportRepository' - ); - - - $this->app->bind( - 'Firefly\Storage\Piggybank\PiggybankRepositoryInterface', - 'Firefly\Storage\Piggybank\EloquentPiggybankRepository' - ); - - $this->app->bind( - 'Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface', - 'Firefly\Storage\RecurringTransaction\EloquentRecurringTransactionRepository' - ); - - $this->app->bind( - 'Firefly\Storage\Reminder\ReminderRepositoryInterface', - 'Firefly\Storage\Reminder\EloquentReminderRepository' - ); - - $this->app->bind( - 'Firefly\Storage\Account\AccountRepositoryInterface', - 'Firefly\Storage\Account\EloquentAccountRepository' - ); - $this->app->bind( - 'Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface', - 'Firefly\Storage\TransactionJournal\EloquentTransactionJournalRepository' - ); - - $this->app->bind( - 'Firefly\Storage\Limit\LimitRepositoryInterface', - 'Firefly\Storage\Limit\EloquentLimitRepository' - ); - - $this->app->bind( - 'Firefly\Storage\Budget\BudgetRepositoryInterface', - 'Firefly\Storage\Budget\EloquentBudgetRepository' - ); - $this->app->bind( - 'Firefly\Storage\Category\CategoryRepositoryInterface', - 'Firefly\Storage\Category\EloquentCategoryRepository' - ); - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Transaction/EloquentTransactionRepository.php b/app/lib/Firefly/Storage/Transaction/EloquentTransactionRepository.php deleted file mode 100644 index a4307a2e50..0000000000 --- a/app/lib/Firefly/Storage/Transaction/EloquentTransactionRepository.php +++ /dev/null @@ -1,32 +0,0 @@ -_user = \Auth::user(); - } - - /** - * @param \User $user - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - return true; - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/Transaction/TransactionRepositoryInterface.php b/app/lib/Firefly/Storage/Transaction/TransactionRepositoryInterface.php deleted file mode 100644 index 314f72b0c4..0000000000 --- a/app/lib/Firefly/Storage/Transaction/TransactionRepositoryInterface.php +++ /dev/null @@ -1,19 +0,0 @@ -_user = \Auth::user(); - } - - /** - * Get them ALL - * - * @return Collection - */ - public function get() { - return $this->_user->transactionjournals()->with('transactions')->get(); - } - - /** - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importTransfer(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - - if ($job->attempts() > 10) { - \Log::error('Never found accounts for transfer "' . $payload['data']['description'] . '". KILL!'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - /** @var \Firefly\Helper\Controllers\TransactionInterface $transactions */ - $transactions = \App::make('Firefly\Helper\Controllers\TransactionInterface'); - $transactions->overruleUser($this->_user); - - /* - * Prep some variables from the payload: - */ - $fromAccountId = intval($payload['data']['accountfrom_id']); - $toAccountId = intval($payload['data']['accountto_id']); - $description = $payload['data']['description']; - $transferId = intval($payload['data']['id']); - $amount = floatval($payload['data']['amount']); - $date = new Carbon($payload['data']['date']); - - /* - * maybe Journal is already imported: - */ - $importEntry = $repository->findImportEntry($importMap, 'Transfer', $transferId); - - /* - * if so, delete job and return: - */ - if (!is_null($importEntry)) { - \Log::debug('Already imported transfer ' . $description); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - /* - * Find the 'from' account: - */ - $oldFromAccountEntry = $repository->findImportEntry($importMap, 'Account', $fromAccountId); - - /* - * Find the 'to' account: - */ - $oldToAccountEntry = $repository->findImportEntry($importMap, 'Account', $toAccountId); - - /* - * Import transfer: - */ - $set = [ - 'account_from_id' => $oldFromAccountEntry->new, - 'account_to_id' => $oldToAccountEntry->new, - 'amount' => $amount, - 'description' => $description, - 'date' => $date->format('Y-m-d'), - 'category' => '', - 'what' => 'transfer', - 'return_journal' => true - ]; - $returnSet = $transactions->store($set); - $journal = $returnSet['journal']; - - /* - * Validate the store action: - */ - if ($journal instanceof MessageBag) { - /* - * It's a message bag; clearly something went wrong. - */ - \Log::notice('Could not import TJ "' . $description . '": ' . $journal->first()); - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } else if ($journal instanceof \TransactionJournal && $journal->errors()->count() > 0) { - /* - * It's a journal but it still failed somehow. - */ - \Log::notice('Could not import TJ "' . $description . '": ' . $journal->errors()->first()); - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - $repository->store($importMap, 'Transfer', $transferId, $journal->id); - \Log::debug('Imported transfer "' . $description . '" (' . $amount . ') (' . $date->format('Y-m-d') . ')'); - - // update map: - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed. - - } - - /** - * @param \User $user - * - * @return mixed|void - */ - public function overruleUser(\User $user) - { - $this->_user = $user; - return true; - } - - /** - * @param array $data - * - * @return \TransactionJournal - */ - public function store(array $data) - { - /* - * Create the journal and fill relevant fields. - */ - $journal = new \TransactionJournal; - $journal->description = trim($data['description']); - $journal->date = new Carbon($data['date']); - $journal->user_id = $this->_user->id; - $journal->completed = false; - - /* - * Find the more complex fields and fill those: - */ - $currency = \TransactionCurrency::where('code', 'EUR')->first(); - $journal->transaction_currency_id = $currency->id; - $transactionType = \TransactionType::where('type', $data['what'])->first(); - $journal->transaction_type_id = $transactionType->id; - - /* - * Validate & save journal - */ - $journal->validate(); - $journal->save(); - - /* - * Return regardless. - */ - return $journal; - } - - /** - * @param \TransactionJournal $journal - * @param \Account $account - * @param $amount - * - * @return \Transaction|null - */ - public function saveTransaction(\TransactionJournal $journal, \Account $account, $amount) - { - $transaction = new \Transaction; - $transaction->account_id = $account->id; - $transaction->transaction_journal_id = $journal->id; - $transaction->amount = $amount; - if ($transaction->validate()) { - $transaction->save(); - } - return $transaction; - - } - - - /** - * @param Job $job - * @param array $payload - * - * @return mixed - */ - public function importTransaction(Job $job, array $payload) - { - /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ - $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); - - /** @var \Importmap $importMap */ - $importMap = $repository->findImportmap($payload['mapID']); - $user = $importMap->user; - $this->overruleUser($user); - - if ($job->attempts() > 10) { - \Log::error('Never found asset account for transaction "' . $payload['data']['description'] . '". KILL!'); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ - $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); - $accounts->overruleUser($user); - - /** @var \Firefly\Helper\Controllers\TransactionInterface $transactions */ - $transactions = \App::make('Firefly\Helper\Controllers\TransactionInterface'); - $transactions->overruleUser($this->_user); - - - /* - * Prep some vars coming out of the pay load: - */ - $amount = floatval($payload['data']['amount']); - $date = new Carbon($payload['data']['date']); - $description = $payload['data']['description']; - $transactionId = intval($payload['data']['id']); - $accountId = intval($payload['data']['account_id']); - - /* - * maybe Journal is already imported: - */ - $importEntry = $repository->findImportEntry($importMap, 'Transaction', $transactionId); - - /* - * if so, delete job and return: - */ - if (!is_null($importEntry)) { - \Log::debug('Already imported transaction ' . $description); - - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - } - - /* - * Find or create the "import account" which is used because at this point, Firefly - * doesn't know which beneficiary (expense account) should be connected to this transaction. - */ - $accountType = $accounts->findAccountType('Import account'); - $importAccount = $accounts->firstOrCreate( - [ - 'account_type_id' => $accountType->id, - 'name' => 'Import account', - 'user_id' => $user->id, - 'active' => 1, - ] - ); - unset($accountType); - - /* - * Find the asset account this transaction is paid from / paid to: - */ - $accountEntry = $repository->findImportEntry($importMap, 'Account', $accountId); - - /* - * Prep some data for the import routine: - */ - $set = [ - 'category' => '', - 'description' => $description, - 'date' => $date->format('Y-m-d'), - 'return_journal' => true, - 'account_id' => $accountEntry->new - ]; - - - /* - * If the amount is less than zero, we move money to the $importAccount. Otherwise, - * we move it from the $importAccount. - */ - - if ($amount < 0) { - // if amount is less than zero, move to $importAccount - $set['what'] = 'withdrawal'; - $set['expense_account'] = $importAccount->name; - } else { - $set['what'] = 'deposit'; - $set['revenue_account'] = $importAccount->name; - } - - /* - * Modify the amount so it will work with or new transaction journal structure. - */ - $set['amount'] = $amount < 0 ? $amount * -1 : $amount; - - /* - * Import it: - */ - $returnSet = $transactions->store($set); - $journal = $returnSet['journal']; - - /* - * Validate the store action: - */ - if ($journal instanceof MessageBag) { - - /* - * It's a message bag; clearly something went wrong. - */ - \Log::notice('Could not import transfer "' . $description . '": ' . $journal->first()); - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } else if ($journal instanceof \TransactionJournal && $journal->errors()->count() > 0) { - /* - * It's a journal but it still failed somehow. - */ - \Log::notice('Could not import transfer "' . $description . '": ' . $journal->errors()->first()); - if (\Config::get('queue.default') == 'sync') { - $importMap->jobsdone++; - $importMap->save(); - $job->delete(); // count fixed - } else { - $job->release(300); // proper release. - } - return; - } - - $repository->store($importMap, 'Transaction', $transactionId, $journal->id); - \Log::debug('Imported transaction "' . $description . '" (' . $amount . ') (' . $date->format('Y-m-d') . ')'); - - // update map: - $importMap->jobsdone++; - $importMap->save(); - - $job->delete(); // count fixed - return; - - } - - /** - * @param $journalId - * - * @return mixed - */ - public function find($journalId) - { - return $this->_user->transactionjournals()->with( - ['transactions' => function ($q) { - return $q->orderBy('amount', 'ASC'); - }, 'transactioncurrency', 'transactiontype', 'components', 'transactions.account', - 'transactions.account.accounttype'] - ) - ->where('id', $journalId)->first(); - } - - /** - * @param \Account $account - * @param int $count - * @param Carbon $start - * @param Carbon $end - * - * @return mixed - */ - public function getByAccountInDateRange(\Account $account, $count = 25, Carbon $start, Carbon $end) - { - $accountID = $account->id; - $query = $this->_user->transactionjournals()->with( - [ - 'transactions', - 'transactioncurrency', - 'transactiontype' - ] - ) - ->leftJoin( - 'transactions', 'transactions.transaction_journal_id', '=', - 'transaction_journals.id' - ) - ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') - ->where('accounts.id', $accountID) - ->where('date', '>=', $start->format('Y-m-d')) - ->where('date', '<=', $end->format('Y-m-d')) - ->orderBy('transaction_journals.date', 'DESC') - ->orderBy('transaction_journals.id', 'DESC') - ->take($count) - ->get(['transaction_journals.*']); - - return $query; - } - /** - * @param \TransactionJournal $journal - * @param $data - * - * @return mixed|\TransactionJournal - * @throws \Firefly\Exception\FireflyException - */ - public function update(\TransactionJournal $journal, $data) - { - /* - * Update the basic fields: - */ - $journal->description = trim($data['description']); - $journal->date = new Carbon($data['date']); - - /* - * Validate & save journal - */ - $journal->validate(); - $journal->save(); - - /* - * Return regardless. - */ - return $journal; - - - } -// /* -// * Grab some of the repositories we need: -// */ -// /** @var \Firefly\Storage\Category\CategoryRepositoryInterface $catRepository */ -// $catRepository = \App::make('Firefly\Storage\Category\CategoryRepositoryInterface'); -// $catRepository->overruleUser($this->_user); -// -// /** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budgetRepository */ -// $budRepository = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface'); -// $budRepository->overruleUser($this->_user); -// -// /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accountRepository */ -// $accountRepository = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); -// $accountRepository->overruleUser($this->_user); -// -// -// update basics first: -// $journal->description = $data['description']; -// $journal->date = $data['date']; -// $amount = floatval($data['amount']); -// -// // remove previous category, if any: -// if (!is_null($journal->categories()->first())) { -// $journal->categories()->detach($journal->categories()->first()->id); -// } -// // remove previous budget, if any: -// if (!is_null($journal->budgets()->first())) { -// $journal->budgets()->detach($journal->budgets()->first()->id); -// } -// // remove previous piggy bank, if any: -// -// -// $category = isset($data['category']) ? $catRepository->findByName($data['category']) : null; -// if (!is_null($category)) { -// $journal->categories()->attach($category); -// } -// // update the amounts: -// $transactions = $journal->transactions()->orderBy('amount', 'ASC')->get(); -// -// // remove previous piggy bank, if any: -// /** @var \Transaction $transaction */ -// foreach ($transactions as $transaction) { -// if (!is_null($transaction->piggybank()->first())) { -// $transaction->piggybank_id = null; -// $transaction->save(); -// } -// } -// unset($transaction); -// -// $transactions[0]->amount = $amount * -1; -// $transactions[1]->amount = $amount; -// -// // switch on type to properly change things: -// $fireEvent = false; -// switch ($journal->transactiontype->type) { -// case 'Withdrawal': -// // means transaction[0] is the users account. -// $account = $accountRepository->find($data['account_id']); -// $beneficiary = $accountRepository->createOrFindBeneficiary($data['beneficiary']); -// $transactions[0]->account()->associate($account); -// $transactions[1]->account()->associate($beneficiary); -// -// // do budget: -// $budget = $budRepository->find($data['budget_id']); -// if (!is_null($budget)) { -// $journal->budgets()->attach($budget); -// } -// -// break; -// case 'Deposit': -// // means transaction[0] is the beneficiary. -// $account = $accountRepository->find($data['account_id']); -// $beneficiary = $accountRepository->createOrFindBeneficiary($data['beneficiary']); -// $journal->transactions[0]->account()->associate($beneficiary); -// $journal->transactions[1]->account()->associate($account); -// break; -// case 'Transfer': -// // means transaction[0] is account that sent the money (from). -// /** @var \Account $fromAccount */ -// $fromAccount = $accountRepository->find($data['account_from_id']); -// /** @var \Account $toAccount */ -// $toAccount = $accountRepository->find($data['account_to_id']); -// $journal->transactions[0]->account()->associate($fromAccount); -// $journal->transactions[1]->account()->associate($toAccount); -// -// // attach the new piggy bank, if valid: -// /** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggyRepository */ -// $piggyRepository = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface'); -// $piggyRepository->overruleUser($this->_user); -// -// if (isset($data['piggybank_id'])) { -// /** @var \Piggybank $piggyBank */ -// $piggyBank = $piggyRepository->find(intval($data['piggybank_id'])); -// -// // loop transactions and re-attach the piggy bank: -// -// if ($piggyBank) { -// -// $connected = false; -// foreach ($journal->transactions()->get() as $transaction) { -// if ($transaction->account_id == $piggyBank->account_id) { -// $connected = true; -// $transaction->piggybank()->associate($piggyBank); -// $transaction->save(); -// $fireEvent = true; -// break; -// } -// } -// if ($connected === false) { -// \Session::flash( -// 'warning', 'Piggy bank "' . e($piggyBank->name) -// . '" is not set to draw money from any of the accounts in this transfer' -// ); -// } -// } -// } -// -// -// break; -// default: -// throw new FireflyException('Cannot edit this!'); -// break; -// } -// -// $transactions[0]->save(); -// $transactions[1]->save(); -// if ($journal->validate()) { -// $journal->save(); -// } -// if ($fireEvent) { -// \Event::fire('piggybanks.updateRelatedTransfer', [$piggyBank]); -// } -// -// return $journal; -// -// -// } - - -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalRepositoryInterface.php b/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalRepositoryInterface.php deleted file mode 100644 index 2d01a7884d..0000000000 --- a/app/lib/Firefly/Storage/TransactionJournal/TransactionJournalRepositoryInterface.php +++ /dev/null @@ -1,88 +0,0 @@ -first(); - } - - /** - * @param $reset - * - * @return mixed - */ - public function findByReset($reset) - { - return \User::where('reset', $reset)->first(); - } - - /** - * @param $array - * - * @return bool|\User - */ - public function register($array) - { - $user = new \User; - $user->email = isset($array['email']) ? $array['email'] : null; - $user->migrated = 0; - $user->reset = \Str::random(32); - $user->password = \Hash::make(\Str::random(12)); - - if (!$user->save()) { - \Log::error('Invalid user'); - \Session::flash('error', 'Input invalid, please try again: ' . $user->errors()->first()); - - return false; - } - $user->save(); - - return $user; - } - - /** - * @param \User $user - * @param $password - * - * @return bool - */ - public function updatePassword(\User $user, $password) - { - /** @noinspection PhpUndefinedFieldInspection */ - $user->password = $password; - /** @noinspection PhpUndefinedMethodInspection */ - $user->forceSave(); - - return true; - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Storage/User/UserRepositoryInterface.php b/app/lib/Firefly/Storage/User/UserRepositoryInterface.php deleted file mode 100644 index d74b9cbae9..0000000000 --- a/app/lib/Firefly/Storage/User/UserRepositoryInterface.php +++ /dev/null @@ -1,43 +0,0 @@ -listen('budgets.destroy', 'Firefly\Trigger\Budgets\EloquentBudgetTrigger@destroy'); -// $events->listen('budgets.store', 'Firefly\Trigger\Budgets\EloquentBudgetTrigger@store'); -// $events->listen('budgets.update', 'Firefly\Trigger\Budgets\EloquentBudgetTrigger@update'); - - } - - /** - * Same. Doesn't do much. - * - * @param \Budget $budget - * - * @return bool - */ - public function update(\Budget $budget) - { - return true; - - } -} diff --git a/app/lib/Firefly/Trigger/Journals/EloquentJournalTrigger.php b/app/lib/Firefly/Trigger/Journals/EloquentJournalTrigger.php deleted file mode 100644 index cbb5196fae..0000000000 --- a/app/lib/Firefly/Trigger/Journals/EloquentJournalTrigger.php +++ /dev/null @@ -1,64 +0,0 @@ -user()->first()->recurringtransactions()->get(); - $result = []; - /* - * Prep vars - */ - $description = strtolower($journal->description); - $result = [0 => 0]; - - /** @var \RecurringTransaction $recurring */ - foreach ($set as $recurring) { - \Event::fire('recurring.rescan', [$recurring, $journal]); - } - - return true; - - } - - /** - * @param Dispatcher $events - */ - public function subscribe(Dispatcher $events) - { -// $events->listen('journals.store', 'Firefly\Trigger\Journals\EloquentJournalTrigger@store'); -// $events->listen('journals.update', 'Firefly\Trigger\Journals\EloquentJournalTrigger@update'); - - } - - /** - * @param \TransactionJournal $journal - * - * @return bool - */ - public function update(\TransactionJournal $journal) - { - return true; - - } - -} \ No newline at end of file diff --git a/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php b/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php deleted file mode 100644 index 2633684c14..0000000000 --- a/app/lib/Firefly/Trigger/Limits/EloquentLimitTrigger.php +++ /dev/null @@ -1,133 +0,0 @@ -where('components.user_id', \Auth::user()->id) - ->where('limits.repeats', 1) - ->get(['limits.*']); - } else { - $limits = []; - } - - /** @var \Limit $limit */ - foreach ($limits as $limit) { - // the limit repeats, and there should be at least one repetition already. - /** @var \LimitRepetition $primer */ - $primer = $limit->limitrepetitions()->orderBy('startdate', 'DESC')->first(); - $today = new Carbon; - $start = clone $primer->enddate; - // from the primer onwards. - while ($start <= $today) { - $start->addDay(); - $end = clone $start; - - // add period to determin end of limitrepetition: - switch ($limit->repeat_freq) { - case 'daily': - $end->addDay(); - break; - case 'weekly': - $end->addWeek(); - break; - case 'monthly': - $end->addMonth(); - break; - case 'quarterly': - $end->addMonths(3); - break; - case 'half-year': - $end->addMonths(6); - break; - case 'yearly': - $end->addYear(); - break; - } - $end->subDay(); - // create repetition: - $limit->createRepetition($start); - $start = clone $end; - } - } - } - - /** - * @param \Limit $limit - * - * @return bool - */ - public function destroy(\Limit $limit) - { - return true; - - } - - /** - * @param \LimitRepetition $repetition - */ - public function madeRepetition(\LimitRepetition $repetition) - { - \Log::debug('TRIGGER: Created a limit repetition (#' . $repetition->id . ')'); - } - - /** - * @param \Limit $limit - * - * @return bool - */ - public function store(\Limit $limit) - { - // create a repetition (repetitions) for this limit (we ignore "repeats"): - $limit->createRepetition($limit->startdate); - - return true; - } - - /** - * @param Dispatcher $events - */ - public function subscribe(Dispatcher $events) - { - //$events->listen('budgets.change', 'Firefly\Trigger\Limits\EloquentLimitTrigger@updateLimitRepetitions'); -// $events->listen('limits.destroy', 'Firefly\Trigger\Limits\EloquentLimitTrigger@destroy'); -// $events->listen('limits.store', 'Firefly\Trigger\Limits\EloquentLimitTrigger@store'); -// $events->listen('limits.update', 'Firefly\Trigger\Limits\EloquentLimitTrigger@update'); -// $events->listen('limits.check', 'Firefly\Trigger\Limits\EloquentLimitTrigger@checkRepeatingLimits'); -// $events->listen('limits.repetition', 'Firefly\Trigger\Limits\EloquentLimitTrigger@madeRepetition'); - //\Event::fire('limits.repetition', [$repetition]); - - } - - /** - * @param \Limit $limit - * - * @return bool - */ - public function update(\Limit $limit) - { - // remove and recreate limit repetitions. - // if limit is not repeating, simply update the repetition to match the limit, - // even though deleting everything is easier. - $limit->createRepetition($limit->startdate); - - return true; - } -} diff --git a/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php b/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php deleted file mode 100644 index 5a51efe653..0000000000 --- a/app/lib/Firefly/Trigger/Piggybanks/EloquentPiggybankTrigger.php +++ /dev/null @@ -1,239 +0,0 @@ -piggybanks()->where('repeats', 1)->get(); - } else { - $piggies = []; - } - - \Log::debug('Now in checkRepeatingPiggies with ' . count($piggies) . ' piggies found.'); - - /** @var \Piggybank $piggyBank */ - foreach ($piggies as $piggyBank) { - \Log::debug('Now working on ' . $piggyBank->name); - - /* - * Get the latest repetition, see if Firefly needs to create more. - */ - /** @var \PiggybankRepetition $primer */ - $primer = $piggyBank->piggybankrepetitions()->orderBy('targetdate', 'DESC')->first(); - \Log::debug('Last target date is: ' . $primer->targetdate); - - $today = new Carbon; - - // the next repetition must be created starting at the day after the target date of the previous one. - /* - * A repeated expense runs from day 1 to day X. Since it repeats, the next repetition starts at day X+1 - * until however often the repeated expense is set to repeat: a month, a week, a year. - */ - $start = clone $primer->targetdate; - $start->addDay(); - - while ($start <= $today) { - \Log::debug('Looping! Start is: ' . $start); - - // to get to the end of the current repetition, we switch on the piggy bank's - // repetition period: - $end = clone $start; - switch ($piggyBank->rep_length) { - case 'day': - $end->addDays($piggyBank->rep_every); - break; - case 'week': - $end->addWeeks($piggyBank->rep_every); - break; - case 'month': - $end->addMonths($piggyBank->rep_every); - break; - case 'year': - $end->addYears($piggyBank->rep_every); - break; - } - $end->subDay(); - - // create repetition: - $piggyBank->createRepetition($start, $end); - - $start = clone $end; - $start->addDay(); - - - } - - } - } - - /** - * @param \Piggybank $piggyBank - * @param \TransactionJournal $journal - * @param \Transaction $transaction - * - * @return bool - */ - public function createRelatedTransfer( - \Piggybank $piggyBank, \TransactionJournal $journal, \Transaction $transaction - ) { - $repetition = $piggyBank->repetitionForDate($journal->date); - if (!is_null($repetition)) { - // get the amount transferred TO this - $amount = floatval($transaction->amount); - $repetition->currentamount += $amount; - $repetition->save(); - } else { - \Session::flash('warning', 'Cannot add transfer to piggy, outside of scope.'); - } - - return true; - } - - /** - * @param \Piggybank $piggyBank - * @param $amount - */ - public function modifyAmountAdd(\Piggybank $piggyBank, $amount) - { - $rep = $piggyBank->currentRelevantRep(); - $today = new Carbon; - - // create event: - $event = new \PiggybankEvent; - $event->date = new Carbon; - $event->amount = $amount; - $event->piggybank()->associate($piggyBank); - - // for future / past repetitions. - if (!($rep->startdate >= $today && $rep->targetdate <= $today)) { - $event->date = $rep->startdate; - } - - - $event->save(); - } - - /** - * @param \Piggybank $piggyBank - * @param $amount - */ - public function modifyAmountRemove(\Piggybank $piggyBank, $amount) - { - // create event: - $event = new \PiggybankEvent; - $event->date = new Carbon; - $event->amount = $amount; - $event->piggybank()->associate($piggyBank); - $event->save(); - } - - /** - * This method is called when a piggy bank or repeated expense is created. It will create the first - * repetition which by default is equal to the PB / RE itself. After that, other triggers will take over. - * - * @param \Piggybank $piggyBank - * - * @return bool - */ - public function store(\Piggybank $piggyBank) - { - $piggyBank->createRepetition($piggyBank->startdate, $piggyBank->targetdate); - - return true; - } - - /** - * @param Dispatcher $events - */ - public function subscribe(Dispatcher $events) - { -// $events->listen('piggybanks.modifyAmountAdd', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@modifyAmountAdd'); -// $events->listen('piggybanks.modifyAmountRemove', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@modifyAmountRemove'); -// $events->listen('piggybanks.store', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@store'); -// $events->listen('piggybanks.update', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@update'); -// $events->listen('piggybanks.createRelatedTransfer', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@createRelatedTransfer'); -// $events->listen('piggybanks.updateRelatedTransfer', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@updateRelatedTransfer'); -// $events->listen('piggybanks.storepiggybanks.check', 'Firefly\Trigger\Piggybanks\EloquentPiggybankTrigger@checkRepeatingPiggies'); - - } - - /** - * When the user updates a piggy bank the repetitions, past and now, may be wrong. The best bet - * would be to delete everything and start over, but that also means past repetitions will be gone. - * - * Instead, we have disabled changing the dates when the piggy bank is repeating: a repeated expense cannot - * have its dates changed. This will prevent many problems I don't want to deal with. - * - * @param \Piggybank $piggyBank - */ - public function update(\Piggybank $piggyBank) - { - // delete all repetitions: - foreach ($piggyBank->piggybankrepetitions()->get() as $rep) { - - $rep->delete(); - } - unset($rep); - - // trigger "new" piggy bank to recreate them. - \Event::fire('piggybanks.store', [$piggyBank]); - - - // loop the repetitions and update them according to the events and the transactions: - foreach ($piggyBank->piggybankrepetitions()->get() as $rep) { - // SUM for transactions - $query = \Transaction::where('piggybank_id', $piggyBank->id)->leftJoin( - 'transaction_journals', 'transaction_journals.id', '=', - 'transactions.transaction_journal_id' - ); - if (!is_null($rep->startdate)) { - $query->where('transaction_journals.date', '>=', $rep->startdate->format('Y-m-d')); - } - if (!is_null($rep->targetdate)) { - $query->where( - 'transaction_journals.date', '<=', $rep->targetdate->format('Y-m-d') - ); - } - $sum = $query->sum('transactions.amount'); - - // get events for piggy bank, save those as well: - $eventSumQuery = $piggyBank->piggybankevents(); - if (!is_null($rep->startdate)) { - $eventSumQuery->where('date', '>=', $rep->startdate->format('Y-m-d')); - } - if (!is_null($rep->targetdate)) { - $eventSumQuery->where('date', '<=', $rep->targetdate->format('Y-m-d')); - } - $eventSum = floatval($eventSumQuery->sum('amount')); - $rep->currentamount = floatval($sum) + $eventSum; - $rep->save(); - - } - } - - public function updateRelatedTransfer(\Piggybank $piggyBank) - { - // fire the "update" trigger which should handle things just fine: - \Event::fire('piggybanks.update', [$piggyBank]); - } - - -} \ No newline at end of file diff --git a/app/lib/Firefly/Trigger/Recurring/EloquentRecurringTrigger.php b/app/lib/Firefly/Trigger/Recurring/EloquentRecurringTrigger.php deleted file mode 100644 index b29167bb48..0000000000 --- a/app/lib/Firefly/Trigger/Recurring/EloquentRecurringTrigger.php +++ /dev/null @@ -1,111 +0,0 @@ -match); - $description = strtolower($journal->description); - - /* - * Attach expense account to description for more narrow matching. - */ - $transactions = $journal->transactions()->get(); - /** @var \Transaction $transaction */ - foreach ($transactions as $transaction) { - /** @var \Account $account */ - $account = $transaction->account()->first(); - /** @var \AccountType $type */ - $type = $account->accountType()->first(); - if ($type->type == 'Expense account' || $type->type == 'Beneficiary account') { - $description .= ' ' . strtolower($account->name); - } - } - - $count = 0; - foreach ($matches as $word) { - if (!(strpos($description, strtolower($word)) === false)) { - $count++; - } - } - if ($count >= count($matches)) { - $wordMatch = true; - } - - /* - * Match amount. - */ - - $amountMatch = false; - if (count($transactions) > 1) { - - $amount = max(floatval($transactions[0]->amount), floatval($transactions[1]->amount)); - $min = floatval($recurring->amount_min); - $max = floatval($recurring->amount_max); - if ($amount >= $min && $amount <= $max) { - $amountMatch = true; - } - } - - /* - * If both, update! - */ - if ($wordMatch && $amountMatch) { - $journal->recurringTransaction()->associate($recurring); - $journal->save(); - } - - } - - /** - * Trigger! - * - * @param Dispatcher $events - */ - public function subscribe(Dispatcher $events) - { - //$events->listen('recurring.rescan', 'Firefly\Trigger\Recurring\EloquentRecurringTrigger@rescan'); - } - - /** - * @param \RecurringTransaction $recurring - */ - public function update(\RecurringTransaction $recurring) - { - } -} \ No newline at end of file diff --git a/app/lib/Firefly/Validation/FireflyValidator.php b/app/lib/Firefly/Validation/FireflyValidator.php deleted file mode 100644 index cb3bb93d8e..0000000000 --- a/app/lib/Firefly/Validation/FireflyValidator.php +++ /dev/null @@ -1,22 +0,0 @@ -app->validator->resolver( - function ($translator, $data, $rules, $messages) { - return new FireflyValidator($translator, $data, $rules, $messages); - } - ); - } - - public function register() - { - } -} \ No newline at end of file diff --git a/app/routes.php b/app/routes.php index eff0807f35..73def8cf0a 100644 --- a/app/routes.php +++ b/app/routes.php @@ -176,8 +176,6 @@ Route::group( Route::get('/chart/home/categories', ['uses' => 'GoogleChartController@allCategoriesHomeChart']); Route::get('/chart/home/recurring', ['uses' => 'GoogleChartController@recurringTransactionsOverview']); Route::get('/chart/account/{account}/{view?}', ['uses' => 'GoogleChartController@accountBalanceChart']); - Route::get('/chart/sankey/{account}/out/{view?}', ['uses' => 'GoogleChartController@accountSankeyOutChart']); - Route::get('/chart/sankey/{account}/in/{view?}', ['uses' => 'GoogleChartController@accountSankeyInChart']); Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']); Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']); Route::get('/chart/recurring/{recurring}', ['uses' => 'GoogleChartController@recurringOverview']); diff --git a/app/views/accounts/show.blade.php b/app/views/accounts/show.blade.php index ce978f17bc..d54e245446 100644 --- a/app/views/accounts/show.blade.php +++ b/app/views/accounts/show.blade.php @@ -33,29 +33,6 @@ -
-
-
-
- Out -
-
-
-
-
-
-
-
-
- In -
-
-
-
-
-
-
-
diff --git a/composer.json b/composer.json index 7b3fad61ff..f551a8ccde 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,9 @@ "mockery/mockery": "@stable", "league/factory-muffin": "~2.0", "codeception/codeception": "*", - "codeception/c3": "2.*" + "codeception/c3": "2.*", + "sebastian/phpcpd": "*", + "sebastian/phpdcd": "*" }, "autoload": { diff --git a/composer.lock b/composer.lock index 0b40a3d726..3408416d1b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "4149e5d1a8b58787b3e9f68fc8cf40b9", + "hash": "54b87a48702c03e0eef7f37449f7888a", "packages": [ { "name": "classpreloader/classpreloader", @@ -3880,6 +3880,45 @@ ], "time": "2014-09-10 00:51:36" }, + { + "name": "sebastian/finder-facade", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/finder-facade.git", + "reference": "1e396fda3449fce9df032749fa4fa2619e0347e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/1e396fda3449fce9df032749fa4fa2619e0347e0", + "reference": "1e396fda3449fce9df032749fa4fa2619e0347e0", + "shasum": "" + }, + "require": { + "symfony/finder": ">=2.2.0", + "theseer/fdomdocument": ">=1.3.1" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", + "homepage": "https://github.com/sebastianbergmann/finder-facade", + "time": "2013-05-28 06:10:03" + }, { "name": "sebastian/global-state", "version": "1.0.0", @@ -3931,6 +3970,111 @@ ], "time": "2014-10-06 09:23:50" }, + { + "name": "sebastian/phpcpd", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpcpd.git", + "reference": "a9462153f2dd90466a010179901d31fbff598365" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/a9462153f2dd90466a010179901d31fbff598365", + "reference": "a9462153f2dd90466a010179901d31fbff598365", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-timer": ">=1.0.4", + "sebastian/finder-facade": ">=1.1.0", + "sebastian/version": ">=1.0.3", + "symfony/console": ">=2.2.0", + "theseer/fdomdocument": "~1.4" + }, + "bin": [ + "phpcpd" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Copy/Paste Detector (CPD) for PHP code.", + "homepage": "https://github.com/sebastianbergmann/phpcpd", + "time": "2014-03-31 09:25:30" + }, + { + "name": "sebastian/phpdcd", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpdcd.git", + "reference": "10246f167713d0bd0b74540ca81e4caf30b72157" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpdcd/zipball/10246f167713d0bd0b74540ca81e4caf30b72157", + "reference": "10246f167713d0bd0b74540ca81e4caf30b72157", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-timer": ">=1.0.4", + "phpunit/php-token-stream": ">=1.1.3", + "sebastian/finder-facade": ">=1.1.0", + "sebastian/version": ">=1.0.3", + "symfony/console": ">=2.2.0" + }, + "require-dev": { + "phpunit/phpunit": "~3.7" + }, + "bin": [ + "phpdcd" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Dead Code Detector (DCD) for PHP code.", + "homepage": "https://github.com/sebastianbergmann/phpdcd", + "time": "2014-04-27 06:42:32" + }, { "name": "sebastian/version", "version": "1.0.3", @@ -4157,6 +4301,46 @@ "description": "Symfony Yaml Component", "homepage": "http://symfony.com", "time": "2014-12-02 20:19:20" + }, + { + "name": "theseer/fdomdocument", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/fDOMDocument.git", + "reference": "d08cf070350f884c63fc9078d27893c2ab6c7cef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/d08cf070350f884c63fc9078d27893c2ab6c7cef", + "reference": "d08cf070350f884c63fc9078d27893c2ab6c7cef", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "lib-libxml": "*", + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "lead" + } + ], + "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", + "homepage": "https://github.com/theseer/fDOMDocument", + "time": "2014-09-13 10:57:19" } ], "aliases": [], diff --git a/public/assets/javascript/firefly/accounts.js b/public/assets/javascript/firefly/accounts.js index 0a3ec71d4a..b63d11ca98 100644 --- a/public/assets/javascript/firefly/accounts.js +++ b/public/assets/javascript/firefly/accounts.js @@ -3,10 +3,5 @@ $(function () { if (typeof(googleLineChart) == "function" && typeof accountID != 'undefined' && typeof view != 'undefined') { googleLineChart('chart/account/' + accountID + '/' + view, 'overview-chart'); } - // - if (typeof(googleSankeyChart) == 'function' && typeof accountID != 'undefined' && typeof view != 'undefined') { - googleSankeyChart('chart/sankey/' + accountID + '/out' + '/' + view, 'account-out-sankey'); - googleSankeyChart('chart/sankey/' + accountID + '/in' + '/' + view, 'account-in-sankey'); - } }); \ No newline at end of file diff --git a/public/assets/javascript/firefly/gcharts.js b/public/assets/javascript/firefly/gcharts.js index c0bc5dd090..4aebc1a993 100644 --- a/public/assets/javascript/firefly/gcharts.js +++ b/public/assets/javascript/firefly/gcharts.js @@ -224,43 +224,3 @@ function googlePieChart(URL, container, options) { console.log('No container found called "' + container + '"'); } } - -function googleSankeyChart(URL, container, options) { - if ($('#' + container).length == 1) { - $.getJSON(URL).success(function (data) { - /* - Get the data from the JSON - */ - gdata = new google.visualization.DataTable(data); - - /* - Format as money - */ - - if (gdata.getNumberOfRows() < 1) { - $('#' + container).parent().parent().remove(); - return; - } else if (gdata.getNumberOfRows() < 6) { - defaultSankeyChartOptions.height = 100 - } else { - defaultSankeyChartOptions.height = 400 - } - - - /* - Create a new google charts object. - */ - var chart = new google.visualization.Sankey(document.getElementById(container)); - - /* - Draw it: - */ - chart.draw(gdata, options || defaultSankeyChartOptions); - - }).fail(function () { - $('#' + container).addClass('google-chart-error'); - }); - } else { - console.log('No container found called "' + container + '"'); - } -} \ No newline at end of file diff --git a/public/assets/javascript/firefly/gcharts.options.js b/public/assets/javascript/firefly/gcharts.options.js index dc18206bd1..3c1ec5a131 100644 --- a/public/assets/javascript/firefly/gcharts.options.js +++ b/public/assets/javascript/firefly/gcharts.options.js @@ -136,6 +136,3 @@ var defaultPieChartOptions = { colors: ["#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"] }; -var defaultSankeyChartOptions = { - height: 400 -} \ No newline at end of file