mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-08-27 08:02:23 +00:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b8e07ac38e | ||
|
c7273e4b60 | ||
|
33d4fd4af0 | ||
|
71b11e26d2 | ||
|
77f4111b09 | ||
|
9965297f36 | ||
|
5ca466a826 | ||
|
90f417facc | ||
|
eacbd038b7 | ||
|
5446e85424 | ||
|
77b4942691 | ||
|
824cf71e0b | ||
|
239bbd30c0 | ||
|
6f6b653d54 | ||
|
e4155ce735 | ||
|
7eaf307834 | ||
|
7db7950415 | ||
|
fcc184cd2a | ||
|
6423feff3a | ||
|
e97da25d5a | ||
|
f49a37a38e | ||
|
07e6b33095 | ||
|
9136b50e3c | ||
|
c3fd5c7136 | ||
|
98612dd253 | ||
|
4d7f5238dd | ||
|
f472a01a80 | ||
|
420b5790e3 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -11,4 +11,5 @@ tests/_output/*
|
||||
_ide_helper.php
|
||||
/build/logs/clover.xml
|
||||
index.html*
|
||||
app/storage/firefly-export*
|
||||
app/storage/firefly-export*
|
||||
.vagrant
|
||||
|
@@ -2,7 +2,6 @@ firefly-iii
|
||||
===========
|
||||
|
||||
[](https://travis-ci.org/JC5/firefly-iii)
|
||||
[](https://coveralls.io/r/JC5/firefly-iii?branch=master)
|
||||

|
||||
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
|
@@ -26,6 +26,9 @@ $(function () {
|
||||
str += '<span style="color:' + colour + '">' + point.series.name + '</span>: € ' + Highcharts.numberFormat(point.y, 2) + '<br />';
|
||||
}
|
||||
if (x == 1) {
|
||||
str += '<span style="color:' + colour + '">' + point.series.name + '</span>: € ' + Highcharts.numberFormat(point.y, 2) + '<br />';
|
||||
}
|
||||
if (x == 2) {
|
||||
str += '<span style="color:' + colour + '">' + point.series.name + '</span>: ' + Highcharts.numberFormat(point.y, 1) + '%<br />';
|
||||
}
|
||||
}
|
||||
|
3
app/config/.gitignore
vendored
3
app/config/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
local/
|
||||
laptop/
|
||||
laptop/
|
||||
vagrant/
|
@@ -8,6 +8,8 @@ use Firefly\Storage\Account\AccountRepositoryInterface as ARI;
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
|
||||
|
||||
class AccountController extends \BaseController
|
||||
{
|
||||
|
||||
@@ -66,7 +68,8 @@ class AccountController extends \BaseController
|
||||
public function edit(Account $account)
|
||||
{
|
||||
$openingBalance = $this->_accounts->openingBalanceTransaction($account);
|
||||
return View::make('accounts.edit')->with('account', $account)->with('openingBalance', $openingBalance)->with('title','Edit account "'.$account->name.'"');
|
||||
return View::make('accounts.edit')->with('account', $account)->with('openingBalance', $openingBalance)
|
||||
->with('title', 'Edit account "' . $account->name . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +93,7 @@ class AccountController extends \BaseController
|
||||
}
|
||||
}
|
||||
|
||||
return View::make('accounts.index')->with('accounts', $set)->with('title','All your accounts');
|
||||
return View::make('accounts.index')->with('accounts', $set)->with('title', 'All your accounts');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use \Illuminate\Routing\Controller;
|
||||
|
||||
/**
|
||||
* Class BaseController
|
||||
*/
|
||||
|
@@ -6,6 +6,9 @@ use Firefly\Storage\Budget\BudgetRepositoryInterface as BRI;
|
||||
|
||||
/**
|
||||
* Class BudgetController
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*
|
||||
*/
|
||||
class BudgetController extends BaseController
|
||||
{
|
||||
@@ -14,12 +17,12 @@ class BudgetController extends BaseController
|
||||
protected $_repository;
|
||||
|
||||
/**
|
||||
* @param BI $budgets
|
||||
* @param BI $budgets
|
||||
* @param BRI $repository
|
||||
*/
|
||||
public function __construct(BI $budgets, BRI $repository)
|
||||
{
|
||||
$this->_budgets = $budgets;
|
||||
$this->_budgets = $budgets;
|
||||
$this->_repository = $repository;
|
||||
}
|
||||
|
||||
@@ -30,7 +33,7 @@ class BudgetController extends BaseController
|
||||
{
|
||||
$periods = \Config::get('firefly.periods_to_text');
|
||||
|
||||
return View::make('budgets.create')->with('periods', $periods);
|
||||
return View::make('budgets.create')->with('periods', $periods)->with('title', 'Create a new budget');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,7 +43,8 @@ class BudgetController extends BaseController
|
||||
*/
|
||||
public function delete(Budget $budget)
|
||||
{
|
||||
return View::make('budgets.delete')->with('budget', $budget);
|
||||
return View::make('budgets.delete')->with('budget', $budget)
|
||||
->with('title', 'Delete budget "' . $budget->name . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,20 +54,16 @@ class BudgetController extends BaseController
|
||||
*/
|
||||
public function destroy(Budget $budget)
|
||||
{
|
||||
// remove budget
|
||||
Event::fire('budgets.destroy', [$budget]); // just before deletion.
|
||||
$result = $this->_repository->destroy($budget);
|
||||
if ($result === true) {
|
||||
Session::flash('success', 'The budget was deleted.');
|
||||
if (Input::get('from') == 'date') {
|
||||
return Redirect::route('budgets.index');
|
||||
} else {
|
||||
return Redirect::route('budgets.index.budget');
|
||||
}
|
||||
} else {
|
||||
Session::flash('error', 'Could not delete the budget. Check the logs to be sure.');
|
||||
}
|
||||
$this->_repository->destroy($budget);
|
||||
Session::flash('success', 'The budget was deleted.');
|
||||
|
||||
return Redirect::route('budgets.index');
|
||||
// redirect:
|
||||
if (Input::get('from') == 'date') {
|
||||
return Redirect::route('budgets.index');
|
||||
}
|
||||
return Redirect::route('budgets.index.budget');
|
||||
|
||||
}
|
||||
|
||||
@@ -74,7 +74,8 @@ class BudgetController extends BaseController
|
||||
*/
|
||||
public function edit(Budget $budget)
|
||||
{
|
||||
return View::make('budgets.edit')->with('budget', $budget);
|
||||
return View::make('budgets.edit')->with('budget', $budget)
|
||||
->with('title', 'Edit budget "' . $budget->name . '"');
|
||||
|
||||
}
|
||||
|
||||
@@ -84,62 +85,71 @@ class BudgetController extends BaseController
|
||||
public function indexByBudget()
|
||||
{
|
||||
$budgets = $this->_repository->get();
|
||||
$today = new Carbon;
|
||||
|
||||
|
||||
return View::make('budgets.indexByBudget')->with('budgets', $budgets)->with('today', $today);
|
||||
return View::make('budgets.indexByBudget')->with('budgets', $budgets)->with('today', new Carbon)
|
||||
->with('title', 'All your budgets grouped by budget');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this|\Illuminate\View\View
|
||||
* @throws Firefly\Exception\FireflyException
|
||||
* @return $this
|
||||
*/
|
||||
public function indexByDate()
|
||||
{
|
||||
// get a list of dates by getting all repetitions:
|
||||
$set = $this->_repository->get();
|
||||
$set = $this->_repository->get();
|
||||
$budgets = $this->_budgets->organizeByDate($set);
|
||||
|
||||
|
||||
return View::make('budgets.indexByDate')->with('budgets', $budgets);
|
||||
return View::make('budgets.indexByDate')->with('budgets', $budgets)
|
||||
->with('title', 'All your budgets grouped by date');
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Three use cases for this view:
|
||||
*
|
||||
* - Show everything.
|
||||
* - Show a specific repetition.
|
||||
* - Show everything shows NO repetition.
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param LimitRepetition $repetition
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function show(Budget $budget)
|
||||
public function show(Budget $budget, \LimitRepetition $repetition = null)
|
||||
{
|
||||
/**
|
||||
* Use the
|
||||
*/
|
||||
$useSessionDates = Input::get('useSession') == 'true' ? true : false;
|
||||
|
||||
|
||||
$filters = [];
|
||||
|
||||
if (!is_null(Input::get('rep'))) {
|
||||
$repetitionId = intval(Input::get('rep'));
|
||||
$repetitions = $this->_budgets->organizeRepetition($repetitionId);
|
||||
$filters[] = $repetitions[0]['limit'];
|
||||
$filters[] = $repetitions[0]['limitrepetition'];
|
||||
} else {
|
||||
if (Input::get('noenvelope') == 'true') {
|
||||
$repetitions = $this->_budgets->outsideRepetitions($budget);
|
||||
$filters[] = 'no_envelope';
|
||||
} else {
|
||||
// grab all limit repetitions, order them, show them:
|
||||
$repetitions = $this->_budgets->organizeRepetitions($budget, $useSessionDates);
|
||||
}
|
||||
$view = null;
|
||||
$title = null;
|
||||
\Log::debug('Is envelope true? ' . (Input::get('noenvelope') == 'true'));
|
||||
switch (true) {
|
||||
case (!is_null($repetition)):
|
||||
$data = $this->_budgets->organizeRepetition($repetition);
|
||||
$view = 1;
|
||||
$title = $budget->name . ', ' . $repetition->periodShow() . ', ' . mf($repetition->limit->amount,
|
||||
false);
|
||||
break;
|
||||
case (Input::get('noenvelope') == 'true'):
|
||||
$data = $this->_budgets->outsideRepetitions($budget);
|
||||
$view = 2;
|
||||
$title = $budget->name . ', transactions outside an envelope';
|
||||
break;
|
||||
default:
|
||||
$data = $this->_budgets->organizeRepetitions($budget, $useSessionDates);
|
||||
$view = $useSessionDates ? 3 : 4;
|
||||
$title = $useSessionDates ? $budget->name . ' in session period' : $budget->name;
|
||||
break;
|
||||
}
|
||||
|
||||
return View::make('budgets.show')->with('budget', $budget)->with('repetitions', $repetitions)->with(
|
||||
'filters', $filters
|
||||
)->with('highlight', Input::get('highlight'))->with('useSessionDates', $useSessionDates);
|
||||
return View::make('budgets.show')
|
||||
->with('budget', $budget)
|
||||
->with('repetitions', $data)
|
||||
->with('view', $view)
|
||||
->with('highlight', Input::get('highlight'))
|
||||
->with('useSessionDates', $useSessionDates)
|
||||
->with('title', $title);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -13,12 +13,12 @@ class CategoryController extends BaseController
|
||||
|
||||
/**
|
||||
* @param CRI $repository
|
||||
* @param CI $category
|
||||
* @param CI $category
|
||||
*/
|
||||
public function __construct(CRI $repository, CI $category)
|
||||
{
|
||||
$this->_repository = $repository;
|
||||
$this->_category = $category;
|
||||
$this->_category = $category;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,7 +26,7 @@ class CategoryController extends BaseController
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return View::make('categories.create');
|
||||
return View::make('categories.create')->with('title', 'Create a new category');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +36,8 @@ class CategoryController extends BaseController
|
||||
*/
|
||||
public function delete(Category $category)
|
||||
{
|
||||
return View::make('categories.delete')->with('category', $category);
|
||||
return View::make('categories.delete')->with('category', $category)
|
||||
->with('title', 'Delete category "' . $category->name . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,13 +47,8 @@ class CategoryController extends BaseController
|
||||
*/
|
||||
public function destroy(Category $category)
|
||||
{
|
||||
$result = $this->_repository->destroy($category);
|
||||
if ($result === true) {
|
||||
Session::flash('success', 'The category was deleted.');
|
||||
} else {
|
||||
Session::flash('error', 'Could not delete the category. Check the logs to be sure.');
|
||||
}
|
||||
|
||||
$this->_repository->destroy($category);
|
||||
Session::flash('success', 'The category was deleted.');
|
||||
return Redirect::route('categories.index');
|
||||
}
|
||||
|
||||
@@ -63,7 +59,8 @@ class CategoryController extends BaseController
|
||||
*/
|
||||
public function edit(Category $category)
|
||||
{
|
||||
return View::make('categories.edit')->with('category', $category);
|
||||
return View::make('categories.edit')->with('category', $category)
|
||||
->with('title', 'Edit category "' . $category->name . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +70,8 @@ class CategoryController extends BaseController
|
||||
{
|
||||
$categories = $this->_repository->get();
|
||||
|
||||
return View::make('categories.index')->with('categories', $categories);
|
||||
return View::make('categories.index')->with('categories', $categories)
|
||||
->with('title', 'All your categories');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,14 +82,14 @@ class CategoryController extends BaseController
|
||||
public function show(Category $category)
|
||||
{
|
||||
$start = \Session::get('start');
|
||||
$end = \Session::get('end');
|
||||
$end = \Session::get('end');
|
||||
|
||||
|
||||
$journals = $this->_category->journalsInRange($category, $start, $end);
|
||||
|
||||
return View::make('categories.show')->with('category', $category)->with('journals', $journals)->with(
|
||||
'highlight', Input::get('highlight')
|
||||
);
|
||||
'highlight', Input::get('highlight')
|
||||
)->with('title', 'Overview for category "'.$category->name.'"');;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -20,42 +20,35 @@ class ChartController extends BaseController
|
||||
*/
|
||||
public function __construct(ChartInterface $chart, AccountRepositoryInterface $accounts)
|
||||
{
|
||||
$this->_chart = $chart;
|
||||
$this->_chart = $chart;
|
||||
$this->_accounts = $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a budget, all limits and all their repetitions and displays three numbers per repetition:
|
||||
* the amount of money in the repetition (represented as "an envelope"), the amount spent and the spent percentage.
|
||||
*
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function budgetDefault(\Budget $budget)
|
||||
{
|
||||
$expense = [];
|
||||
$left = [];
|
||||
$expense = [];
|
||||
$left = [];
|
||||
$envelope = [];
|
||||
// get all limit repetitions for this budget.
|
||||
/** @var \Limit $limit */
|
||||
foreach ($budget->limits as $limit) {
|
||||
/** @var \LimitRepetition $rep */
|
||||
foreach ($limit->limitrepetitions as $rep) {
|
||||
$spentInRep = \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', '>=', $rep->startdate->format('Y-m-d')
|
||||
)->where('transaction_journals.date', '<=', $rep->enddate->format('Y-m-d'))->where(
|
||||
'amount', '>', 0
|
||||
)->sum('amount');
|
||||
|
||||
|
||||
$pct = round(($spentInRep / $limit->amount) * 100, 2);
|
||||
$name = $rep->periodShow();
|
||||
$expense[] = [$name, floatval($spentInRep)];
|
||||
$left[] = [$name, $pct];
|
||||
// get the amount of money spent in this period on this budget.
|
||||
$spentInRep = $rep->amount - $rep->left();
|
||||
$pct = round((floatval($spentInRep) / floatval($limit->amount)) * 100, 2);
|
||||
$name = $rep->periodShow();
|
||||
$envelope[] = [$name, floatval($limit->amount)];
|
||||
$expense[] = [$name, floatval($spentInRep)];
|
||||
$left[] = [$name, $pct];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +56,12 @@ class ChartController extends BaseController
|
||||
'chart_title' => 'Overview for budget ' . $budget->name,
|
||||
'subtitle' => 'All envelopes',
|
||||
'series' => [
|
||||
[
|
||||
'type' => 'line',
|
||||
'yAxis' => 1,
|
||||
'name' => 'Amount in envelope',
|
||||
'data' => $envelope
|
||||
],
|
||||
[
|
||||
'type' => 'column',
|
||||
'name' => 'Expenses in envelope',
|
||||
@@ -75,6 +74,7 @@ class ChartController extends BaseController
|
||||
'data' => $left
|
||||
]
|
||||
|
||||
|
||||
]
|
||||
];
|
||||
|
||||
@@ -82,29 +82,27 @@ class ChartController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a single limit repetition (so a single "envelope") and displays the amount of money spent
|
||||
* per day and subsequently how much money is left.
|
||||
*
|
||||
* @param LimitRepetition $rep
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function budgetLimit(\LimitRepetition $rep)
|
||||
{
|
||||
$budget = $rep->limit->budget;
|
||||
$current = clone $rep->startdate;
|
||||
$expense = [];
|
||||
$leftInLimit = [];
|
||||
$budget = $rep->limit->budget;
|
||||
$current = clone $rep->startdate;
|
||||
$expense = [];
|
||||
$leftInLimit = [];
|
||||
$currentLeftInLimit = floatval($rep->limit->amount);
|
||||
while ($current <= $rep->enddate) {
|
||||
$spent = \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', $current->format('Y-m-d')
|
||||
)->where('amount', '>', 0)->sum('amount');
|
||||
$spent = floatval($spent) == 0 ? null : floatval($spent);
|
||||
$entry = [$current->timestamp * 1000, $spent];
|
||||
$expense[] = $entry;
|
||||
$spent = $this->_chart->spentOnDay($budget, $current);
|
||||
$spent = floatval($spent) == 0 ? null : floatval($spent);
|
||||
$entry = [$current->timestamp * 1000, $spent];
|
||||
$expense[] = $entry;
|
||||
$currentLeftInLimit = $currentLeftInLimit - $spent;
|
||||
$leftInLimit[] = [$current->timestamp * 1000, $currentLeftInLimit];
|
||||
$leftInLimit[] = [$current->timestamp * 1000, $currentLeftInLimit];
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
@@ -132,53 +130,44 @@ class ChartController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes a budget and gets all transactions in it which haven't got an envelope (limit).
|
||||
*
|
||||
* Usually this means that very old and unorganized or very NEW transactions get displayed; there was never an
|
||||
* envelope or it hasn't been created (yet).
|
||||
*
|
||||
*
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function budgetNoLimits(\Budget $budget)
|
||||
{
|
||||
$inRepetitions = [];
|
||||
foreach ($budget->limits as $limit) {
|
||||
foreach ($limit->limitrepetitions as $repetition) {
|
||||
$set = $budget->transactionjournals()->leftJoin(
|
||||
'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id'
|
||||
)->where('transaction_types.type', 'Withdrawal')->where(
|
||||
'date', '>=', $repetition->startdate->format('Y-m-d')
|
||||
)->where('date', '<=', $repetition->enddate->format('Y-m-d'))->orderBy('date', 'DESC')->get(
|
||||
['transaction_journals.id']
|
||||
);
|
||||
foreach ($set as $item) {
|
||||
$inRepetitions[] = $item->id;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We can go about this two ways. Either we find all transactions which definitely are IN an envelope
|
||||
* and exclude them or we search for transactions outside of the range of any of the envelopes we have.
|
||||
*
|
||||
* Since either is shitty we go with the first one because it's easier to build.
|
||||
*/
|
||||
$inRepetitions = $this->_chart->allJournalsInBudgetEnvelope($budget);
|
||||
|
||||
}
|
||||
|
||||
$query = $budget->transactionjournals()->whereNotIn(
|
||||
'transaction_journals.id', $inRepetitions
|
||||
)->orderBy('date', 'DESC')->orderBy(
|
||||
'transaction_journals.id', 'DESC'
|
||||
);
|
||||
/*
|
||||
* With this set of id's, we can search for all journals NOT in that set.
|
||||
* BUT they have to be in the budget (duh).
|
||||
*/
|
||||
$set = $this->_chart->journalsNotInSet($budget, $inRepetitions);
|
||||
/*
|
||||
* Next step: get all transactions for those journals.
|
||||
*/
|
||||
$transactions = $this->_chart->transactionsByJournals($set);
|
||||
|
||||
|
||||
$result = $query->get(['transaction_journals.id']);
|
||||
$set = [];
|
||||
foreach ($result as $entry) {
|
||||
$set[] = $entry->id;
|
||||
}
|
||||
// all transactions for these journals, grouped by date and SUM
|
||||
$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`')]
|
||||
);
|
||||
|
||||
|
||||
// this set builds the chart:
|
||||
/*
|
||||
* this set builds the chart:
|
||||
*/
|
||||
$expense = [];
|
||||
|
||||
foreach ($transactions as $t) {
|
||||
$date = new Carbon($t->date);
|
||||
$date = new Carbon($t->date);
|
||||
$expense[] = [$date->timestamp * 1000, floatval($t->aggregate)];
|
||||
}
|
||||
$return = [
|
||||
@@ -186,126 +175,104 @@ class ChartController extends BaseController
|
||||
'subtitle' => 'Not organized by an envelope',
|
||||
'series' => [
|
||||
[
|
||||
'type' => 'spline',
|
||||
'type' => 'column',
|
||||
'name' => 'Expenses per day',
|
||||
'data' => $expense
|
||||
]
|
||||
|
||||
]
|
||||
];
|
||||
|
||||
return Response::json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets all transactions within a budget within the period set by the current session
|
||||
* start and end date. It also includes any envelopes which might exist within this period.
|
||||
*
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function budgetSession(\Budget $budget)
|
||||
{
|
||||
$expense = [];
|
||||
$repetitionSeries = [];
|
||||
$current = clone Session::get('start');
|
||||
$end = clone Session::get('end');
|
||||
while ($current <= $end) {
|
||||
$spent = \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', $current->format('Y-m-d')
|
||||
)->where('amount', '>', 0)->sum('amount');
|
||||
$spent = floatval($spent) == 0 ? null : floatval($spent);
|
||||
if (!is_null($spent)) {
|
||||
$expense[] = [$current->timestamp * 1000, $spent];
|
||||
}
|
||||
$series = [];
|
||||
$end = clone Session::get('end');
|
||||
$start = clone Session::get('start');
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Expenses per day in the session's period. That's easy.
|
||||
*/
|
||||
$expense = [];
|
||||
$current = clone Session::get('start');
|
||||
while ($current <= $end) {
|
||||
$spent = $this->_chart->spentOnDay($budget, $current);
|
||||
$spent = floatval($spent) == 0 ? null : floatval($spent);
|
||||
$expense[] = [$current->timestamp * 1000, $spent];
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
// find all limit repetitions (for this budget) between start and end.
|
||||
$start = clone Session::get('start');
|
||||
$repetitionSeries[] = [
|
||||
$series[] = [
|
||||
'type' => 'column',
|
||||
'name' => 'Expenses per day',
|
||||
'data' => $expense
|
||||
];
|
||||
unset($expense, $spent, $current);
|
||||
|
||||
/*
|
||||
* Find all limit repetitions (for this budget) between start and end. This is
|
||||
* quite a complex query.
|
||||
*/
|
||||
$reps = $this->_chart->limitsInRange($budget, $start, $end);
|
||||
|
||||
/** @var \Limit $limit */
|
||||
foreach ($budget->limits as $limit) {
|
||||
$reps = $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'));
|
||||
}
|
||||
/*
|
||||
* For each limitrepetition we create a serie that contains the amount left in
|
||||
* the limitrepetition for its entire date-range. Entries are only actually included when they
|
||||
* fall into the charts date range.
|
||||
*
|
||||
* So example: we have a session date from Jan 15 to Jan 30. The limitrepetition starts at 1 Jan until 1 Feb.
|
||||
*
|
||||
* We loop from 1 Jan to 1 Feb but only include Jan 15 / Jan 30. But we do keep count of the amount outside
|
||||
* of these dates because otherwise the line might be wrong.
|
||||
*/
|
||||
/** @var \LimitRepetition $repetition */
|
||||
foreach ($reps as $repetition) {
|
||||
$limitAmount = $repetition->limit->amount;
|
||||
|
||||
// create a serie for the repetition.
|
||||
$currentSerie = [
|
||||
'type' => 'spline',
|
||||
'id' => 'rep-' . $repetition->id,
|
||||
'yAxis' => 1,
|
||||
'name' => 'Envelope #'.$repetition->id.' in ' . $repetition->periodShow(),
|
||||
'data' => []
|
||||
];
|
||||
$current = clone $repetition->startdate;
|
||||
while ($current <= $repetition->enddate) {
|
||||
if ($current >= $start && $current <= $end) {
|
||||
// spent on limit:
|
||||
$spentSoFar = $this->_chart->spentOnLimitRepetitionBetweenDates(
|
||||
$repetition, $repetition->startdate, $current
|
||||
);
|
||||
$leftInLimit = floatval($limitAmount) - floatval($spentSoFar);
|
||||
|
||||
// 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'));
|
||||
}
|
||||
);
|
||||
$currentSerie['data'][] = [$current->timestamp * 1000, $leftInLimit];
|
||||
}
|
||||
)
|
||||
->get();
|
||||
$currentLeftInLimit = floatval($limit->amount);
|
||||
/** @var \LimitRepetition $repetition */
|
||||
foreach ($reps as $repetition) {
|
||||
// create a serie for the repetition.
|
||||
$currentSerie = [
|
||||
'type' => 'spline',
|
||||
'id' => 'rep-' . $repetition->id,
|
||||
'yAxis' => 1,
|
||||
'name' => 'Envelope in ' . $repetition->periodShow(),
|
||||
'data' => []
|
||||
];
|
||||
$current = clone $repetition->startdate;
|
||||
while ($current <= $repetition->enddate) {
|
||||
if ($current >= Session::get('start') && $current <= Session::get('end')) {
|
||||
// spent on limit:
|
||||
$spentSoFar = \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', '>=', $repetition->startdate->format('Y-m-d')
|
||||
)->where('transaction_journals.date', '<=', $current->format('Y-m-d'))->where(
|
||||
'amount', '>', 0
|
||||
)->sum('amount');
|
||||
$spent = floatval($spent) == 0 ? null : floatval($spent);
|
||||
$currentLeftInLimit = floatval($limit->amount) - floatval($spentSoFar);
|
||||
|
||||
$currentSerie['data'][] = [$current->timestamp * 1000, $currentLeftInLimit];
|
||||
}
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
// do something here.
|
||||
$repetitionSeries[] = $currentSerie;
|
||||
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
// do something here.
|
||||
$series[] = $currentSerie;
|
||||
}
|
||||
|
||||
|
||||
$return = [
|
||||
'chart_title' => 'Overview for budget ' . $budget->name,
|
||||
'subtitle' =>
|
||||
'Between ' . Session::get('start')->format('M jS, Y') . ' and ' . Session::get('end')->format(
|
||||
'M jS, Y'
|
||||
),
|
||||
'series' => $repetitionSeries
|
||||
'series' => $series
|
||||
];
|
||||
|
||||
return Response::json($return);
|
||||
@@ -320,11 +287,11 @@ class ChartController extends BaseController
|
||||
public function categoryShowChart(Category $category)
|
||||
{
|
||||
$start = Session::get('start');
|
||||
$end = Session::get('end');
|
||||
$end = Session::get('end');
|
||||
$range = Session::get('range');
|
||||
|
||||
$serie = $this->_chart->categoryShowChart($category, $range, $start, $end);
|
||||
$data = [
|
||||
$data = [
|
||||
'chart_title' => $category->name,
|
||||
'subtitle' => '<a href="' . route('categories.show', [$category->id]) . '">View more</a>',
|
||||
'series' => $serie
|
||||
@@ -344,23 +311,23 @@ class ChartController extends BaseController
|
||||
{
|
||||
// get preferences and accounts (if necessary):
|
||||
$start = Session::get('start');
|
||||
$end = Session::get('end');
|
||||
$end = Session::get('end');
|
||||
|
||||
if (is_null($account)) {
|
||||
// get, depending on preferences:
|
||||
/** @var \Firefly\Helper\Preferences\PreferencesHelperInterface $prefs */
|
||||
$prefs = \App::make('Firefly\Helper\Preferences\PreferencesHelperInterface');
|
||||
$pref = $prefs->get('frontpageAccounts', []);
|
||||
$pref = $prefs->get('frontpageAccounts', []);
|
||||
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $acct */
|
||||
$acct = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$acct = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$accounts = $acct->getByIds($pref->data);
|
||||
} else {
|
||||
$accounts = [$account];
|
||||
}
|
||||
// loop and get array data.
|
||||
|
||||
$url = count($accounts) == 1 && is_array($accounts)
|
||||
$url = count($accounts) == 1 && is_array($accounts)
|
||||
? '<a href="' . route('accounts.show', [$account->id]) . '">View more</a>'
|
||||
:
|
||||
'<a href="' . route('accounts.index') . '">View more</a>';
|
||||
@@ -371,7 +338,6 @@ class ChartController extends BaseController
|
||||
];
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
\Log::debug('Now building series for ' . $account->name);
|
||||
$data['series'][] = $this->_chart->account($account, $start, $end);
|
||||
}
|
||||
|
||||
@@ -390,7 +356,7 @@ class ChartController extends BaseController
|
||||
{
|
||||
$account = $this->_accounts->findByName($name);
|
||||
|
||||
$date = Carbon::createFromDate($year, $month, $day);
|
||||
$date = Carbon::createFromDate($year, $month, $day);
|
||||
$result = $this->_chart->accountDailySummary($account, $date);
|
||||
|
||||
return View::make('charts.info')->with('rows', $result['rows'])->with('sum', $result['sum'])->with(
|
||||
@@ -414,7 +380,7 @@ class ChartController extends BaseController
|
||||
public function homeCategories()
|
||||
{
|
||||
$start = Session::get('start');
|
||||
$end = Session::get('end');
|
||||
$end = Session::get('end');
|
||||
|
||||
return Response::json($this->_chart->categories($start, $end));
|
||||
|
||||
|
@@ -38,6 +38,10 @@ class HomeController extends BaseController
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
// Queue::push(function($job)
|
||||
// {
|
||||
// Log::debug('This is a job!');
|
||||
// });
|
||||
|
||||
\Event::fire('limits.check');
|
||||
\Event::fire('piggybanks.check');
|
||||
|
46
app/controllers/MigrateController.php
Normal file
46
app/controllers/MigrateController.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MigrateController
|
||||
*/
|
||||
class MigrateController extends BaseController
|
||||
{
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('migrate.index')->with('index', 'Migration');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function upload()
|
||||
{
|
||||
if (Input::hasFile('file') && Input::file('file')->isValid()) {
|
||||
// move file to storage:
|
||||
// ->move($destinationPath, $fileName);
|
||||
$path = storage_path();
|
||||
$fileName = 'firefly-iii-import-' . date('Y-m-d-H-i') . '.json';
|
||||
$fullName = $path . DIRECTORY_SEPARATOR . $fileName;
|
||||
if (is_writable($path)) {
|
||||
Input::file('file')->move($path, $fileName);
|
||||
// so now we push something in a queue and do something with it! Yay!
|
||||
\Log::debug('Pushed a job to start the import.');
|
||||
Queue::push('Firefly\Queue\Import@start', ['file' => $fullName, 'user' => \Auth::user()->id]);
|
||||
Session::flash('success', 'The import job has been queued. Please be patient. Data will appear');
|
||||
return Redirect::route('index');
|
||||
}
|
||||
Session::flash('error', 'Could not save file to storage.');
|
||||
return Redirect::route('migrate.index');
|
||||
|
||||
} else {
|
||||
Session::flash('error', 'Please upload a file.');
|
||||
return Redirect::route('migrate.index');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -197,6 +197,7 @@ class TransactionController extends BaseController
|
||||
}
|
||||
|
||||
// trigger the creation for recurring transactions.
|
||||
Event::fire('journals.store',[$journal]);
|
||||
|
||||
if (Input::get('create') == '1') {
|
||||
return Redirect::route('transactions.create', [$what])->withInput();
|
||||
@@ -225,6 +226,7 @@ class TransactionController extends BaseController
|
||||
if ($journal->validate()) {
|
||||
// has been saved, return to index:
|
||||
Session::flash('success', 'Transaction updated!');
|
||||
Event::fire('journals.update',[$journal]);
|
||||
|
||||
return Redirect::route('transactions.index');
|
||||
} else {
|
||||
|
@@ -25,8 +25,8 @@ class CreateRecurringTransactionsTable extends Migration
|
||||
$table->integer('user_id')->unsigned();
|
||||
$table->string('name', 50);
|
||||
$table->string('match', 255);
|
||||
$table->decimal('amount_max', 10, 2);
|
||||
$table->decimal('amount_min', 10, 2);
|
||||
$table->decimal('amount_max', 10, 2);
|
||||
$table->date('date');
|
||||
$table->boolean('active');
|
||||
|
@@ -24,6 +24,7 @@ class CreateTransactionJournalsTable extends Migration
|
||||
$table->timestamps();
|
||||
$table->integer('user_id')->unsigned();
|
||||
$table->integer('transaction_type_id')->unsigned();
|
||||
$table->integer('recurring_transaction_id')->unsigned()->nullable();
|
||||
$table->integer('transaction_currency_id')->unsigned();
|
||||
$table->string('description', 255)->nullable();
|
||||
$table->boolean('completed');
|
||||
@@ -34,6 +35,11 @@ class CreateTransactionJournalsTable extends Migration
|
||||
->references('id')->on('transaction_types')
|
||||
->onDelete('cascade');
|
||||
|
||||
// connect transaction journals to recurring transactions
|
||||
$table->foreign('recurring_transaction_id')
|
||||
->references('id')->on('recurring_transactions')
|
||||
->onDelete('set null');
|
||||
|
||||
// connect transaction journals to transaction currencies
|
||||
$table->foreign('transaction_currency_id')
|
||||
->references('id')->on('transaction_currencies')
|
||||
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateImportmapsTable extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('importmaps', function(Blueprint $table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
$table->integer('user_id')->unsigned();
|
||||
$table->string('file',500);
|
||||
|
||||
// connect maps to users
|
||||
$table->foreign('user_id')
|
||||
->references('id')->on('users')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('importmaps');
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateImportentriesTable extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('importentries', function(Blueprint $table)
|
||||
{
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
$table->string('class',200);
|
||||
$table->integer('importmap_id')->unsigned();
|
||||
$table->integer('old')->unsigned();
|
||||
$table->integer('new')->unsigned();
|
||||
|
||||
// map import entries to import map.
|
||||
// connect accounts to account_types
|
||||
$table->foreign('importmap_id')
|
||||
->references('id')->on('importmaps')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('importentries');
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class CreateFailedJobsTable extends Migration
|
||||
{
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('failed_jobs');
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('failed_jobs', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->text('connection');
|
||||
$table->text('queue');
|
||||
$table->text('payload');
|
||||
$table->timestamp('failed_at');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -11,16 +11,20 @@ class AccountTypeSeeder extends Seeder
|
||||
DB::table('account_types')->delete();
|
||||
|
||||
AccountType::create(
|
||||
['type' => 'Default account','editable' => true]
|
||||
['type' => 'Default account', 'editable' => true]
|
||||
);
|
||||
AccountType::create(
|
||||
['type' => 'Cash account','editable' => false]
|
||||
['type' => 'Cash account', 'editable' => false]
|
||||
);
|
||||
AccountType::create(
|
||||
['type' => 'Initial balance account','editable' => false]
|
||||
['type' => 'Initial balance account', 'editable' => false]
|
||||
);
|
||||
AccountType::create(
|
||||
['type' => 'Beneficiary account','editable' => true]
|
||||
['type' => 'Beneficiary account', 'editable' => true]
|
||||
);
|
||||
|
||||
AccountType::create(
|
||||
['type' => 'Import account', 'editable' => false]
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -2,8 +2,6 @@
|
||||
|
||||
namespace Firefly\Helper\Controllers;
|
||||
|
||||
use Firefly\Exception\FireflyException;
|
||||
|
||||
/**
|
||||
* Class Account
|
||||
*
|
||||
@@ -11,15 +9,15 @@ use Firefly\Exception\FireflyException;
|
||||
*/
|
||||
class Account implements AccountInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
*
|
||||
* @return mixed
|
||||
* @return \TransactionJournal|null
|
||||
*/
|
||||
public function openingBalanceTransaction(\Account $account)
|
||||
{
|
||||
return \TransactionJournal::
|
||||
withRelevantData()->account($account)
|
||||
return \TransactionJournal::withRelevantData()
|
||||
->account($account)
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=',
|
||||
'transaction_journals.transaction_type_id')
|
||||
->where('transaction_types.type', 'Opening balance')
|
||||
@@ -27,55 +25,54 @@ class Account implements AccountInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
* @param $perPage
|
||||
* 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.
|
||||
*
|
||||
* @return mixed|void
|
||||
* If it is the case, we remove $item and continue like nothing ever happened. This will however,
|
||||
* mess up some statisics but we can live with that. We might be needing some cleanup routine in the future.
|
||||
*
|
||||
* For now, we simply warn 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 = [
|
||||
'budgets' => [],
|
||||
'categories' => [],
|
||||
'accounts' => []
|
||||
'accounts' => []
|
||||
];
|
||||
$items = [];
|
||||
|
||||
|
||||
// build a query:
|
||||
$query = \TransactionJournal::withRelevantData()->defaultSorting()->account($account)->after($start)
|
||||
$query = \TransactionJournal::withRelevantData()
|
||||
->defaultSorting()
|
||||
->account($account)
|
||||
->after($start)
|
||||
->before($end);
|
||||
// filter some:
|
||||
if (\Input::get('type')) {
|
||||
switch (\Input::get('type')) {
|
||||
case 'transactions':
|
||||
$query->transactionTypes(['Deposit', 'Withdrawal']);
|
||||
break;
|
||||
case 'transfers':
|
||||
$query->transactionTypes(['Transfer']);
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('No case for type "' . \Input::get('type') . '"!');
|
||||
break;
|
||||
}
|
||||
switch (\Input::get('type')) {
|
||||
case 'transactions':
|
||||
$query->transactionTypes(['Deposit', 'Withdrawal']);
|
||||
break;
|
||||
case 'transfers':
|
||||
$query->transactionTypes(['Transfer']);
|
||||
break;
|
||||
}
|
||||
|
||||
if (\Input::get('show')) {
|
||||
switch (\Input::get('show')) {
|
||||
case 'expenses':
|
||||
case 'out':
|
||||
$query->lessThan(0);
|
||||
break;
|
||||
case 'income':
|
||||
case 'in':
|
||||
$query->moreThan(0);
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('No case for show "' . \Input::get('show') . '"!');
|
||||
break;
|
||||
}
|
||||
switch (\Input::get('show')) {
|
||||
case 'expenses':
|
||||
case 'out':
|
||||
$query->lessThan(0);
|
||||
break;
|
||||
case 'income':
|
||||
case 'in':
|
||||
$query->moreThan(0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,26 +88,11 @@ class Account implements AccountInterface
|
||||
foreach ($result as $index => $item) {
|
||||
|
||||
foreach ($item->components as $component) {
|
||||
if ($component->class == 'Budget') {
|
||||
$stats['budgets'][$component->id] = $component;
|
||||
}
|
||||
if ($component->class == 'Category') {
|
||||
$stats['categories'][$component->id] = $component;
|
||||
}
|
||||
$stats[$component->class][$component->id] = $component;
|
||||
}
|
||||
// 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, we remove $item and continue like nothing ever happened.
|
||||
|
||||
// this will however, mess up some statisics but we can live with that.
|
||||
// we might be needing some cleanup routine in the future.
|
||||
|
||||
// for now, we simply warn the user of this.
|
||||
|
||||
if (count($item->transactions) < 2) {
|
||||
\Session::flash('warning',
|
||||
'Some transactions are incomplete; they will not be shown. Statistics may differ.');
|
||||
\Session::flash('warning', 'Some transactions are incomplete; they will not be shown.');
|
||||
unset($result[$index]);
|
||||
continue;
|
||||
}
|
||||
@@ -138,7 +120,6 @@ class Account implements AccountInterface
|
||||
->transactionTypes(['Transfer'])->sum('transactions.amount'));
|
||||
$trfDiff = $trfIn + $trfOut;
|
||||
|
||||
|
||||
$stats['period'] = [
|
||||
'in' => $trIn,
|
||||
'out' => $trOut,
|
||||
@@ -155,7 +136,5 @@ class Account implements AccountInterface
|
||||
];
|
||||
|
||||
return $return;
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -13,6 +13,11 @@ class Budget implements BudgetInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* First, loop all budgets, all of their limits and all repetitions to get an overview per period
|
||||
* and some basic information about that repetition's data.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param Collection $budgets
|
||||
*
|
||||
* @return mixed|void
|
||||
@@ -21,32 +26,30 @@ class Budget implements BudgetInterface
|
||||
{
|
||||
$return = [];
|
||||
|
||||
/** @var \Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
|
||||
/** @var \Limit $limit */
|
||||
foreach ($budget->limits as $limit) {
|
||||
|
||||
/** @var \LimitRepetition $rep */
|
||||
foreach ($limit->limitrepetitions as $rep) {
|
||||
$periodOrder = $rep->periodOrder();
|
||||
$period = $rep->periodShow();
|
||||
$return[$periodOrder] = isset($return[$periodOrder])
|
||||
? $return[$periodOrder]
|
||||
: ['date' => $period,
|
||||
'dateObject' => $rep->startdate,
|
||||
'start' => $rep->startdate,
|
||||
'end' => $rep->enddate,
|
||||
'budget_id' => $limit->budget_id];
|
||||
/** @var \LimitRepetition $repetition */
|
||||
foreach ($limit->limitrepetitions as $repetition) {
|
||||
$repetition->left = $repetition->left();
|
||||
$periodOrder = $repetition->periodOrder();
|
||||
$period = $repetition->periodShow();
|
||||
if (!isset($return[$periodOrder])) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// put all the budgets under their respective date:
|
||||
foreach ($budgets as $budget) {
|
||||
foreach ($budget->limits as $limit) {
|
||||
foreach ($limit->limitrepetitions as $rep) {
|
||||
$rep->left = $rep->left();
|
||||
$return[$periodOrder] = [
|
||||
'date' => $period,
|
||||
'start' => $repetition->startdate,
|
||||
'end' => $repetition->enddate,
|
||||
'budget_id' => $budget->id,
|
||||
'limitrepetitions' => [$repetition]
|
||||
];
|
||||
} else {
|
||||
$return[$periodOrder]['limitrepetitions'][] = $repetition;
|
||||
}
|
||||
|
||||
$month = $rep->periodOrder();
|
||||
$return[$month]['limitrepetitions'][] = $rep;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,30 +59,24 @@ class Budget implements BudgetInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a repetition (complex because of user check)
|
||||
* and then get the transactions in it.
|
||||
* @param $repetitionId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function organizeRepetition($repetitionId)
|
||||
public function organizeRepetition(\LimitRepetition $repetition)
|
||||
{
|
||||
$result = [];
|
||||
$repetition = \LimitRepetition::with('limit', 'limit.budget')->leftJoin(
|
||||
'limits', 'limit_repetitions.limit_id', '=', 'limits.id'
|
||||
)->leftJoin('components', 'limits.component_id', '=', 'components.id')->where(
|
||||
'components.user_id', \Auth::user()->id
|
||||
)
|
||||
->where('limit_repetitions.id', $repetitionId)->first(['limit_repetitions.*']);
|
||||
|
||||
// get transactions:
|
||||
$set = $repetition->limit->budget->transactionjournals()->with(
|
||||
'transactions', 'transactions.account', 'components', 'transactiontype'
|
||||
)->leftJoin(
|
||||
'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id'
|
||||
)->where('transaction_types.type', 'Withdrawal')->where(
|
||||
'date', '>=', $repetition->startdate->format('Y-m-d')
|
||||
)->where('date', '<=', $repetition->enddate->format('Y-m-d'))->orderBy('date', 'DESC')->orderBy(
|
||||
'id', 'DESC'
|
||||
)->get(['transaction_journals.*']);
|
||||
$set = $repetition->limit->budget
|
||||
->transactionjournals()
|
||||
->withRelevantData()
|
||||
->transactionTypes(['Withdrawal'])
|
||||
->after($repetition->startdate)
|
||||
->before($repetition->enddate)
|
||||
->defaultSorting()
|
||||
->get(['transaction_journals.*']);
|
||||
|
||||
$result[0] = [
|
||||
'date' => $repetition->periodShow(),
|
||||
@@ -93,8 +90,10 @@ class Budget implements BudgetInterface
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param \Budget $budget
|
||||
* @param bool $useSessionDates
|
||||
* @param bool $useSessionDates
|
||||
*
|
||||
* @return array|mixed
|
||||
* @throws \Firefly\Exception\FireflyException
|
||||
@@ -102,15 +101,15 @@ class Budget implements BudgetInterface
|
||||
public function organizeRepetitions(\Budget $budget, $useSessionDates = false)
|
||||
{
|
||||
$sessionStart = \Session::get('start');
|
||||
$sessionEnd = \Session::get('end');
|
||||
$sessionEnd = \Session::get('end');
|
||||
|
||||
$result = [];
|
||||
$result = [];
|
||||
$inRepetition = [];
|
||||
|
||||
// get the limits:
|
||||
if ($useSessionDates) {
|
||||
$limits = $budget->limits()->where('startdate', '>=', $sessionStart->format('Y-m-d'))->where(
|
||||
'startdate', '<=', $sessionEnd->format('Y-m-d')
|
||||
'startdate', '<=', $sessionEnd->format('Y-m-d')
|
||||
)->get();
|
||||
} else {
|
||||
$limits = $budget->limits;
|
||||
@@ -119,7 +118,7 @@ class Budget implements BudgetInterface
|
||||
/** @var \Limit $limit */
|
||||
foreach ($limits as $limit) {
|
||||
foreach ($limit->limitrepetitions as $repetition) {
|
||||
$order = $repetition->periodOrder();
|
||||
$order = $repetition->periodOrder();
|
||||
$result[$order] = [
|
||||
'date' => $repetition->periodShow(),
|
||||
'limitrepetition' => $repetition,
|
||||
@@ -127,16 +126,14 @@ class Budget implements BudgetInterface
|
||||
'journals' => [],
|
||||
'paginated' => false
|
||||
];
|
||||
$transactions = [];
|
||||
$set = $budget->transactionjournals()->with(
|
||||
'transactions', 'transactions.account', 'components', 'transactiontype'
|
||||
)->leftJoin(
|
||||
'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id'
|
||||
)->where('transaction_types.type', 'Withdrawal')->where(
|
||||
'date', '>=', $repetition->startdate->format('Y-m-d')
|
||||
)->where('date', '<=', $repetition->enddate->format('Y-m-d'))->orderBy('date', 'DESC')->orderBy(
|
||||
'id', 'DESC'
|
||||
)->get(['transaction_journals.*']);
|
||||
$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;
|
||||
@@ -146,30 +143,17 @@ class Budget implements BudgetInterface
|
||||
|
||||
}
|
||||
if ($useSessionDates === false) {
|
||||
$query = $budget->transactionjournals()->withRelevantData()->defaultSorting();
|
||||
if (count($inRepetition) > 0) {
|
||||
$query = $budget->transactionjournals()->with(
|
||||
'transactions', 'transactions.account', 'components', 'transactiontype',
|
||||
'transactions.account.accounttype'
|
||||
)->whereNotIn(
|
||||
'transaction_journals.id', $inRepetition
|
||||
)->orderBy('date', 'DESC')->orderBy(
|
||||
'transaction_journals.id', 'DESC'
|
||||
);
|
||||
} else {
|
||||
$query = $budget->transactionjournals()->with(
|
||||
'transactions', 'transactions.account', 'components', 'transactiontype',
|
||||
'transactions.account.accounttype'
|
||||
)->orderBy('date', 'DESC')->orderBy(
|
||||
'transaction_journals.id', 'DESC'
|
||||
);
|
||||
$query->whereNotIn('transaction_journals.id', $inRepetition);
|
||||
}
|
||||
|
||||
// build paginator:
|
||||
$perPage = 25;
|
||||
$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();
|
||||
$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 = [];
|
||||
@@ -177,9 +161,12 @@ class Budget implements BudgetInterface
|
||||
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];
|
||||
$paginator = \Paginator::make($items, $totalItems, $perPage);
|
||||
$result['0000'] = [
|
||||
'date' => 'Not in an envelope',
|
||||
'limit' => null,
|
||||
'paginated' => true,
|
||||
'journals' => $paginator];
|
||||
}
|
||||
krsort($result);
|
||||
|
||||
@@ -196,13 +183,12 @@ class Budget implements BudgetInterface
|
||||
$inRepetitions = [];
|
||||
foreach ($budget->limits as $limit) {
|
||||
foreach ($limit->limitrepetitions as $repetition) {
|
||||
$set = $budget->transactionjournals()->leftJoin(
|
||||
'transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id'
|
||||
)->where('transaction_types.type', 'Withdrawal')->where(
|
||||
'date', '>=', $repetition->startdate->format('Y-m-d')
|
||||
)->where('date', '<=', $repetition->enddate->format('Y-m-d'))->orderBy('date', 'DESC')->get(
|
||||
['transaction_journals.id']
|
||||
);
|
||||
$set = $budget->transactionjournals()
|
||||
->transactionTypes(['Withdrawal'])
|
||||
->after($repetition->startdate)
|
||||
->before($repetition->enddate)
|
||||
->defaultSorting()
|
||||
->get(['transaction_journals.id']);
|
||||
foreach ($set as $item) {
|
||||
$inRepetitions[] = $item->id;
|
||||
}
|
||||
@@ -210,21 +196,17 @@ class Budget implements BudgetInterface
|
||||
|
||||
}
|
||||
|
||||
$query = $budget->transactionjournals()->with(
|
||||
'transactions', 'transactions.account', 'components', 'transactiontype',
|
||||
'transactions.account.accounttype'
|
||||
)->whereNotIn(
|
||||
'transaction_journals.id', $inRepetitions
|
||||
)->orderBy('date', 'DESC')->orderBy(
|
||||
'transaction_journals.id', 'DESC'
|
||||
);
|
||||
$query = $budget->transactionjournals()
|
||||
->withRelevantData()
|
||||
->whereNotIn('transaction_journals.id', $inRepetitions)
|
||||
->defaultSorting();
|
||||
|
||||
// build paginator:
|
||||
$perPage = 25;
|
||||
$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();
|
||||
$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 = [];
|
||||
@@ -233,8 +215,12 @@ class Budget implements BudgetInterface
|
||||
$items[] = $item;
|
||||
}
|
||||
$paginator = \Paginator::make($items, $totalItems, $perPage);
|
||||
$result = [0 => ['date' => 'Not in an envelope', 'limit' => null, 'paginated' => true,
|
||||
'journals' => $paginator]];
|
||||
$result = [0 => [
|
||||
'date' => 'Not in an envelope',
|
||||
'limit' => null,
|
||||
'paginated' => true,
|
||||
'journals' => $paginator
|
||||
]];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ interface BudgetInterface
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function organizeRepetition($repetitionId);
|
||||
public function organizeRepetition(\LimitRepetition $repetition);
|
||||
|
||||
|
||||
/**
|
||||
|
@@ -4,6 +4,7 @@ namespace Firefly\Helper\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Firefly\Exception\FireflyException;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class Chart
|
||||
@@ -23,8 +24,8 @@ class Chart implements ChartInterface
|
||||
public function account(\Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
$current = clone $start;
|
||||
$today = new Carbon;
|
||||
$return = ['name' => $account->name, 'id' => $account->id, 'data' => []];
|
||||
$today = new Carbon;
|
||||
$return = ['name' => $account->name, 'id' => $account->id, 'data' => []];
|
||||
|
||||
while ($current <= $end) {
|
||||
if ($current > $today) {
|
||||
@@ -106,7 +107,7 @@ class Chart implements ChartInterface
|
||||
|
||||
$data = [];
|
||||
|
||||
$budgets = \Auth::user()->budgets()->with(
|
||||
$budgets = \Auth::user()->budgets()->with(
|
||||
['limits' => function ($q) {
|
||||
$q->orderBy('limits.startdate', 'ASC');
|
||||
}, 'limits.limitrepetitions' => function ($q) use ($start) {
|
||||
@@ -117,6 +118,7 @@ class Chart implements ChartInterface
|
||||
$limitInPeriod = '';
|
||||
$spentInPeriod = '';
|
||||
|
||||
/** @var \Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
$budget->count = 0;
|
||||
foreach ($budget->limits as $limit) {
|
||||
@@ -129,21 +131,38 @@ class Chart implements ChartInterface
|
||||
$rep->left = $rep->left();
|
||||
// overspent:
|
||||
if ($rep->left < 0) {
|
||||
$rep->spent = ($rep->left * -1) + $rep->amount;
|
||||
$rep->overspent = $rep->left * -1;
|
||||
$total = $rep->spent + $rep->overspent;
|
||||
$rep->spent_pct = round(($rep->spent / $total) * 100);
|
||||
$rep->spent = ($rep->left * -1) + $rep->amount;
|
||||
$rep->overspent = $rep->left * -1;
|
||||
$total = $rep->spent + $rep->overspent;
|
||||
$rep->spent_pct = round(($rep->spent / $total) * 100);
|
||||
$rep->overspent_pct = 100 - $rep->spent_pct;
|
||||
} else {
|
||||
$rep->spent = $rep->amount - $rep->left;
|
||||
$rep->spent = $rep->amount - $rep->left;
|
||||
$rep->spent_pct = round(($rep->spent / $rep->amount) * 100);
|
||||
$rep->left_pct = 100 - $rep->spent_pct;
|
||||
$rep->left_pct = 100 - $rep->spent_pct;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
$budget->count += count($limit->limitrepetitions);
|
||||
}
|
||||
if ($budget->count == 0) {
|
||||
// get expenses in period until today, starting at $start.
|
||||
$end = \Session::get('end');
|
||||
$expenses = $budget->transactionjournals()->after($start)->before($end)
|
||||
->transactionTypes(
|
||||
['Withdrawal']
|
||||
)->get();
|
||||
$budget->spentInPeriod = 0;
|
||||
/** @var \TransactionJournal $expense */
|
||||
foreach ($expenses as $expense) {
|
||||
$transaction = $expense->transactions[1];
|
||||
if (!is_null($transaction)) {
|
||||
$budget->spentInPeriod += floatval($transaction->amount);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -161,16 +180,25 @@ class Chart implements ChartInterface
|
||||
|
||||
foreach ($budgets as $budget) {
|
||||
if ($budget->count > 0) {
|
||||
$data['labels'][] = wordwrap($budget->name, 12, "<br>");
|
||||
}
|
||||
foreach ($budget->limits as $limit) {
|
||||
foreach ($limit->limitrepetitions as $rep) {
|
||||
//0: envelope for period:
|
||||
$amount = floatval($rep->amount);
|
||||
$spent = $rep->spent;
|
||||
$color = $spent > $amount ? '#FF0000' : null;
|
||||
$data['series'][0]['data'][] = ['y' => $amount, 'id' => 'amount-' . $rep->id];
|
||||
$data['series'][1]['data'][] = ['y' => $rep->spent, 'color' => $color, 'id' => 'spent-' . $rep->id];
|
||||
$data['labels'][] = $budget->name;
|
||||
foreach ($budget->limits as $limit) {
|
||||
foreach ($limit->limitrepetitions as $rep) {
|
||||
//0: envelope for period:
|
||||
$amount = floatval($rep->amount);
|
||||
$spent = $rep->spent;
|
||||
$color = $spent > $amount ? '#FF0000' : null;
|
||||
$data['series'][0]['data'][] = ['y' => $amount, 'id' => 'amount-' . $rep->id];
|
||||
$data['series'][1]['data'][] = ['y' => $rep->spent, 'color' => $color,
|
||||
'id' => 'spent-' . $rep->id];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// add for "empty" budget:
|
||||
if ($budget->spentInPeriod > 0) {
|
||||
$data['labels'][] = $budget->name;
|
||||
$data['series'][0]['data'][] = ['y' => null, 'id' => 'amount-norep-' . $budget->id];
|
||||
$data['series'][1]['data'][] = ['y' => $budget->spentInPeriod,
|
||||
'id' => 'spent-norep-' . $budget->id];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,10 +239,10 @@ class Chart implements ChartInterface
|
||||
. ' transactions!');
|
||||
}
|
||||
$transaction = $journal->transactions[0];
|
||||
$amount = floatval($transaction->amount);
|
||||
$amount = floatval($transaction->amount);
|
||||
|
||||
// get budget from journal:
|
||||
$category = $journal->categories()->first();
|
||||
$category = $journal->categories()->first();
|
||||
$categoryName = is_null($category) ? '(no category)' : $category->name;
|
||||
|
||||
$result[$categoryName] = isset($result[$categoryName]) ? $result[$categoryName] + floatval($amount)
|
||||
@@ -335,7 +363,7 @@ class Chart implements ChartInterface
|
||||
|
||||
|
||||
// get sum for current range:
|
||||
$journals = \TransactionJournal::
|
||||
$journals = \TransactionJournal::
|
||||
with(
|
||||
['transactions' => function ($q) {
|
||||
$q->where('amount', '>', 0);
|
||||
@@ -360,7 +388,7 @@ class Chart implements ChartInterface
|
||||
. ' transactions!');
|
||||
}
|
||||
$transaction = $journal->transactions[0];
|
||||
$amount = floatval($transaction->amount);
|
||||
$amount = floatval($transaction->amount);
|
||||
$currentSum += $amount;
|
||||
|
||||
}
|
||||
@@ -401,4 +429,150 @@ class Chart implements ChartInterface
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* We check how much money has been spend on the limitrepetition (aka: the current envelope) in the period denoted.
|
||||
* Aka, we have a certain amount of money in an envelope and we wish to know how much we've spent between the dates
|
||||
* entered. This 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')) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@@ -54,4 +54,61 @@ interface ChartInterface
|
||||
* @return mixed
|
||||
*/
|
||||
public function categoryShowChart(\Category $category, $range, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return float|null
|
||||
*/
|
||||
public function spentOnDay(\Budget $budget, Carbon $date);
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function allJournalsInBudgetEnvelope(\Budget $budget);
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
* @param array $ids
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function journalsNotInSet(\Budget $budget, array $ids);
|
||||
|
||||
/**
|
||||
* @param array $set
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function transactionsByJournals(array $set);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
|
||||
/**
|
||||
* We check how much money has been spend on the limitrepetition (aka: the current envelope) in the period denoted.
|
||||
* Aka, we have a certain amount of money in an envelope and we wish to know how much we've spent between the dates
|
||||
* entered. This 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);
|
||||
|
||||
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Helper\Form;
|
||||
|
||||
/**
|
||||
* Class FormHelper
|
||||
*
|
||||
* @package Firefly\Form
|
||||
*/
|
||||
class FormHelper
|
||||
{
|
||||
|
||||
/**
|
||||
* @param null $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function budget($value = null)
|
||||
{
|
||||
|
||||
$str = '<select name="budget_id" class="form-control">';
|
||||
|
||||
$str .= '<option value="0" label="(no budget)"';
|
||||
if (is_null($value) || intval($value) == 0) {
|
||||
$str .= ' selected="selected"';
|
||||
}
|
||||
$str .= '</option>';
|
||||
|
||||
/** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budgets */
|
||||
$budgets = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
||||
$list = $budgets->getAsSelectList();
|
||||
foreach ($list as $id => $name) {
|
||||
$str .= '<option value="' . e($id) . '" label="' . e($name) . '"';
|
||||
if ($id == intval($value)) {
|
||||
$str .= ' selected="selected"';
|
||||
}
|
||||
$str .= '>' . e($name) . '</option>';
|
||||
}
|
||||
|
||||
|
||||
$str .= '</select>';
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Helper\Form;
|
||||
|
||||
use Illuminate\Events\Dispatcher;
|
||||
|
||||
/**
|
||||
* Class FormTrigger
|
||||
*
|
||||
* @package Firefly\Helper\Form
|
||||
*/
|
||||
class FormTrigger
|
||||
{
|
||||
|
||||
public function registerFormExtensions()
|
||||
{
|
||||
\Form::macro(
|
||||
'budget', function () {
|
||||
$helper = new FormHelper;
|
||||
|
||||
return $helper->budget();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Dispatcher $events
|
||||
*/
|
||||
public function subscribe(Dispatcher $events)
|
||||
{
|
||||
$events->listen('laravel.booted', 'Firefly\Helper\Form\FormTrigger@registerFormExtensions');
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,327 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Helper\Migration;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Firefly\Exception\FireflyException;
|
||||
|
||||
/**
|
||||
* Class MigrationHelper
|
||||
*
|
||||
* @package Firefly\Helper\Migration
|
||||
*/
|
||||
class MigrationHelper implements MigrationHelperInterface
|
||||
{
|
||||
protected $path;
|
||||
protected $JSON;
|
||||
protected $map = [];
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function loadFile($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function validFile()
|
||||
{
|
||||
// file does not exist:
|
||||
if (!file_exists($this->path)) {
|
||||
\Log::error('Migration file ' . $this->path . ' does not exist!');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// load the content:
|
||||
$content = file_get_contents($this->path);
|
||||
if ($content === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse the content
|
||||
$this->JSON = json_decode($content);
|
||||
if (is_null($this->JSON)) {
|
||||
return false;
|
||||
}
|
||||
\Log::info('Migration file ' . $this->path . ' is valid!');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function migrate()
|
||||
{
|
||||
\Log::info('Start of migration.');
|
||||
\DB::beginTransaction();
|
||||
|
||||
try {
|
||||
// create cash account:
|
||||
$this->_createCashAccount();
|
||||
|
||||
$this->_importAccounts();
|
||||
$this->_importComponents();
|
||||
//$this->_importPiggybanks();
|
||||
|
||||
// create transactions:
|
||||
$this->_importTransactions();
|
||||
|
||||
// create transfers:
|
||||
$this->_importTransfers();
|
||||
|
||||
// create limits:
|
||||
$this->_importLimits();
|
||||
|
||||
|
||||
} catch (FireflyException $e) {
|
||||
\DB::rollBack();
|
||||
\Log::error('Rollback because of error!');
|
||||
\Log::error($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
\DB::commit();
|
||||
\Log::info('Done!');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function _createCashAccount()
|
||||
{
|
||||
$cashAT = \AccountType::where('description', 'Cash account')->first();
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$cash = $accounts->store(['name' => 'Cash account', 'account_type' => $cashAT, 'active' => 0]);
|
||||
\Log::info('Created cash account (#' . $cash->id . ')');
|
||||
$this->map['cash'] = $cash;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function _importAccounts()
|
||||
{
|
||||
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
\Log::info('Going to import ' . count($this->JSON->accounts) . ' accounts.');
|
||||
foreach ($this->JSON->accounts as $entry) {
|
||||
// create account:
|
||||
if ($entry->openingbalance == 0) {
|
||||
$account = $accounts->store(['name' => $entry->name]);
|
||||
} else {
|
||||
$account = $accounts->storeWithInitialBalance(
|
||||
['name' => $entry->name],
|
||||
new Carbon($entry->openingbalancedate),
|
||||
floatval($entry->openingbalance)
|
||||
);
|
||||
}
|
||||
$this->map['accounts'][$entry->id] = $account;
|
||||
\Log::info('Imported account "' . $entry->name . '" with balance ' . $entry->openingbalance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function _importComponents()
|
||||
{
|
||||
$beneficiaryAT = \AccountType::where('description', 'Beneficiary account')->first();
|
||||
foreach ($this->JSON->components as $entry) {
|
||||
switch ($entry->type->type) {
|
||||
case 'beneficiary':
|
||||
/** @noinspection PhpParamsInspection */
|
||||
$beneficiary = $this->_importBeneficiary($entry, $beneficiaryAT);
|
||||
$this->map['accounts'][$entry->id] = $beneficiary;
|
||||
break;
|
||||
case 'category':
|
||||
$component = $this->_importCategory($entry);
|
||||
$this->map['categories'][$entry->id] = $component;
|
||||
break;
|
||||
case 'budget':
|
||||
$component = $this->_importBudget($entry);
|
||||
$this->map['budgets'][$entry->id] = $component;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $component
|
||||
* @param \AccountType $beneficiaryAT
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _importBeneficiary($component, \AccountType $beneficiaryAT)
|
||||
{
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
|
||||
return $accounts->store(
|
||||
[
|
||||
'name' => $component->name,
|
||||
'account_type' => $beneficiaryAT
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $component
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _importCategory($component)
|
||||
{
|
||||
/** @var \Firefly\Storage\Component\ComponentRepositoryInterface $components */
|
||||
$components = \App::make('Firefly\Storage\Component\ComponentRepositoryInterface');
|
||||
|
||||
return $components->store(['name' => $component->name, 'class' => 'Category']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $component
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _importBudget($component)
|
||||
{
|
||||
/** @var \Firefly\Storage\Component\ComponentRepositoryInterface $components */
|
||||
$components = \App::make('Firefly\Storage\Component\ComponentRepositoryInterface');
|
||||
|
||||
return $components->store(['name' => $component->name, 'class' => 'Budget']);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function _importTransactions()
|
||||
{
|
||||
|
||||
/** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */
|
||||
$journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||
|
||||
// loop component_transaction to find beneficiaries, categories and budgets:
|
||||
$beneficiaries = [];
|
||||
$categories = [];
|
||||
$budgets = [];
|
||||
foreach ($this->JSON->component_transaction as $entry) {
|
||||
// beneficiaries
|
||||
if (isset($this->map['accounts'][$entry->component_id])) {
|
||||
$beneficiaries[$entry->transaction_id] = $this->map['accounts'][$entry->component_id];
|
||||
}
|
||||
|
||||
// categories
|
||||
if (isset($this->map['categories'][$entry->component_id])) {
|
||||
$categories[$entry->transaction_id] = $this->map['categories'][$entry->component_id];
|
||||
}
|
||||
|
||||
// budgets:
|
||||
if (isset($this->map['budgets'][$entry->component_id])) {
|
||||
$budgets[$entry->transaction_id] = $this->map['budgets'][$entry->component_id];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->JSON->transactions as $entry) {
|
||||
|
||||
// to properly save the amount, do it times -1:
|
||||
$amount = $entry->amount * -1;
|
||||
|
||||
/** @var \Account $fromAccount */
|
||||
$fromAccount = isset($this->map['accounts'][$entry->account_id])
|
||||
? $this->map['accounts'][$entry->account_id] : false;
|
||||
|
||||
/** @var \Account $toAccount */
|
||||
$toAccount = isset($beneficiaries[$entry->id]) ? $beneficiaries[$entry->id] : $this->map['cash'];
|
||||
|
||||
$date = new Carbon($entry->date);
|
||||
$journal = $journals->createSimpleJournal($fromAccount, $toAccount, $entry->description, $amount, $date);
|
||||
|
||||
// save budgets and categories, on the journal
|
||||
if (isset($budgets[$entry->id])) {
|
||||
$budget = $budgets[$entry->id];
|
||||
$journal->budgets()->save($budget);
|
||||
}
|
||||
if (isset($categories[$entry->id])) {
|
||||
$category = $categories[$entry->id];
|
||||
$journal->categories()->save($category);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function _importTransfers()
|
||||
{
|
||||
/** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */
|
||||
$journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||
|
||||
foreach ($this->JSON->transfers as $entry) {
|
||||
|
||||
// to properly save the amount, do it times 1 (?):
|
||||
$amount = $entry->amount * -1;
|
||||
|
||||
/** @var \Account $fromAccount */
|
||||
$fromAccount = isset($this->map['accounts'][$entry->accountfrom_id])
|
||||
? $this->map['accounts'][$entry->accountto_id] : false;
|
||||
|
||||
/** @var \Account $toAccount */
|
||||
$toAccount = isset($this->map['accounts'][$entry->accountto_id])
|
||||
? $this->map['accounts'][$entry->accountfrom_id] : false;
|
||||
|
||||
$date = new Carbon($entry->date);
|
||||
$journals->createSimpleJournal($fromAccount, $toAccount, $entry->description, $amount, $date);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function _importLimits()
|
||||
{
|
||||
\Log::info('Importing limits');
|
||||
foreach ($this->JSON->limits as $entry) {
|
||||
\Log::debug(
|
||||
'Now at #' . $entry->id . ': EUR ' . $entry->amount . ' for month ' . $entry->date
|
||||
. ' and componentID: ' . $entry->component_id
|
||||
);
|
||||
$budget = isset($this->map['budgets'][$entry->component_id]) ? $this->map['budgets'][$entry->component_id]
|
||||
: null;
|
||||
if (!is_null($budget)) {
|
||||
\Log::debug('Found budget for this limit: #' . $budget->id . ', ' . $budget->name);
|
||||
|
||||
$limit = new \Limit;
|
||||
$limit->budget()->associate($budget);
|
||||
$limit->startdate = new Carbon($entry->date);
|
||||
$limit->amount = floatval($entry->amount);
|
||||
$limit->repeats = 0;
|
||||
$limit->repeat_freq = 'monthly';
|
||||
try {
|
||||
$limit->save();
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
} else {
|
||||
\Log::warning('No budget for this limit!');
|
||||
}
|
||||
|
||||
|
||||
// create repeat thing should not be necessary.
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Helper\Migration;
|
||||
|
||||
/**
|
||||
* Interface MigrationHelperInterface
|
||||
*
|
||||
* @package Firefly\Helper\Migration
|
||||
*/
|
||||
interface MigrationHelperInterface
|
||||
{
|
||||
/**
|
||||
* @param $path
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function loadFile($path);
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function validFile();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function migrate();
|
||||
|
||||
}
|
674
app/lib/Firefly/Queue/Import.php
Normal file
674
app/lib/Firefly/Queue/Import.php
Normal file
@@ -0,0 +1,674 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Queue;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Queue\Jobs\Job;
|
||||
|
||||
/**
|
||||
* Class Import
|
||||
*
|
||||
* @package Firefly\Queue
|
||||
*/
|
||||
class Import
|
||||
{
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface */
|
||||
protected $_accounts;
|
||||
|
||||
/** @var \Firefly\Storage\Import\ImportRepositoryInterface */
|
||||
protected $_repository;
|
||||
|
||||
/** @var \Firefly\Storage\Budget\BudgetRepositoryInterface */
|
||||
protected $_budgets;
|
||||
|
||||
/** @var \Firefly\Storage\Category\CategoryRepositoryInterface */
|
||||
protected $_categories;
|
||||
|
||||
/** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface */
|
||||
protected $_journals;
|
||||
|
||||
/** @var \Firefly\Storage\Limit\LimitRepositoryInterface */
|
||||
protected $_limits;
|
||||
|
||||
/** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface */
|
||||
protected $_piggybanks;
|
||||
|
||||
/** @var \Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface */
|
||||
protected $_recurring;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$this->_repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface');
|
||||
$this->_budgets = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
||||
$this->_categories = \App::make('Firefly\Storage\Category\CategoryRepositoryInterface');
|
||||
$this->_journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||
$this->_limits = \App::make('Firefly\Storage\Limit\LimitRepositoryInterface');
|
||||
$this->_piggybanks = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface');
|
||||
$this->_recurring = \App::make('Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface');
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function cleanImportAccount(Job $job, array $payload)
|
||||
{
|
||||
$importAccountType = $this->_accounts->findAccountType('Import account');
|
||||
$importAccounts = $this->_accounts->getByAccountType($importAccountType);
|
||||
if (count($importAccounts) == 0) {
|
||||
$job->delete();
|
||||
} else if (count($importAccounts) == 1) {
|
||||
/** @var \Account $importAccount */
|
||||
$importAccount = $importAccounts[0];
|
||||
$transactions = $importAccount->transactions()->get();
|
||||
/** @var \Transaction $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$transaction->account()->associate($importAccount);
|
||||
$transaction->save();
|
||||
}
|
||||
\Log::debug('Updated ' . count($transactions) . ' transactions from Import Account to cash.');
|
||||
}
|
||||
$job->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*
|
||||
* @throws \Firefly\Exception\FireflyException
|
||||
*/
|
||||
public function importComponent(Job $job, array $payload)
|
||||
{
|
||||
|
||||
\Log::debug('Going to import component "' . $payload['data']['name'] . '".');
|
||||
switch ($payload['data']['type']['type']) {
|
||||
case 'beneficiary':
|
||||
$payload['class'] = 'Account';
|
||||
$payload['data']['account_type'] = 'Beneficiary account';
|
||||
$this->importAccount($job, $payload);
|
||||
break;
|
||||
case 'budget':
|
||||
$this->importBudget($job, $payload);
|
||||
break;
|
||||
case 'category':
|
||||
$this->importCategory($job, $payload);
|
||||
break;
|
||||
case 'payer':
|
||||
$job->delete();
|
||||
break;
|
||||
default:
|
||||
$job->delete();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a personal account or beneficiary as a new account.
|
||||
*
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function importAccount(Job $job, array $payload)
|
||||
{
|
||||
|
||||
/** @var \Importmap $importMap */
|
||||
$importMap = $this->_repository->findImportmap($payload['mapID']);
|
||||
$user = $importMap->user;
|
||||
$this->overruleUser($user);
|
||||
|
||||
|
||||
// maybe we've already imported this account:
|
||||
$importEntry = $this->_repository->findImportEntry($importMap, 'Account', intval($payload['data']['id']));
|
||||
|
||||
// if so, delete job and return:
|
||||
if (!is_null($importEntry)) {
|
||||
$job->delete();
|
||||
return;
|
||||
}
|
||||
|
||||
// if we try to import a beneficiary, Firefly will "merge" already,
|
||||
// so we don't care:
|
||||
if (isset($payload['data']['account_type']) && $payload['data']['account_type'] == 'Beneficiary account') {
|
||||
// store beneficiary
|
||||
$acct = $this->_accounts->createOrFindBeneficiary($payload['data']['name']);
|
||||
\Log::debug('Imported ' . $payload['class'] . ' "' . $payload['data']['name'] . '".');
|
||||
$this->_repository->store($importMap, 'Account', $payload['data']['id'], $acct->id);
|
||||
$job->delete();
|
||||
return;
|
||||
}
|
||||
|
||||
// but we cannot merge accounts, so we need to search first:
|
||||
$acct = $this->_accounts->findByName($payload['data']['name']);
|
||||
if (is_null($acct)) {
|
||||
// store new one!
|
||||
$acct = $this->_accounts->store((array)$payload['data']);
|
||||
\Log::debug('Imported ' . $payload['class'] . ' "' . $payload['data']['name'] . '".');
|
||||
$this->_repository->store($importMap, 'Account', $payload['data']['id'], $acct->id);
|
||||
} else {
|
||||
// use previous one!
|
||||
\Log::debug('Already imported ' . $payload['class'] . ' "' . $payload['data']['name'] . '".');
|
||||
$this->_repository->store($importMap, 'Account', $payload['data']['id'], $acct->id);
|
||||
}
|
||||
|
||||
// and delete the job
|
||||
$job->delete();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
*/
|
||||
protected function overruleUser(\User $user)
|
||||
{
|
||||
$this->_accounts->overruleUser($user);
|
||||
$this->_budgets->overruleUser($user);
|
||||
$this->_categories->overruleUser($user);
|
||||
$this->_journals->overruleUser($user);
|
||||
$this->_limits->overruleUser($user);
|
||||
$this->_repository->overruleUser($user);
|
||||
$this->_piggybanks->overruleUser($user);
|
||||
$this->_recurring->overruleUser($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a budget into Firefly.
|
||||
*
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function importBudget(Job $job, array $payload)
|
||||
{
|
||||
/** @var \Importmap $importMap */
|
||||
$importMap = $this->_repository->findImportmap($payload['mapID']);
|
||||
$user = $importMap->user;
|
||||
$this->overruleUser($user);
|
||||
|
||||
// maybe we've already imported this budget:
|
||||
$bdg = $this->_budgets->findByName($payload['data']['name']);
|
||||
|
||||
if (is_null($bdg)) {
|
||||
// we have not!
|
||||
$bdg = $this->_budgets->store((array)$payload['data']);
|
||||
$this->_repository->store($importMap, 'Budget', $payload['data']['id'], $bdg->id);
|
||||
\Log::debug('Imported budget "' . $payload['data']['name'] . '".');
|
||||
} else {
|
||||
// we have!
|
||||
$this->_repository->store($importMap, 'Budget', $payload['data']['id'], $bdg->id);
|
||||
\Log::debug('Already had budget "' . $payload['data']['name'] . '".');
|
||||
}
|
||||
|
||||
// delete job.
|
||||
$job->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a category into Firefly.
|
||||
*
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function importCategory(Job $job, array $payload)
|
||||
{
|
||||
|
||||
/** @var \Importmap $importMap */
|
||||
$importMap = $this->_repository->findImportmap($payload['mapID']);
|
||||
$user = $importMap->user;
|
||||
$this->overruleUser($user);
|
||||
|
||||
// try to find budget:
|
||||
$current = $this->_categories->findByName($payload['data']['name']);
|
||||
if (is_null($current)) {
|
||||
$cat = $this->_categories->store((array)$payload['data']);
|
||||
$this->_repository->store($importMap, 'Category', $payload['data']['id'], $cat->id);
|
||||
\Log::debug('Imported category "' . $payload['data']['name'] . '".');
|
||||
} else {
|
||||
$this->_repository->store($importMap, 'Category', $payload['data']['id'], $current->id);
|
||||
\Log::debug('Already had category "' . $payload['data']['name'] . '".');
|
||||
}
|
||||
|
||||
$job->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function importComponentTransaction(Job $job, array $payload)
|
||||
{
|
||||
if ($job->attempts() > 1) {
|
||||
\Log::info('importComponentTransaction Job running for ' . $job->attempts() . 'th time!');
|
||||
}
|
||||
if ($job->attempts() > 30) {
|
||||
\Log::error('importComponentTransaction Job running for ' . $job->attempts() . 'th time, so KILL!');
|
||||
$job->delete();
|
||||
return;
|
||||
}
|
||||
|
||||
$oldComponentId = intval($payload['data']['component_id']);
|
||||
$oldTransactionId = intval($payload['data']['transaction_id']);
|
||||
|
||||
/** @var \Importmap $importMap */
|
||||
$importMap = $this->_repository->findImportmap($payload['mapID']);
|
||||
$user = $importMap->user;
|
||||
$this->overruleUser($user);
|
||||
|
||||
$oldTransactionMap = $this->_repository->findImportEntry($importMap, 'Transaction', $oldTransactionId);
|
||||
|
||||
// we don't know what the component is, so we need to search for it in a set
|
||||
// of possible types (Account / Beneficiary, Budget, Category)
|
||||
/** @var \Importentry $oldComponentMap */
|
||||
$oldComponentMap = $this->_repository->findImportComponentMap($importMap, $oldComponentId);
|
||||
|
||||
if (is_null($oldComponentMap)) {
|
||||
\Log::debug('importComponentTransaction Could not run this one, waiting for five minutes...');
|
||||
$job->release(300);
|
||||
return;
|
||||
}
|
||||
|
||||
$journal = $this->_journals->find($oldTransactionMap->new);
|
||||
\Log::debug('Going to update ' . $journal->description);
|
||||
|
||||
// find the cash account:
|
||||
|
||||
|
||||
switch ($oldComponentMap->class) {
|
||||
case 'Budget':
|
||||
// budget thing link:
|
||||
$budget = $this->_budgets->find($oldComponentMap->new);
|
||||
|
||||
\Log::debug('Updating transactions budget.');
|
||||
$journal->budgets()->save($budget);
|
||||
$journal->save();
|
||||
\Log::debug('Updated transactions budget.');
|
||||
|
||||
break;
|
||||
case 'Category':
|
||||
$category = $this->_categories->find($oldComponentMap->new);
|
||||
$journal = $this->_journals->find($oldTransactionMap->new);
|
||||
\Log::info('Updating transactions category (old id is #' . $oldComponentMap->old . ').');
|
||||
if (!is_null($category)) {
|
||||
$journal->categories()->save($category);
|
||||
$journal->save();
|
||||
\Log::info('Updated transactions category.');
|
||||
} else {
|
||||
\Log::error('No category mapping to old id #' . $oldComponentMap->old . ' found. Release for 5m!');
|
||||
$job->release(300);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'Account':
|
||||
\Log::info('Updating transactions Account.');
|
||||
$account = $this->_accounts->find($oldComponentMap->new);
|
||||
$journal = $this->_journals->find($oldTransactionMap->new);
|
||||
if (is_null($account)) {
|
||||
\Log::debug('Cash account is needed.');
|
||||
$account = $this->_accounts->getCashAccount();
|
||||
\Log::info($account);
|
||||
}
|
||||
|
||||
foreach ($journal->transactions as $transaction) {
|
||||
if ($transaction->account()->first()->account_type_id == 5) {
|
||||
$transaction->account()->associate($account);
|
||||
$transaction->save();
|
||||
\Log::debug(
|
||||
'Updated transactions (#' . $journal->id . '), #' . $transaction->id . '\'s Account.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
$job->delete();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function importLimit(Job $job, array $payload)
|
||||
{
|
||||
if ($job->attempts() > 30) {
|
||||
\Log::error('importLimit Job running for ' . $job->attempts() . 'th time, so KILL!');
|
||||
$job->delete();
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var \Importmap $importMap */
|
||||
$importMap = $this->_repository->findImportmap($payload['mapID']);
|
||||
$user = $importMap->user;
|
||||
$this->overruleUser($user);
|
||||
|
||||
|
||||
// find the budget this limit is part of:
|
||||
$importEntry = $this->_repository->findImportEntry(
|
||||
$importMap, 'Budget',
|
||||
intval($payload['data']['component_id'])
|
||||
);
|
||||
|
||||
// budget is not yet imported:
|
||||
if (is_null($importEntry)) {
|
||||
\Log::debug(
|
||||
'importLimit Cannot import limit #' . $payload['data']['id'] .
|
||||
' because the budget is not here yet. #' . $job->attempts()
|
||||
);
|
||||
$job->release(300);
|
||||
return;
|
||||
}
|
||||
// find similar limit:
|
||||
\Log::debug('Trying to find budget with ID #' . $importEntry->new . ', based on entry #' . $importEntry->id);
|
||||
$budget = $this->_budgets->find($importEntry->new);
|
||||
if (!is_null($budget)) {
|
||||
$current = $this->_limits->findByBudgetAndDate($budget, new Carbon($payload['data']['date']));
|
||||
if (is_null($current)) {
|
||||
// create it!
|
||||
$payload['data']['budget_id'] = $budget->id;
|
||||
$payload['data']['startdate'] = $payload['data']['date'];
|
||||
$payload['data']['period'] = 'monthly';
|
||||
$lim = $this->_limits->store((array)$payload['data']);
|
||||
$this->_repository->store($importMap, 'Limit', $payload['data']['id'], $lim->id);
|
||||
\Event::fire('limits.store', [$lim]);
|
||||
\Log::debug('Imported ' . $payload['class'] . ', for ' . $budget->name . ' (' . $lim->startdate . ').');
|
||||
} else {
|
||||
// already has!
|
||||
$this->_repository->store($importMap, 'Budget', $payload['data']['id'], $current->id);
|
||||
\Log::debug(
|
||||
'Already had ' . $payload['class'] . ', for ' . $budget->name . ' (' . $current->startdate . ').'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// cannot import component limit, no longer supported.
|
||||
\Log::error('Cannot import limit for other than budget!');
|
||||
}
|
||||
$job->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function importPiggybank(Job $job, array $payload)
|
||||
{
|
||||
/** @var \Importmap $importMap */
|
||||
$importMap = $this->_repository->findImportmap($payload['mapID']);
|
||||
$user = $importMap->user;
|
||||
$this->overruleUser($user);
|
||||
|
||||
// try to find related piggybank:
|
||||
$current = $this->_piggybanks->findByName($payload['data']['name']);
|
||||
|
||||
// we need an account to go with this piggy bank:
|
||||
$set = $this->_accounts->getActiveDefault();
|
||||
if (count($set) > 0) {
|
||||
$account = $set[0];
|
||||
$payload['data']['account_id'] = $account->id;
|
||||
} else {
|
||||
\Log::debug('Released job for work in five minutes...');
|
||||
$job->release(300);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($current)) {
|
||||
$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;
|
||||
$piggy = $this->_piggybanks->store((array)$payload['data']);
|
||||
$this->_repository->store($importMap, 'Piggybank', $payload['data']['id'], $piggy->id);
|
||||
\Log::debug('Imported ' . $payload['class'] . ' "' . $payload['data']['name'] . '".');
|
||||
\Event::fire('piggybanks.store', [$piggy]);
|
||||
} else {
|
||||
$this->_repository->store($importMap, 'Piggybank', $payload['data']['id'], $current->id);
|
||||
\Log::debug('Already had ' . $payload['class'] . ' "' . $payload['data']['name'] . '".');
|
||||
}
|
||||
$job->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function importPredictable(Job $job, array $payload)
|
||||
{
|
||||
/** @var \Importmap $importMap */
|
||||
$importMap = $this->_repository->findImportmap($payload['mapID']);
|
||||
$user = $importMap->user;
|
||||
$this->overruleUser($user);
|
||||
|
||||
|
||||
// try to find related recurring transaction:
|
||||
$current = $this->_recurring->findByName($payload['data']['description']);
|
||||
if (is_null($current)) {
|
||||
|
||||
$payload['data']['name'] = $payload['data']['description'];
|
||||
$payload['data']['match'] = join(',', explode(' ', $payload['data']['description']));
|
||||
$pct = intval($payload['data']['pct']);
|
||||
$payload['data']['amount_min'] = floatval($payload['data']['amount']) * ($pct / 100) * -1;
|
||||
$payload['data']['amount_max'] = floatval($payload['data']['amount']) * (1 + ($pct / 100)) * -1;
|
||||
$payload['data']['date'] = date('Y-m-') . $payload['data']['dom'];
|
||||
$payload['data']['repeat_freq'] = 'monthly';
|
||||
$payload['data']['active'] = intval($payload['data']['inactive']) == 1 ? 0 : 1;
|
||||
$payload['data']['automatch'] = 1;
|
||||
|
||||
$recur = $this->_recurring->store((array)$payload['data']);
|
||||
|
||||
$this->_repository->store($importMap, 'RecurringTransaction', $payload['data']['id'], $recur->id);
|
||||
\Log::debug('Imported ' . $payload['class'] . ' "' . $payload['data']['name'] . '".');
|
||||
} else {
|
||||
$this->_repository->store($importMap, 'RecurringTransaction', $payload['data']['id'], $current->id);
|
||||
\Log::debug('Already had ' . $payload['class'] . ' "' . $payload['data']['description'] . '".');
|
||||
}
|
||||
$job->delete();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function importSetting(Job $job, array $payload)
|
||||
{
|
||||
switch ($payload['data']['name']) {
|
||||
default:
|
||||
$job->delete();
|
||||
return;
|
||||
break;
|
||||
case 'piggyAccount':
|
||||
// if we have this account, update all piggy banks:
|
||||
$accountID = intval($payload['data']['value']);
|
||||
|
||||
/** @var \Importmap $importMap */
|
||||
$importMap = $this->_repository->findImportmap($payload['mapID']);
|
||||
$user = $importMap->user;
|
||||
$this->overruleUser($user);
|
||||
|
||||
|
||||
$importEntry = $this->_repository->findImportEntry($importMap, 'Account', $accountID);
|
||||
if ($importEntry) {
|
||||
|
||||
$all = $this->_piggybanks->get();
|
||||
$account = $this->_accounts->find($importEntry->new);
|
||||
|
||||
\Log::debug('Updating all piggybanks, found the right setting.');
|
||||
foreach ($all as $piggy) {
|
||||
$piggy->account()->associate($account);
|
||||
unset($piggy->leftInAccount); //??
|
||||
$piggy->save();
|
||||
}
|
||||
} else {
|
||||
\Log::debug('importSetting wait five minutes and try again...');
|
||||
$job->release(300);
|
||||
}
|
||||
break;
|
||||
}
|
||||
$job->delete();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function importTransaction(Job $job, array $payload)
|
||||
{
|
||||
|
||||
/** @var \Importmap $importMap */
|
||||
$importMap = $this->_repository->findImportmap($payload['mapID']);
|
||||
$user = $importMap->user;
|
||||
$this->overruleUser($user);
|
||||
|
||||
// find or create the account type for the import account.
|
||||
// find or create the account for the import account.
|
||||
$accountType = $this->_accounts->findAccountType('Import account');
|
||||
$importAccount = $this->_accounts->createOrFind('Import account', $accountType);
|
||||
|
||||
|
||||
// if amount is more than zero, move from $importAccount
|
||||
$amount = floatval($payload['data']['amount']);
|
||||
|
||||
$accountEntry = $this->_repository->findImportEntry(
|
||||
$importMap, 'Account',
|
||||
intval($payload['data']['account_id'])
|
||||
);
|
||||
$personalAccount = $this->_accounts->find($accountEntry->new);
|
||||
|
||||
if ($amount < 0) {
|
||||
// if amount is less than zero, move to $importAccount
|
||||
$accountFrom = $personalAccount;
|
||||
$accountTo = $importAccount;
|
||||
} else {
|
||||
$accountFrom = $importAccount;
|
||||
$accountTo = $personalAccount;
|
||||
}
|
||||
$amount = $amount < 0 ? $amount * -1 : $amount;
|
||||
$date = new Carbon($payload['data']['date']);
|
||||
|
||||
// find a journal?
|
||||
$current = $this->_repository->findImportEntry($importMap, 'Transaction', intval($payload['data']['id']));
|
||||
|
||||
|
||||
if (is_null($current)) {
|
||||
$journal = $this->_journals->createSimpleJournal(
|
||||
$accountFrom, $accountTo,
|
||||
$payload['data']['description'], $amount, $date
|
||||
);
|
||||
$this->_repository->store($importMap, 'Transaction', $payload['data']['id'], $journal->id);
|
||||
\Log::debug(
|
||||
'Imported transaction "' . $payload['data']['description'] . '" (' . $journal->date->format('Y-m-d')
|
||||
. ').'
|
||||
);
|
||||
} else {
|
||||
// do nothing.
|
||||
\Log::debug('ALREADY imported transaction "' . $payload['data']['description'] . '".');
|
||||
}
|
||||
|
||||
$job->delete();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
* @param array $payload
|
||||
*/
|
||||
public function importTransfer(Job $job, array $payload)
|
||||
{
|
||||
|
||||
|
||||
/** @var \Importmap $importMap */
|
||||
$importMap = $this->_repository->findImportmap($payload['mapID']);
|
||||
$user = $importMap->user;
|
||||
$this->overruleUser($user);
|
||||
|
||||
// from account:
|
||||
$oldFromAccountID = intval($payload['data']['accountfrom_id']);
|
||||
$oldFromAccountEntry = $this->_repository->findImportEntry($importMap, 'Account', $oldFromAccountID);
|
||||
$accountFrom = $this->_accounts->find($oldFromAccountEntry->new);
|
||||
|
||||
// to account:
|
||||
$oldToAccountID = intval($payload['data']['accountto_id']);
|
||||
$oldToAccountEntry = $this->_repository->findImportEntry($importMap, 'Account', $oldToAccountID);
|
||||
$accountTo = $this->_accounts->find($oldToAccountEntry->new);
|
||||
if (!is_null($accountFrom) && !is_null($accountTo)) {
|
||||
$amount = floatval($payload['data']['amount']);
|
||||
$date = new Carbon($payload['data']['date']);
|
||||
$journal = $this->_journals->createSimpleJournal(
|
||||
$accountFrom, $accountTo, $payload['data']['description'],
|
||||
$amount, $date
|
||||
);
|
||||
\Log::debug('Imported transfer "' . $payload['data']['description'] . '".');
|
||||
$job->delete();
|
||||
} else {
|
||||
$job->release(5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Job $job
|
||||
* @param $payload
|
||||
*/
|
||||
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)) {
|
||||
// we are able to process the file!
|
||||
|
||||
// make an import map. Which is some kind of object because we use queues.
|
||||
$importMap = new \Importmap;
|
||||
$importMap->user()->associate($user);
|
||||
$importMap->file = $filename;
|
||||
$importMap->save();
|
||||
|
||||
// we can now launch a billion jobs importing every little thing into Firefly III
|
||||
$raw = file_get_contents($filename);
|
||||
$JSON = json_decode($raw);
|
||||
|
||||
$classes = ['accounts', 'components', 'limits', 'piggybanks',
|
||||
'predictables', 'settings', 'transactions', 'transfers'];
|
||||
|
||||
foreach ($classes as $classes_plural) {
|
||||
$class = ucfirst(\Str::singular($classes_plural));
|
||||
\Log::debug('Create job to import all ' . $classes_plural);
|
||||
foreach ($JSON->$classes_plural as $entry) {
|
||||
\Log::debug('Create job to import single ' . $class);
|
||||
$fn = 'import' . $class;
|
||||
$jobFunction = 'Firefly\Queue\Import@' . $fn;
|
||||
\Queue::push($jobFunction, ['data' => $entry, 'class' => $class, 'mapID' => $importMap->id]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// , components, limits, piggybanks, predictables, settings, transactions, transfers
|
||||
// component_predictables, component_transactions, component_transfers
|
||||
|
||||
$count = count($JSON->component_transaction);
|
||||
foreach ($JSON->component_transaction as $index => $entry) {
|
||||
\Log::debug('Create job to import components_transaction! Yay! (' . $index . '/' . $count . ') ');
|
||||
$fn = 'importComponentTransaction';
|
||||
$jobFunction = 'Firefly\Queue\Import@' . $fn;
|
||||
\Queue::push($jobFunction, ['data' => $entry, 'mapID' => $importMap->id]);
|
||||
}
|
||||
|
||||
// queue a job to clean up the "import account", it should properly fall back
|
||||
// to the cash account (which it doesn't always do for some reason).
|
||||
\Queue::push('Firefly\Queue\Import@cleanImportAccount', ['mapID' => $importMap->id]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
\Log::debug('Done with job "start"');
|
||||
// this is it, close the job:
|
||||
$job->delete();
|
||||
}
|
||||
}
|
@@ -46,11 +46,23 @@ interface AccountRepositoryInterface
|
||||
public function find($accountId);
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
* @param $type
|
||||
* @return mixed
|
||||
*/
|
||||
public function findByName($name);
|
||||
public function findAccountType($type);
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param \AccountType $type
|
||||
* @return mixed
|
||||
*/
|
||||
public function findByName($name, \AccountType $type = null);
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function findByNameAny($name);
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
@@ -89,6 +101,18 @@ interface AccountRepositoryInterface
|
||||
*/
|
||||
public function getDefault();
|
||||
|
||||
/**
|
||||
* @param \AccountType $type
|
||||
* @return mixed
|
||||
*/
|
||||
public function getByAccountType(\AccountType $type);
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function overruleUser(\User $user);
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*
|
||||
|
@@ -12,11 +12,15 @@ use Carbon\Carbon;
|
||||
*/
|
||||
class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_user = \Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,7 +28,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return \Auth::user()->accounts()->count();
|
||||
return $this->_user->accounts()->count();
|
||||
|
||||
}
|
||||
|
||||
@@ -86,8 +90,8 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
$accountIDs = array_unique($accountIDs);
|
||||
if (count($accountIDs) > 0) {
|
||||
// find the "initial balance" type accounts in this list. Should be just 1.
|
||||
$query = \Auth::user()->accounts()->accountTypeIn(['Initial balance account'])
|
||||
->whereIn('accounts.id', $accountIDs);
|
||||
$query = $this->_user->accounts()->accountTypeIn(['Initial balance account'])
|
||||
->whereIn('accounts.id', $accountIDs);
|
||||
if ($query->count() == 1) {
|
||||
$iba = $query->first(['accounts.*']);
|
||||
$iba->delete();
|
||||
@@ -111,7 +115,16 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
*/
|
||||
public function find($accountId)
|
||||
{
|
||||
return \Auth::user()->accounts()->where('id', $accountId)->first();
|
||||
return $this->_user->accounts()->where('id', $accountId)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @return mixed
|
||||
*/
|
||||
public function findAccountType($type)
|
||||
{
|
||||
return \AccountType::where('type', $type)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,9 +137,23 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
$type = is_null($type) ? \AccountType::where('type', 'Default account')->first() : $type;
|
||||
|
||||
return \Auth::user()->accounts()->where('account_type_id', $type->id)
|
||||
->where('name', 'like', '%' . $name . '%')
|
||||
->first();
|
||||
return $this->_user->accounts()->where('account_type_id', $type->id)
|
||||
->where('name', 'like', '%' . $name . '%')
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for import
|
||||
*
|
||||
* @param $name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function findByNameAny($name)
|
||||
{
|
||||
return $this->_user->accounts()
|
||||
->where('name', 'like', '%' . $name . '%')
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,7 +161,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return \Auth::user()->accounts()->with('accounttype')->orderBy('name', 'ASC')->get();
|
||||
return $this->_user->accounts()->with('accounttype')->orderBy('name', 'ASC')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,10 +169,10 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
*/
|
||||
public function getActiveDefault()
|
||||
{
|
||||
return \Auth::user()->accounts()->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.type', 'Default account')->where('accounts.active', 1)
|
||||
return $this->_user->accounts()->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.type', 'Default account')->where('accounts.active', 1)
|
||||
|
||||
->get(['accounts.*']);
|
||||
->get(['accounts.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,12 +180,12 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
*/
|
||||
public function getActiveDefaultAsSelectList()
|
||||
{
|
||||
$list = \Auth::user()->accounts()->leftJoin(
|
||||
'account_types', 'account_types.id', '=', 'accounts.account_type_id'
|
||||
$list = $this->_user->accounts()->leftJoin(
|
||||
'account_types', 'account_types.id', '=', 'accounts.account_type_id'
|
||||
)
|
||||
->where('account_types.type', 'Default account')->where('accounts.active', 1)
|
||||
->where('account_types.type', 'Default account')->where('accounts.active', 1)
|
||||
|
||||
->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
|
||||
->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
|
||||
$return = [];
|
||||
foreach ($list as $entry) {
|
||||
$return[intval($entry->id)] = $entry->name;
|
||||
@@ -172,16 +199,22 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
*/
|
||||
public function getBeneficiaries()
|
||||
{
|
||||
$list = \Auth::user()->accounts()->leftJoin(
|
||||
'account_types', 'account_types.id', '=', 'accounts.account_type_id'
|
||||
$list = $this->_user->accounts()->leftJoin(
|
||||
'account_types', 'account_types.id', '=', 'accounts.account_type_id'
|
||||
)
|
||||
->where('account_types.type', 'Beneficiary account')->where('accounts.active', 1)
|
||||
->where('account_types.type', 'Beneficiary account')->where('accounts.active', 1)
|
||||
|
||||
->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
|
||||
->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function getByAccountType(\AccountType $type)
|
||||
{
|
||||
return $this->_user->accounts()->with('accounttype')->orderBy('name', 'ASC')
|
||||
->where('account_type_id', $type->id)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ids
|
||||
*
|
||||
@@ -190,7 +223,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
public function getByIds(array $ids)
|
||||
{
|
||||
if (count($ids) > 0) {
|
||||
return \Auth::user()->accounts()->with('accounttype')->whereIn('id', $ids)->orderBy('name', 'ASC')->get();
|
||||
return $this->_user->accounts()->with('accounttype')->whereIn('id', $ids)->orderBy('name', 'ASC')->get();
|
||||
} else {
|
||||
return $this->getActiveDefault();
|
||||
}
|
||||
@@ -202,7 +235,15 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
public function getCashAccount()
|
||||
{
|
||||
$type = \AccountType::where('type', 'Cash account')->first();
|
||||
$cash = \Auth::user()->accounts()->where('account_type_id', $type->id)->first();
|
||||
$cash = $this->_user->accounts()->where('account_type_id', $type->id)->first();
|
||||
if (is_null($cash)) {
|
||||
$cash = new \Account;
|
||||
$cash->accountType()->associate($type);
|
||||
$cash->user()->associate($this->_user);
|
||||
$cash->name = 'Cash account';
|
||||
$cash->active = 1;
|
||||
$cash->save();
|
||||
}
|
||||
|
||||
return $cash;
|
||||
|
||||
@@ -213,10 +254,20 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
*/
|
||||
public function getDefault()
|
||||
{
|
||||
return \Auth::user()->accounts()->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.type', 'Default account')
|
||||
return $this->_user->accounts()->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.type', 'Default account')
|
||||
|
||||
->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
|
||||
->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function overruleUser(\User $user)
|
||||
{
|
||||
$this->_user = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,6 +285,9 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
&& get_class($data['account_type']) == 'AccountType'
|
||||
) {
|
||||
$accountType = $data['account_type'];
|
||||
} else if (isset($data['account_type']) && is_string($data['account_type'])) {
|
||||
$accountType = \AccountType::where('type', $data['account_type'])->first();
|
||||
|
||||
} else {
|
||||
$accountType = \AccountType::where('type', 'Default account')->first();
|
||||
}
|
||||
@@ -243,7 +297,8 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
*/
|
||||
$account = new \Account;
|
||||
$account->accountType()->associate($accountType);
|
||||
$account->user()->associate(\Auth::user());
|
||||
$account->user()->associate($this->_user);
|
||||
|
||||
$account->name = $data['name'];
|
||||
$account->active
|
||||
= isset($data['active']) && intval($data['active']) >= 0 && intval($data['active']) <= 1 ? intval(
|
||||
@@ -256,7 +311,9 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
if (isset($data['openingbalance']) && isset($data['openingbalancedate'])) {
|
||||
$amount = floatval($data['openingbalance']);
|
||||
$date = new Carbon($data['openingbalancedate']);
|
||||
$this->_createInitialBalance($account, $amount, $date);
|
||||
if ($amount != 0) {
|
||||
$this->_createInitialBalance($account, $amount, $date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,7 +375,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
// create new account:
|
||||
$initial = new \Account;
|
||||
$initial->accountType()->associate($initialBalanceAT);
|
||||
$initial->user()->associate(\Auth::user());
|
||||
$initial->user()->associate($this->_user);
|
||||
$initial->name = $account->name . ' initial balance';
|
||||
$initial->active = 0;
|
||||
if ($initial->validate()) {
|
||||
@@ -328,6 +385,7 @@ class EloquentAccountRepository implements AccountRepositoryInterface
|
||||
$transactionJournal = \App::make(
|
||||
'Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'
|
||||
);
|
||||
$transactionJournal->overruleUser($this->_user);
|
||||
|
||||
$transactionJournal->createSimpleJournal(
|
||||
$initial, $account, 'Initial Balance for ' . $account->name, $amount, $date
|
||||
|
@@ -23,6 +23,19 @@ interface BudgetRepositoryInterface
|
||||
*/
|
||||
public function find($budgetId);
|
||||
|
||||
|
||||
/**
|
||||
* @param $budgetName
|
||||
* @return mixed
|
||||
*/
|
||||
public function findByName($budgetName);
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function overruleUser(\User $user);
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
|
@@ -3,19 +3,32 @@
|
||||
namespace Firefly\Storage\Budget;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
/**
|
||||
* Class EloquentBudgetRepository
|
||||
*
|
||||
* @package Firefly\Storage\Budget
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*
|
||||
*/
|
||||
class EloquentBudgetRepository implements BudgetRepositoryInterface
|
||||
{
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_user = \Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
*
|
||||
* @return bool|mixed
|
||||
* @return bool
|
||||
*/
|
||||
public function destroy(\Budget $budget)
|
||||
{
|
||||
@@ -27,25 +40,35 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
|
||||
/**
|
||||
* @param $budgetId
|
||||
*
|
||||
* @return mixed
|
||||
* @return \Budget|null
|
||||
*/
|
||||
public function find($budgetId)
|
||||
{
|
||||
|
||||
return \Auth::user()->budgets()->find($budgetId);
|
||||
return $this->_user->budgets()->find($budgetId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @param $budgetName
|
||||
* @return \Budget|null
|
||||
*/
|
||||
public function findByName($budgetName)
|
||||
{
|
||||
|
||||
return $this->_user->budgets()->whereName($budgetName)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$set = \Auth::user()->budgets()->with(
|
||||
['limits' => function ($q) {
|
||||
$q->orderBy('limits.startdate', 'DESC');
|
||||
}, 'limits.limitrepetitions' => function ($q) {
|
||||
$q->orderBy('limit_repetitions.startdate', 'ASC');
|
||||
}]
|
||||
$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();
|
||||
foreach ($set as $budget) {
|
||||
foreach ($budget->limits as $limit) {
|
||||
@@ -59,12 +82,12 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|mixed
|
||||
* @return array
|
||||
*/
|
||||
public function getAsSelectList()
|
||||
{
|
||||
$list = \Auth::user()->budgets()->with(
|
||||
['limits', 'limits.limitrepetitions']
|
||||
$list = $this->_user->budgets()->with(
|
||||
['limits', 'limits.limitrepetitions']
|
||||
)->orderBy('name', 'ASC')->get();
|
||||
$return = [];
|
||||
foreach ($list as $entry) {
|
||||
@@ -74,56 +97,45 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function overruleUser(\User $user)
|
||||
{
|
||||
$this->_user = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*
|
||||
* @return \Budget|mixed
|
||||
* @return \Budget
|
||||
*/
|
||||
public function store($data)
|
||||
{
|
||||
$budget = new \Budget;
|
||||
$budget = new \Budget;
|
||||
$budget->name = $data['name'];
|
||||
$budget->user()->associate(\Auth::user());
|
||||
$budget->user()->associate($this->_user);
|
||||
$budget->save();
|
||||
|
||||
// if limit, create limit (repetition itself will be picked up elsewhere).
|
||||
if (floatval($data['amount']) > 0) {
|
||||
$limit = new \Limit;
|
||||
$limit->budget()->associate($budget);
|
||||
if (isset($data['amount']) && floatval($data['amount']) > 0) {
|
||||
$startDate = new Carbon;
|
||||
switch ($data['repeat_freq']) {
|
||||
case 'daily':
|
||||
$startDate->startOfDay();
|
||||
break;
|
||||
case 'weekly':
|
||||
$startDate->startOfWeek();
|
||||
break;
|
||||
case 'monthly':
|
||||
$startDate->startOfMonth();
|
||||
break;
|
||||
case 'quarterly':
|
||||
$startDate->firstOfQuarter();
|
||||
break;
|
||||
case 'half-year':
|
||||
$startDate->startOfYear();
|
||||
if (intval($startDate->format('m')) >= 7) {
|
||||
$startDate->addMonths(6);
|
||||
}
|
||||
break;
|
||||
case 'yearly':
|
||||
$startDate->startOfYear();
|
||||
break;
|
||||
}
|
||||
$limit->startdate = $startDate;
|
||||
$limit->amount = $data['amount'];
|
||||
$limit->repeats = isset($data['repeats']) ? $data['repeats'] : 0;
|
||||
$limit->repeat_freq = $data['repeat_freq'];
|
||||
if ($limit->validate()) {
|
||||
$limit->save();
|
||||
\Event::fire('limits.store', [$limit]);
|
||||
}
|
||||
$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();
|
||||
}
|
||||
|
@@ -29,6 +29,12 @@ interface CategoryRepositoryInterface
|
||||
*/
|
||||
public function createOrFind($name);
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function overruleUser(\User $user);
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
|
@@ -9,6 +9,16 @@ namespace Firefly\Storage\Category;
|
||||
*/
|
||||
class EloquentCategoryRepository implements CategoryRepositoryInterface
|
||||
{
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_user = \Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
@@ -48,7 +58,7 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface
|
||||
*/
|
||||
public function find($categoryId)
|
||||
{
|
||||
return \Auth::user()->categories()->find($categoryId);
|
||||
return $this->_user->categories()->find($categoryId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +72,7 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
return \Auth::user()->categories()->where('name', 'LIKE', '%' . $name . '%')->first();
|
||||
return $this->_user->categories()->where('name', 'LIKE', '%' . $name . '%')->first();
|
||||
|
||||
}
|
||||
|
||||
@@ -71,7 +81,7 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return \Auth::user()->categories()->orderBy('name', 'ASC')->get();
|
||||
return $this->_user->categories()->orderBy('name', 'ASC')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,10 +91,10 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface
|
||||
*/
|
||||
public function store($data)
|
||||
{
|
||||
$category = new \Category;
|
||||
$category = new \Category;
|
||||
$category->name = $data['name'];
|
||||
|
||||
$category->user()->associate(\Auth::user());
|
||||
$category->user()->associate($this->_user);
|
||||
$category->save();
|
||||
|
||||
return $category;
|
||||
@@ -106,4 +116,14 @@ class EloquentCategoryRepository implements CategoryRepositoryInterface
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function overruleUser(\User $user)
|
||||
{
|
||||
$this->_user = $user;
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -28,4 +28,10 @@ interface ComponentRepositoryInterface
|
||||
*/
|
||||
public function store($data);
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function overruleUser(\User $user);
|
||||
|
||||
}
|
@@ -14,12 +14,14 @@ use Illuminate\Database\QueryException;
|
||||
class EloquentComponentRepository implements ComponentRepositoryInterface
|
||||
{
|
||||
public $validator;
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_user = \Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,7 +29,7 @@ class EloquentComponentRepository implements ComponentRepositoryInterface
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return \Auth::user()->components()->count();
|
||||
return $this->_user->components()->count();
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +42,16 @@ class EloquentComponentRepository implements ComponentRepositoryInterface
|
||||
throw new FireflyException('No implementation.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function overruleUser(\User $user)
|
||||
{
|
||||
$this->_user = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*
|
||||
@@ -62,7 +74,7 @@ class EloquentComponentRepository implements ComponentRepositoryInterface
|
||||
|
||||
}
|
||||
$component->name = $data['name'];
|
||||
$component->user()->associate(\Auth::user());
|
||||
$component->user()->associate($this->_user);
|
||||
try {
|
||||
$component->save();
|
||||
} catch (QueryException $e) {
|
||||
|
58
app/lib/Firefly/Storage/Import/EloquentImportRepository.php
Normal file
58
app/lib/Firefly/Storage/Import/EloquentImportRepository.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Storage\Import;
|
||||
|
||||
|
||||
class EloquentImportRepository implements ImportRepositoryInterface
|
||||
{
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_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();
|
||||
}
|
||||
|
||||
}
|
33
app/lib/Firefly/Storage/Import/ImportRepositoryInterface.php
Normal file
33
app/lib/Firefly/Storage/Import/ImportRepositoryInterface.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Storage\Import;
|
||||
|
||||
/**
|
||||
* Interface ImportRepositoryInterface
|
||||
* @package Firefly\Storage\Import
|
||||
*/
|
||||
interface ImportRepositoryInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param \Importmap $map
|
||||
* @param $class
|
||||
* @param $oldID
|
||||
* @param $newID
|
||||
* @return mixed
|
||||
*/
|
||||
public function store(\Importmap $map, $class, $oldID, $newID);
|
||||
|
||||
public function findImportMap($id);
|
||||
|
||||
public function findImportEntry(\Importmap $map, $class, $oldID);
|
||||
|
||||
public function findImportComponentMap(\Importmap $map, $oldComponentId);
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function overruleUser(\User $user);
|
||||
}
|
@@ -12,7 +12,15 @@ use Carbon\Carbon;
|
||||
*/
|
||||
class EloquentLimitRepository implements LimitRepositoryInterface
|
||||
{
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_user = \Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Limit $limit
|
||||
@@ -26,24 +34,6 @@ class EloquentLimitRepository implements LimitRepositoryInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $limitId
|
||||
*
|
||||
@@ -52,15 +42,20 @@ class EloquentLimitRepository implements LimitRepositoryInterface
|
||||
public function find($limitId)
|
||||
{
|
||||
return \Limit::with('limitrepetitions')->where('limits.id', $limitId)->leftJoin(
|
||||
'components', 'components.id', '=', 'limits.component_id'
|
||||
'components', 'components.id', '=', 'limits.component_id'
|
||||
)
|
||||
->where('components.user_id', \Auth::user()->id)->first(['limits.*']);
|
||||
->where('components.user_id', $this->_user->id)->first(['limits.*']);
|
||||
}
|
||||
|
||||
public function findByBudgetAndDate(\Budget $budget, Carbon $date)
|
||||
{
|
||||
return \Limit::whereComponentId($budget->id)->where('startdate', $date->format('Y-m-d'))->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -72,6 +67,16 @@ class EloquentLimitRepository implements LimitRepositoryInterface
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function overruleUser(\User $user)
|
||||
{
|
||||
$this->_user = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*
|
||||
@@ -116,9 +121,9 @@ class EloquentLimitRepository implements LimitRepositoryInterface
|
||||
// find existing:
|
||||
$count = \Limit::
|
||||
leftJoin('components', 'components.id', '=', 'limits.component_id')->where(
|
||||
'components.user_id', \Auth::user()->id
|
||||
'components.user_id', $this->_user->id
|
||||
)->where('startdate', $date->format('Y-m-d'))->where('component_id', $data['budget_id'])->where(
|
||||
'repeat_freq', $data['period']
|
||||
'repeat_freq', $data['period']
|
||||
)->count();
|
||||
if ($count > 0) {
|
||||
\Session::flash('error', 'There already is an entry for these parameters.');
|
||||
@@ -128,9 +133,9 @@ class EloquentLimitRepository implements LimitRepositoryInterface
|
||||
// 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->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());
|
||||
@@ -139,4 +144,22 @@ class EloquentLimitRepository implements LimitRepositoryInterface
|
||||
return $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
}
|
@@ -12,6 +12,36 @@ use Carbon\Carbon;
|
||||
interface LimitRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param \Limit $limit
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function destroy(\Limit $limit);
|
||||
|
||||
/**
|
||||
* @param $limitId
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function find($limitId);
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
* @param Carbon $date
|
||||
* @return mixed
|
||||
*/
|
||||
public function findByBudgetAndDate(\Budget $budget, Carbon $date);
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTJByBudgetAndDateRange(\Budget $budget, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*
|
||||
@@ -28,25 +58,8 @@ interface LimitRepositoryInterface
|
||||
public function update(\Limit $limit, $data);
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTJByBudgetAndDateRange(\Budget $budget, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param $limitId
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function find($limitId);
|
||||
|
||||
/**
|
||||
* @param \Limit $limit
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function destroy(\Limit $limit);
|
||||
public function overruleUser(\User $user);
|
||||
}
|
@@ -14,6 +14,15 @@ use Firefly\Exception\FireflyException;
|
||||
class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
{
|
||||
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_user = \Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
@@ -21,14 +30,14 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
public function count()
|
||||
{
|
||||
return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where(
|
||||
'accounts.user_id', \Auth::user()->id
|
||||
'accounts.user_id', $this->_user->id
|
||||
)->count();
|
||||
}
|
||||
|
||||
public function countNonrepeating()
|
||||
{
|
||||
return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where(
|
||||
'accounts.user_id', \Auth::user()->id
|
||||
'accounts.user_id', $this->_user->id
|
||||
)->where('repeats', 0)->count();
|
||||
|
||||
}
|
||||
@@ -36,7 +45,7 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
public function countRepeating()
|
||||
{
|
||||
return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where(
|
||||
'accounts.user_id', \Auth::user()->id
|
||||
'accounts.user_id', $this->_user->id
|
||||
)->where('repeats', 1)->count();
|
||||
}
|
||||
|
||||
@@ -60,16 +69,23 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
public function find($piggyBankId)
|
||||
{
|
||||
return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where(
|
||||
'accounts.user_id', \Auth::user()->id
|
||||
'accounts.user_id', $this->_user->id
|
||||
)->where('piggybanks.id', $piggyBankId)->first(['piggybanks.*']);
|
||||
}
|
||||
|
||||
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.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$piggies = \Auth::user()->piggybanks()->with(['account', 'piggybankrepetitions'])->get();
|
||||
$piggies = $this->_user->piggybanks()->with(['account', 'piggybankrepetitions'])->get();
|
||||
|
||||
foreach ($piggies as $pig) {
|
||||
$pig->leftInAccount = $this->leftOnAccount($pig->account);
|
||||
@@ -95,7 +111,6 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Piggybank $piggyBank
|
||||
* @param $amount
|
||||
@@ -115,6 +130,16 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function overruleUser(\User $user)
|
||||
{
|
||||
$this->_user = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*
|
||||
@@ -122,19 +147,20 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
*/
|
||||
public function store($data)
|
||||
{
|
||||
if ($data['targetdate'] == '') {
|
||||
if (isset($data['targetdate']) && $data['targetdate'] == '') {
|
||||
unset($data['targetdate']);
|
||||
}
|
||||
if ($data['reminder'] == 'none') {
|
||||
if (isset($data['reminder']) && $data['reminder'] == 'none') {
|
||||
unset($data['reminder']);
|
||||
}
|
||||
if ($data['startdate'] == '') {
|
||||
if (isset($data['startdate']) && $data['startdate'] == '') {
|
||||
unset($data['startdate']);
|
||||
}
|
||||
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$account = isset($data['account_id']) ? $accounts->find($data['account_id']) : null;
|
||||
$accounts->overruleUser($this->_user);
|
||||
$account = isset($data['account_id']) ? $accounts->find($data['account_id']) : null;
|
||||
|
||||
|
||||
$piggyBank = new \Piggybank($data);
|
||||
@@ -142,7 +168,7 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -150,6 +176,7 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
|
||||
if ($piggyBank->repeats && !isset($data['targetdate'])) {
|
||||
$piggyBank->errors()->add('targetdate', 'Target date is mandatory!');
|
||||
\Log::error('PiggyBank create-error: ' . $piggyBank->errors()->first());
|
||||
|
||||
return $piggyBank;
|
||||
}
|
||||
@@ -161,13 +188,14 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
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);
|
||||
$reminderSkip = $piggyBank->reminder_skip < 1 ? 1 : intval($piggyBank->reminder_skip);
|
||||
$firstReminder = new Carbon;
|
||||
switch ($piggyBank->reminder) {
|
||||
case 'day':
|
||||
@@ -188,8 +216,9 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
}
|
||||
if ($firstReminder > $piggyBank->targetdate) {
|
||||
$piggyBank->errors()->add(
|
||||
'reminder', 'The reminder has been set to remind you after the piggy bank will expire.'
|
||||
'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;
|
||||
}
|
||||
@@ -197,6 +226,7 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
$piggyBank->save();
|
||||
}
|
||||
|
||||
|
||||
return $piggyBank;
|
||||
}
|
||||
|
||||
@@ -210,19 +240,20 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
{
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */
|
||||
$accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$account = isset($data['account_id']) ? $accounts->find($data['account_id']) : null;
|
||||
$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->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->targetdate = strlen($data['targetdate']) > 0 ? new Carbon($data['targetdate']) : null;
|
||||
$piggy->startdate
|
||||
= isset($data['startdate']) && strlen($data['startdate']) > 0 ? new Carbon($data['startdate']) : null;
|
||||
= isset($data['startdate']) && strlen($data['startdate']) > 0 ? new Carbon($data['startdate']) : null;
|
||||
|
||||
|
||||
foreach ($piggy->piggybankrepetitions()->get() as $rep) {
|
||||
@@ -230,7 +261,7 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface
|
||||
}
|
||||
|
||||
if ($piggy->repeats == 1) {
|
||||
$piggy->rep_every = intval($data['rep_every']);
|
||||
$piggy->rep_every = intval($data['rep_every']);
|
||||
$piggy->rep_length = $data['rep_length'];
|
||||
}
|
||||
|
||||
|
@@ -40,6 +40,8 @@ interface PiggybankRepositoryInterface
|
||||
*/
|
||||
public function find($piggyBankId);
|
||||
|
||||
public function findByName($piggyBankName);
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -77,5 +79,11 @@ interface PiggybankRepositoryInterface
|
||||
*/
|
||||
public function update(\Piggybank $piggy, $data);
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function overruleUser(\User $user);
|
||||
|
||||
|
||||
}
|
@@ -12,6 +12,27 @@ use Carbon\Carbon;
|
||||
*/
|
||||
class EloquentRecurringTransactionRepository implements RecurringTransactionRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function overruleUser(\User $user)
|
||||
{
|
||||
$this->_user = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_user = \Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \RecurringTransaction $recurringTransaction
|
||||
*
|
||||
@@ -24,12 +45,17 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo
|
||||
return true;
|
||||
}
|
||||
|
||||
public function findByName($name)
|
||||
{
|
||||
return $this->_user->recurringtransactions()->where('name', 'LIKE', '%' . $name . '%')->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return \Auth::user()->recurringtransactions()->get();
|
||||
return $this->_user->recurringtransactions()->get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,9 +66,9 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo
|
||||
public function store($data)
|
||||
{
|
||||
$recurringTransaction = new \RecurringTransaction;
|
||||
$recurringTransaction->user()->associate(\Auth::user());
|
||||
$recurringTransaction->name = $data['name'];
|
||||
$recurringTransaction->match = join(' ', explode(',', $data['match']));
|
||||
$recurringTransaction->user()->associate($this->_user);
|
||||
$recurringTransaction->name = $data['name'];
|
||||
$recurringTransaction->match = join(' ', explode(',', $data['match']));
|
||||
$recurringTransaction->amount_max = floatval($data['amount_max']);
|
||||
$recurringTransaction->amount_min = floatval($data['amount_min']);
|
||||
|
||||
@@ -53,10 +79,10 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo
|
||||
return $recurringTransaction;
|
||||
}
|
||||
|
||||
$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->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()) {
|
||||
@@ -74,8 +100,8 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo
|
||||
*/
|
||||
public function update(\RecurringTransaction $recurringTransaction, $data)
|
||||
{
|
||||
$recurringTransaction->name = $data['name'];
|
||||
$recurringTransaction->match = join(' ', explode(',', $data['match']));
|
||||
$recurringTransaction->name = $data['name'];
|
||||
$recurringTransaction->match = join(' ', explode(',', $data['match']));
|
||||
$recurringTransaction->amount_max = floatval($data['amount_max']);
|
||||
$recurringTransaction->amount_min = floatval($data['amount_min']);
|
||||
|
||||
@@ -85,10 +111,10 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo
|
||||
|
||||
return $recurringTransaction;
|
||||
}
|
||||
$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->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()) {
|
||||
|
@@ -16,6 +16,12 @@ interface RecurringTransactionRepositoryInterface
|
||||
*/
|
||||
public function get();
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function findByName($name);
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*
|
||||
@@ -38,5 +44,11 @@ interface RecurringTransactionRepositoryInterface
|
||||
*/
|
||||
public function update(\RecurringTransaction $recurringTransaction, $data);
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function overruleUser(\User $user);
|
||||
|
||||
|
||||
}
|
@@ -12,6 +12,26 @@ use Carbon\Carbon;
|
||||
*/
|
||||
class EloquentReminderRepository implements ReminderRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function overruleUser(\User $user)
|
||||
{
|
||||
$this->_user = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_user = \Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Reminder $reminder
|
||||
*
|
||||
@@ -42,7 +62,7 @@ class EloquentReminderRepository implements ReminderRepositoryInterface
|
||||
{
|
||||
$today = new Carbon;
|
||||
|
||||
return \Auth::user()->reminders()->validOn($today)->get();
|
||||
return $this->_user->reminders()->validOn($today)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,8 +72,8 @@ class EloquentReminderRepository implements ReminderRepositoryInterface
|
||||
{
|
||||
$today = new Carbon;
|
||||
|
||||
return \Auth::user()->reminders()->with('recurringtransaction')->validOn($today)->where(
|
||||
'class', 'RecurringTransactionReminder'
|
||||
return $this->_user->reminders()->with('recurringtransaction')->validOn($today)->where(
|
||||
'class', 'RecurringTransactionReminder'
|
||||
)->get();
|
||||
|
||||
}
|
||||
|
@@ -39,4 +39,10 @@ interface ReminderRepositoryInterface
|
||||
|
||||
public function getCurrentRecurringReminders();
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function overruleUser(\User $user);
|
||||
|
||||
}
|
@@ -18,55 +18,60 @@ class StorageServiceProvider extends ServiceProvider
|
||||
public function register()
|
||||
{
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\User\UserRepositoryInterface',
|
||||
'Firefly\Storage\User\EloquentUserRepository'
|
||||
'Firefly\Storage\User\UserRepositoryInterface',
|
||||
'Firefly\Storage\User\EloquentUserRepository'
|
||||
);
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\Transaction\TransactionRepositoryInterface',
|
||||
'Firefly\Storage\Transaction\EloquentTransactionRepository'
|
||||
'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\Piggybank\PiggybankRepositoryInterface',
|
||||
'Firefly\Storage\Piggybank\EloquentPiggybankRepository'
|
||||
'Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface',
|
||||
'Firefly\Storage\RecurringTransaction\EloquentRecurringTransactionRepository'
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface',
|
||||
'Firefly\Storage\RecurringTransaction\EloquentRecurringTransactionRepository'
|
||||
'Firefly\Storage\Reminder\ReminderRepositoryInterface',
|
||||
'Firefly\Storage\Reminder\EloquentReminderRepository'
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\Reminder\ReminderRepositoryInterface',
|
||||
'Firefly\Storage\Reminder\EloquentReminderRepository'
|
||||
'Firefly\Storage\Account\AccountRepositoryInterface',
|
||||
'Firefly\Storage\Account\EloquentAccountRepository'
|
||||
);
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface',
|
||||
'Firefly\Storage\TransactionJournal\EloquentTransactionJournalRepository'
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\Account\AccountRepositoryInterface',
|
||||
'Firefly\Storage\Account\EloquentAccountRepository'
|
||||
);
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface',
|
||||
'Firefly\Storage\TransactionJournal\EloquentTransactionJournalRepository'
|
||||
'Firefly\Storage\Component\ComponentRepositoryInterface',
|
||||
'Firefly\Storage\Component\EloquentComponentRepository'
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\Component\ComponentRepositoryInterface',
|
||||
'Firefly\Storage\Component\EloquentComponentRepository'
|
||||
'Firefly\Storage\Limit\LimitRepositoryInterface',
|
||||
'Firefly\Storage\Limit\EloquentLimitRepository'
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\Limit\LimitRepositoryInterface',
|
||||
'Firefly\Storage\Limit\EloquentLimitRepository'
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\Budget\BudgetRepositoryInterface',
|
||||
'Firefly\Storage\Budget\EloquentBudgetRepository'
|
||||
'Firefly\Storage\Budget\BudgetRepositoryInterface',
|
||||
'Firefly\Storage\Budget\EloquentBudgetRepository'
|
||||
);
|
||||
$this->app->bind(
|
||||
'Firefly\Storage\Category\CategoryRepositoryInterface',
|
||||
'Firefly\Storage\Category\EloquentCategoryRepository'
|
||||
'Firefly\Storage\Category\CategoryRepositoryInterface',
|
||||
'Firefly\Storage\Category\EloquentCategoryRepository'
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -9,5 +9,24 @@ namespace Firefly\Storage\Transaction;
|
||||
*/
|
||||
class EloquentTransactionRepository implements TransactionRepositoryInterface
|
||||
{
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_user = \Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function overruleUser(\User $user)
|
||||
{
|
||||
$this->_user = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@@ -9,6 +9,11 @@ namespace Firefly\Storage\Transaction;
|
||||
*/
|
||||
interface TransactionRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function overruleUser(\User $user);
|
||||
|
||||
|
||||
}
|
@@ -14,6 +14,16 @@ use Firefly\Exception\FireflyException;
|
||||
class EloquentTransactionJournalRepository implements TransactionJournalRepositoryInterface
|
||||
{
|
||||
|
||||
protected $_user = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_user = \Auth::user();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* We're building this thinking the money goes from A to B.
|
||||
@@ -34,8 +44,8 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
* A gains 200 (200). * -1
|
||||
* B loses 200 (-200). * 1
|
||||
*
|
||||
* @param \Account $from
|
||||
* @param \Account $toAccount
|
||||
* @param \Account $from
|
||||
* @param \Account $toAccount
|
||||
* @param $description
|
||||
* @param $amount
|
||||
* @param \Carbon\Carbon $date
|
||||
@@ -48,7 +58,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
$journal = new \TransactionJournal;
|
||||
|
||||
$amountFrom = $amount * -1;
|
||||
$amountTo = $amount;
|
||||
$amountTo = $amount;
|
||||
|
||||
if (round(floatval($amount), 2) == 0.00) {
|
||||
$journal->errors()->add('amount', 'Amount must not be zero.');
|
||||
@@ -64,7 +74,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
}
|
||||
|
||||
// account types for both:
|
||||
$toAT = $toAccount->accountType->type;
|
||||
$toAT = $toAccount->accountType->type;
|
||||
$fromAT = $from->accountType->type;
|
||||
|
||||
$journalType = null;
|
||||
@@ -105,10 +115,10 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
|
||||
$journal->transactionType()->associate($journalType);
|
||||
$journal->transactionCurrency()->associate($currency);
|
||||
$journal->user()->associate(\Auth::user());
|
||||
$journal->completed = false;
|
||||
$journal->user()->associate($this->_user);
|
||||
$journal->completed = false;
|
||||
$journal->description = $description;
|
||||
$journal->date = $date;
|
||||
$journal->date = $date;
|
||||
if (!$journal->validate()) {
|
||||
return $journal;
|
||||
}
|
||||
@@ -119,10 +129,10 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
$fromTransaction->account()->associate($from);
|
||||
$fromTransaction->transactionJournal()->associate($journal);
|
||||
$fromTransaction->description = null;
|
||||
$fromTransaction->amount = $amountFrom;
|
||||
$fromTransaction->amount = $amountFrom;
|
||||
if (!$fromTransaction->validate()) {
|
||||
throw new FireflyException('Cannot create valid transaction (from): ' . $fromTransaction->errors()->first(
|
||||
));
|
||||
throw new FireflyException('Cannot create valid transaction (from): ' . $fromTransaction->errors()
|
||||
->first());
|
||||
}
|
||||
$fromTransaction->save();
|
||||
|
||||
@@ -130,7 +140,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
$toTransaction->account()->associate($toAccount);
|
||||
$toTransaction->transactionJournal()->associate($journal);
|
||||
$toTransaction->description = null;
|
||||
$toTransaction->amount = $amountTo;
|
||||
$toTransaction->amount = $amountTo;
|
||||
if (!$toTransaction->validate()) {
|
||||
throw new FireflyException('Cannot create valid transaction (to): ' . $toTransaction->errors()->first());
|
||||
}
|
||||
@@ -149,13 +159,13 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
*/
|
||||
public function find($journalId)
|
||||
{
|
||||
return \Auth::user()->transactionjournals()->with(
|
||||
['transactions' => function ($q) {
|
||||
return $q->orderBy('amount', 'ASC');
|
||||
}, 'transactioncurrency', 'transactiontype', 'components', 'transactions.account',
|
||||
'transactions.account.accounttype']
|
||||
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();
|
||||
->where('id', $journalId)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,64 +178,76 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
* @param Carbon $date
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getByAccountAndDate(\Account $account, Carbon $date)
|
||||
{
|
||||
$accountID = $account->id;
|
||||
$query = \Auth::user()->transactionjournals()->with(
|
||||
[
|
||||
'transactions',
|
||||
'transactions.account',
|
||||
'transactioncurrency',
|
||||
'transactiontype'
|
||||
]
|
||||
$query = $this->_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', $accountID)
|
||||
->where('transaction_journals.date', $date->format('Y-m-d'))
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->get(['transaction_journals.*']);
|
||||
->distinct()
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=',
|
||||
'transaction_journals.id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->where('transactions.account_id', $accountID)
|
||||
->where('transaction_journals.date', $date->format('Y-m-d'))
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->get(['transaction_journals.*']);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
* @param int $count
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @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 = \Auth::user()->transactionjournals()->with(
|
||||
[
|
||||
'transactions',
|
||||
'transactioncurrency',
|
||||
'transactiontype'
|
||||
]
|
||||
$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.*']);
|
||||
->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 \User $user
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function overruleUser(\User $user)
|
||||
{
|
||||
$this->_user = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $count
|
||||
*
|
||||
@@ -233,19 +255,9 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
*/
|
||||
public function paginate($count = 25, Carbon $start = null, Carbon $end = null)
|
||||
{
|
||||
$query = \Auth::user()->transactionjournals()->with(
|
||||
[
|
||||
'transactions' => function ($q) {
|
||||
return $q->orderBy('amount', 'ASC');
|
||||
},
|
||||
'transactions.account',
|
||||
'transactions.account.accounttype',
|
||||
'transactioncurrency',
|
||||
'transactiontype'
|
||||
]
|
||||
)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.id', 'DESC');
|
||||
$query = $this->_user->transactionjournals()->WithRelevantData()
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.id', 'DESC');
|
||||
if (!is_null($start)) {
|
||||
$query->where('transaction_journals.date', '>=', $start->format('Y-m-d'));
|
||||
}
|
||||
@@ -270,37 +282,40 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
// depending on the $what
|
||||
|
||||
$fromAccount = null;
|
||||
$toAccount = null;
|
||||
$toAccount = null;
|
||||
|
||||
/** @var \Firefly\Storage\Account\AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = \App::make('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$accountRepository->overruleUser($this->_user);
|
||||
|
||||
/** @var \Firefly\Storage\Category\CategoryRepositoryInterface $catRepository */
|
||||
$catRepository = \App::make('Firefly\Storage\Category\CategoryRepositoryInterface');
|
||||
$catRepository->overruleUser($this->_user);
|
||||
|
||||
/** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budRepository */
|
||||
$budRepository = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
||||
$budRepository->overruleUser($this->_user);
|
||||
|
||||
|
||||
switch ($what) {
|
||||
case 'withdrawal':
|
||||
$fromAccount = $accountRepository->find(intval($data['account_id']));
|
||||
$toAccount = $accountRepository->createOrFindBeneficiary($data['beneficiary']);
|
||||
$toAccount = $accountRepository->createOrFindBeneficiary($data['beneficiary']);
|
||||
break;
|
||||
|
||||
case 'deposit':
|
||||
$fromAccount = $accountRepository->createOrFindBeneficiary($data['beneficiary']);
|
||||
$toAccount = $accountRepository->find(intval($data['account_id']));
|
||||
$toAccount = $accountRepository->find(intval($data['account_id']));
|
||||
break;
|
||||
case 'transfer':
|
||||
$fromAccount = $accountRepository->find(intval($data['account_from_id']));
|
||||
$toAccount = $accountRepository->find(intval($data['account_to_id']));
|
||||
$toAccount = $accountRepository->find(intval($data['account_to_id']));
|
||||
|
||||
break;
|
||||
}
|
||||
// fall back to cash if necessary:
|
||||
$fromAccount = is_null($fromAccount) ? $fromAccount = $accountRepository->getCashAccount() : $fromAccount;
|
||||
$toAccount = is_null($toAccount) ? $toAccount = $accountRepository->getCashAccount() : $toAccount;
|
||||
$toAccount = is_null($toAccount) ? $toAccount = $accountRepository->getCashAccount() : $toAccount;
|
||||
|
||||
// create or find category:
|
||||
$category = isset($data['category']) ? $catRepository->createOrFind($data['category']) : null;
|
||||
@@ -309,8 +324,8 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
$budget = isset($data['budget_id']) ? $budRepository->find(intval($data['budget_id'])) : null;
|
||||
// find amount & description:
|
||||
$description = trim($data['description']);
|
||||
$amount = floatval($data['amount']);
|
||||
$date = new Carbon($data['date']);
|
||||
$amount = floatval($data['amount']);
|
||||
$date = new Carbon($data['date']);
|
||||
|
||||
// try to create a journal:
|
||||
$transactionJournal = $this->createSimpleJournal($fromAccount, $toAccount, $description, $amount, $date);
|
||||
@@ -323,6 +338,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
if ($what == 'transfer') {
|
||||
/** @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 */
|
||||
@@ -337,15 +353,15 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
$transaction->piggybank()->associate($piggyBank);
|
||||
$transaction->save();
|
||||
\Event::fire(
|
||||
'piggybanks.createRelatedTransfer', [$piggyBank, $transactionJournal, $transaction]
|
||||
'piggybanks.createRelatedTransfer', [$piggyBank, $transactionJournal, $transaction]
|
||||
);
|
||||
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'
|
||||
'warning', 'Piggy bank "' . e($piggyBank->name)
|
||||
. '" is not set to draw money from any of the accounts in this transfer'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -375,18 +391,21 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
{
|
||||
/** @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']);
|
||||
$journal->date = $data['date'];
|
||||
$amount = floatval($data['amount']);
|
||||
|
||||
// remove previous category, if any:
|
||||
if (!is_null($journal->categories()->first())) {
|
||||
@@ -424,7 +443,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
switch ($journal->transactiontype->type) {
|
||||
case 'Withdrawal':
|
||||
// means transaction[0] is the users account.
|
||||
$account = $accountRepository->find($data['account_id']);
|
||||
$account = $accountRepository->find($data['account_id']);
|
||||
$beneficiary = $accountRepository->createOrFindBeneficiary($data['beneficiary']);
|
||||
$transactions[0]->account()->associate($account);
|
||||
$transactions[1]->account()->associate($beneficiary);
|
||||
@@ -438,7 +457,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
break;
|
||||
case 'Deposit':
|
||||
// means transaction[0] is the beneficiary.
|
||||
$account = $accountRepository->find($data['account_id']);
|
||||
$account = $accountRepository->find($data['account_id']);
|
||||
$beneficiary = $accountRepository->createOrFindBeneficiary($data['beneficiary']);
|
||||
$journal->transactions[0]->account()->associate($beneficiary);
|
||||
$journal->transactions[1]->account()->associate($account);
|
||||
@@ -455,6 +474,7 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
// 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 */
|
||||
@@ -476,8 +496,8 @@ class EloquentTransactionJournalRepository implements TransactionJournalReposito
|
||||
}
|
||||
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'
|
||||
'warning', 'Piggy bank "' . e($piggyBank->name)
|
||||
. '" is not set to draw money from any of the accounts in this transfer'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ interface TransactionJournalRepositoryInterface
|
||||
* @param \Account $toAccount
|
||||
* @param $description
|
||||
* @param $amount
|
||||
* @param Carbon $date
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -27,6 +27,12 @@ interface TransactionJournalRepositoryInterface
|
||||
*/
|
||||
public function get();
|
||||
|
||||
/**
|
||||
* @param \User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function overruleUser(\User $user);
|
||||
|
||||
/**
|
||||
* @param $what
|
||||
* @param $data
|
||||
@@ -52,9 +58,9 @@ interface TransactionJournalRepositoryInterface
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
* @param int $count
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $count
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -62,7 +68,7 @@ interface TransactionJournalRepositoryInterface
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
* @param Carbon $date
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
|
@@ -60,10 +60,10 @@ class EloquentUserRepository implements UserRepositoryInterface
|
||||
*/
|
||||
public function register($array)
|
||||
{
|
||||
$user = new \User;
|
||||
$user->email = isset($array['email']) ? $array['email'] : null;
|
||||
$user = new \User;
|
||||
$user->email = isset($array['email']) ? $array['email'] : null;
|
||||
$user->migrated = 0;
|
||||
$user->reset = \Str::random(32);
|
||||
$user->reset = \Str::random(32);
|
||||
$user->password = \Hash::make(\Str::random(12));
|
||||
|
||||
if (!$user->save()) {
|
||||
|
96
app/lib/Firefly/Trigger/Journals/EloquentJournalTrigger.php
Normal file
96
app/lib/Firefly/Trigger/Journals/EloquentJournalTrigger.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Firefly\Trigger\Journals;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Events\Dispatcher;
|
||||
|
||||
/**
|
||||
* Class EloquentJournalTrigger
|
||||
*
|
||||
* @package Firefly\Trigger\Journals
|
||||
*/
|
||||
class EloquentJournalTrigger
|
||||
{
|
||||
|
||||
/**
|
||||
* @param \TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function store(\TransactionJournal $journal)
|
||||
{
|
||||
// select all reminders for recurring transactions:
|
||||
if ($journal->transaction_type->type == 'Withdrawal') {
|
||||
\Log::debug('Trigger on the creation of a withdrawal');
|
||||
$transaction = $journal->transactions()->orderBy('amount', 'DESC')->first();
|
||||
$amount = floatval($transaction->amount);
|
||||
$description = strtolower($journal->description);
|
||||
$beneficiary = strtolower($transaction->account->name);
|
||||
|
||||
// make an array of parts:
|
||||
$parts = explode(' ', $description);
|
||||
$parts[] = $beneficiary;
|
||||
$today = new Carbon;
|
||||
$set = \RecurringTransactionReminder::
|
||||
leftJoin(
|
||||
'recurring_transactions', 'recurring_transactions.id', '=', 'reminders.recurring_transaction_id'
|
||||
)
|
||||
->where('startdate', '<', $today->format('Y-m-d'))
|
||||
->where('enddate', '>', $today->format('Y-m-d'))
|
||||
->where('amount_min', '<=', $amount)
|
||||
->where('amount_max', '>=', $amount)->get(['reminders.*']);
|
||||
/** @var \RecurringTransctionReminder $reminder */
|
||||
\Log::debug('Have these parts to search for: ' . join('/',$parts));
|
||||
\Log::debug('Found ' . count($set).' possible matching recurring transactions');
|
||||
foreach ($set as $index => $reminder) {
|
||||
/** @var \RecurringTransaction $RT */
|
||||
$RT = $reminder->recurring_transaction;
|
||||
$matches = explode(' ', strtolower($RT->match));
|
||||
\Log::debug($index.': ' . join('/',$matches));
|
||||
$matchCount = 0;
|
||||
foreach ($parts as $part) {
|
||||
if (in_array($part, $matches)) {
|
||||
$matchCount++;
|
||||
}
|
||||
}
|
||||
if ($matchCount >= count($matches)) {
|
||||
// we have a match!
|
||||
\Log::debug(
|
||||
'Match between new journal "' . join('/', $parts) . '" and RT ' . join('/', $matches) . '.'
|
||||
);
|
||||
$journal->recurringTransaction()->associate($RT);
|
||||
$journal->save();
|
||||
// also update the reminder.
|
||||
$reminder->active = 0;
|
||||
$reminder->save();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
|
||||
/**
|
||||
* AccountType
|
||||
*
|
||||
|
@@ -33,7 +33,7 @@ class Budget extends Component
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany|\TransactionJournal
|
||||
*/
|
||||
public function transactionjournals()
|
||||
{
|
||||
|
@@ -27,7 +27,7 @@ class Component extends SingleTableInheritanceEntity
|
||||
public static $rules
|
||||
= [
|
||||
'user_id' => 'exists:users,id|required',
|
||||
'name' => 'required|between:1,255',
|
||||
'name' => ['required', 'between:1,100', 'alphabasic'],
|
||||
'class' => 'required',
|
||||
];
|
||||
protected $table = 'components';
|
||||
|
27
app/models/Importentry.php
Normal file
27
app/models/Importentry.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
/**
|
||||
* Importentry
|
||||
*
|
||||
* @property-read \Importmap $importmap
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property string $class
|
||||
* @property integer $importmap_id
|
||||
* @property integer $old
|
||||
* @property integer $new
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importentry whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importentry whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importentry whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importentry whereClass($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importentry whereImportmapId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importentry whereOld($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importentry whereNew($value)
|
||||
*/
|
||||
class Importentry extends Eloquent {
|
||||
public function importmap()
|
||||
{
|
||||
return $this->belongsTo('Importmap');
|
||||
}
|
||||
}
|
29
app/models/Importmap.php
Normal file
29
app/models/Importmap.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
/**
|
||||
* Class Importmap
|
||||
*
|
||||
* @property-read \User $user
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property integer $user_id
|
||||
* @property string $file
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importmap whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importmap whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importmap whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importmap whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Importmap whereFile($value)
|
||||
*/
|
||||
class Importmap extends Eloquent
|
||||
{
|
||||
/**
|
||||
* User
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('User');
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
/**
|
||||
* TransactionCurrency
|
||||
*
|
||||
|
@@ -47,6 +47,54 @@ use LaravelBook\Ardent\Builder;
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Budget[] $budgets
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\
|
||||
* 'Category[] $categories
|
||||
*/
|
||||
class TransactionJournal extends Ardent
|
||||
{
|
||||
@@ -89,6 +137,14 @@ class TransactionJournal extends Ardent
|
||||
return $this->belongsToMany('Component');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function recurringTransaction()
|
||||
{
|
||||
return $this->belongsTo('RecurringTransaction');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -189,7 +245,7 @@ class TransactionJournal extends Ardent
|
||||
$q->orderBy('amount', 'ASC');
|
||||
}, 'transactiontype', 'components' => function ($q) {
|
||||
$q->orderBy('class');
|
||||
}, 'transactions.account.accounttype']
|
||||
}, 'transactions.account.accounttype','recurringTransaction']
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -134,7 +134,7 @@ Route::group(['before' => 'auth'], function () {
|
||||
Route::get('/budgets',['uses' => 'BudgetController@indexByDate','as' => 'budgets.index']);
|
||||
Route::get('/budgets/create',['uses' => 'BudgetController@create', 'as' => 'budgets.create']);
|
||||
Route::get('/budgets/budget',['uses' => 'BudgetController@indexByBudget','as' => 'budgets.index.budget']);
|
||||
Route::get('/budgets/show/{budget}',['uses' => 'BudgetController@show', 'as' => 'budgets.show']);
|
||||
Route::get('/budgets/show/{budget}/{limitrepetition?}',['uses' => 'BudgetController@show', 'as' => 'budgets.show']);
|
||||
Route::get('/budgets/edit/{budget}',['uses' => 'BudgetController@edit', 'as' => 'budgets.edit']);
|
||||
Route::get('/budgets/delete/{budget}',['uses' => 'BudgetController@delete', 'as' => 'budgets.delete']);
|
||||
|
||||
@@ -157,8 +157,6 @@ Route::group(['before' => 'auth'], function () {
|
||||
Route::get('chart/budget/{budget}/session', ['uses' => 'ChartController@budgetSession', 'as' => 'chart.budget.session']);
|
||||
Route::get('chart/budget/envelope/{limitrepetition}', ['uses' => 'ChartController@budgetLimit', 'as' => 'chart.budget.limit']);
|
||||
|
||||
|
||||
|
||||
// home controller
|
||||
Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']);
|
||||
Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']);
|
||||
@@ -172,20 +170,19 @@ Route::group(['before' => 'auth'], function () {
|
||||
Route::get('/budgets/limits/delete/{limit}',['uses' => 'LimitController@delete','as' => 'budgets.limits.delete']);
|
||||
Route::get('/budgets/limits/edit/{limit}',['uses' => 'LimitController@edit','as' => 'budgets.limits.edit']);
|
||||
|
||||
Route::get('/migrate',['uses' => 'MigrateController@index', 'as' => 'migrate.index']);
|
||||
|
||||
// piggy bank controller
|
||||
Route::get('/piggybanks',['uses' => 'PiggybankController@index','as' => 'piggybanks.index']);
|
||||
Route::get('/piggybanks/create/piggybank', ['uses' => 'PiggybankController@createPiggybank','as' => 'piggybanks.create.piggybank']);
|
||||
Route::get('/piggybanks/create/repeated', ['uses' => 'PiggybankController@createRepeated','as' => 'piggybanks.create.repeated']);
|
||||
|
||||
Route::get('/piggybanks/addMoney/{piggybank}', ['uses' => 'PiggybankController@addMoney','as' => 'piggybanks.amount.add']);
|
||||
Route::get('/piggybanks/removeMoney/{piggybank}', ['uses' => 'PiggybankController@removeMoney','as' => 'piggybanks.amount.remove']);
|
||||
|
||||
Route::get('/piggybanks/show/{piggybank}', ['uses' => 'PiggybankController@show','as' => 'piggybanks.show']);
|
||||
Route::get('/piggybanks/edit/{piggybank}', ['uses' => 'PiggybankController@edit','as' => 'piggybanks.edit']);
|
||||
Route::get('/piggybanks/delete/{piggybank}', ['uses' => 'PiggybankController@delete','as' => 'piggybanks.delete']);
|
||||
Route::post('/piggybanks/updateAmount/{piggybank}',['uses' => 'PiggybankController@updateAmount','as' => 'piggybanks.updateAmount']);
|
||||
|
||||
|
||||
// preferences controller
|
||||
Route::get('/preferences', ['uses' => 'PreferencesController@index', 'as' => 'preferences']);
|
||||
|
||||
@@ -247,6 +244,8 @@ Route::group(['before' => 'csrf|auth'], function () {
|
||||
Route::post('/budgets/limits/destroy/{limit}',['uses' => 'LimitController@destroy','as' => 'budgets.limits.destroy']);
|
||||
Route::post('/budgets/limits/update/{limit}',['uses' => 'LimitController@update','as' => 'budgets.limits.update']);
|
||||
|
||||
Route::post('/migrate/upload',['uses' => 'MigrateController@upload', 'as' => 'migrate.upload']);
|
||||
|
||||
|
||||
// piggy bank controller
|
||||
Route::post('/piggybanks/store/piggybank',['uses' => 'PiggybankController@storePiggybank','as' => 'piggybanks.store.piggybank']);
|
||||
|
@@ -1,373 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class AccountTest
|
||||
*
|
||||
* Test EVERYTHING related to accounts. Models, views controllers.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
* @coversDefaultClass \AccountController
|
||||
*/
|
||||
class AccountTest extends TestCase
|
||||
{
|
||||
protected $_repository;
|
||||
protected $_user;
|
||||
protected $_accounts;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_repository = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$this->_accounts = $this->mock('Firefly\Helper\Controllers\AccountInterface');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
|
||||
Mockery::close();
|
||||
}
|
||||
|
||||
public function testAccountModel()
|
||||
{
|
||||
// create account and user:
|
||||
$account = f::create('Account');
|
||||
$user = f::create('User');
|
||||
$user->accounts()->save($account);
|
||||
|
||||
// new account? balance should be 0.00
|
||||
$this->assertEquals(0.0, $account->balance());
|
||||
|
||||
// create and link two transactions / piggybanks:
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$transaction = f::create('Transaction');
|
||||
$transaction->account()->associate($account);
|
||||
$transaction->save();
|
||||
|
||||
$piggy = f::create('Piggybank');
|
||||
$piggy->account()->associate($account);
|
||||
$piggy->save();
|
||||
|
||||
}
|
||||
// test related models
|
||||
$this->assertCount(2, $account->transactions()->get());
|
||||
$this->assertCount(2, $account->piggybanks()->get());
|
||||
|
||||
// predict should always be null:
|
||||
$this->assertNull($account->predict(new Carbon));
|
||||
|
||||
// user should equal test user:
|
||||
$this->assertEquals($user->id, $account->user()->first()->id);
|
||||
|
||||
$this->assertEquals('testing',\App::environment());
|
||||
|
||||
\Log::debug('Hello from test!');
|
||||
\Log::debug('Number of accounts: ' . \Account::count());
|
||||
\Log::debug('Number of account types: ' . \AccountType::count());
|
||||
|
||||
foreach(\AccountType::get() as $t) {
|
||||
\Log::debug('AccountType: #'.$t->id.', ' . $t->type);
|
||||
}
|
||||
|
||||
// whatever the account type of this account, searching for it using the
|
||||
// scope method should return one account:
|
||||
$accountType = $account->accounttype()->first();
|
||||
$accounts = $accountType->accounts()->count();
|
||||
$this->assertCount($accounts, \Account::AccountTypeIn([$accountType->type])->get());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::create
|
||||
*/
|
||||
public function testCreate()
|
||||
{
|
||||
// test the view:
|
||||
View::shouldReceive('make')->once()->with('accounts.create')->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('title', 'Create account');
|
||||
|
||||
// call and final test:
|
||||
$this->action('GET', 'AccountController@create');
|
||||
$this->assertResponseOk();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::delete
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
// some prep work.
|
||||
/** @var \Account $account */
|
||||
$account = f::create('Account');
|
||||
|
||||
/** @var \AccountType $accountType */
|
||||
$accountType = \AccountType::whereType('Default account')->first();
|
||||
$account->accountType()->associate($accountType);
|
||||
$account->save();
|
||||
|
||||
// for successful binding with the account to delete:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
|
||||
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
// test the view:
|
||||
View::shouldReceive('make')->once()->with('accounts.delete')->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('account', m::any())->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('title', 'Delete account "' . $account->name . '"');
|
||||
|
||||
// call and final test:
|
||||
$this->action('GET', 'AccountController@delete', $account->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::destroy
|
||||
*/
|
||||
public function testDestroy()
|
||||
{
|
||||
/** @var \Account $account */
|
||||
$account = f::create('Account');
|
||||
|
||||
/** @var \AccountType $accountType */
|
||||
$accountType = \AccountType::whereType('Default account')->first();
|
||||
$account->accountType()->associate($accountType);
|
||||
$account->save();
|
||||
|
||||
|
||||
// for successful binding with the account to destroy:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
|
||||
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
// test if the repository receives an argument:
|
||||
$this->_repository->shouldReceive('destroy')->once();
|
||||
|
||||
// post it:
|
||||
$this->action('POST', 'AccountController@destroy', $account->id);
|
||||
$this->assertRedirectedToRoute('accounts.index');
|
||||
$this->assertSessionHas('success');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::edit
|
||||
*/
|
||||
public function testEdit()
|
||||
{
|
||||
/** @var \Account $account */
|
||||
$account = f::create('Account');
|
||||
|
||||
/** @var \AccountType $accountType */
|
||||
$accountType = \AccountType::whereType('Default account')->first();
|
||||
$account->accountType()->associate($accountType);
|
||||
$account->save();
|
||||
|
||||
// for successful binding with the account to edit:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
|
||||
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
// test if the repository works:
|
||||
$this->_accounts->shouldReceive('openingBalanceTransaction')->once()->with(m::any())->andReturn(null);
|
||||
|
||||
// test if the view works:
|
||||
View::shouldReceive('make')->once()->with('accounts.edit')->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('account', m::any())->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('openingBalance', null)->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('title', 'Edit account "' . $account->name . '"');
|
||||
|
||||
$this->action('GET', 'AccountController@edit', $account->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::index
|
||||
*/
|
||||
public function testIndex()
|
||||
{
|
||||
// two account types:
|
||||
$personalType = \AccountType::whereType('Default account')->first();
|
||||
$benType = \AccountType::whereType('Beneficiary account')->first();
|
||||
|
||||
// create two accounts:
|
||||
/** @var \Account $account */
|
||||
$personal = f::create('Account');
|
||||
$personal->accountType()->associate($personalType);
|
||||
$personal->save();
|
||||
$ben = f::create('Account');
|
||||
$ben->accountType()->associate($benType);
|
||||
$ben->save();
|
||||
|
||||
/** @var \AccountType $accountType */
|
||||
$collection = new Collection();
|
||||
$collection->add($personal);
|
||||
$collection->add($ben);
|
||||
|
||||
$list = [
|
||||
'personal' => [$personal],
|
||||
'beneficiaries' => [$ben],
|
||||
];
|
||||
|
||||
// test repository:
|
||||
$this->_repository->shouldReceive('get')->once()->andReturn($collection);
|
||||
|
||||
// test view:
|
||||
View::shouldReceive('make')->once()->with('accounts.index')->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('accounts', $list)->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('title', 'All your accounts');
|
||||
|
||||
$this->action('GET', 'AccountController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::show
|
||||
*/
|
||||
public function testShow()
|
||||
{
|
||||
/** @var \Account $account */
|
||||
$account = f::create('Account');
|
||||
|
||||
/** @var \AccountType $accountType */
|
||||
$accountType = \AccountType::whereType('Default account')->first();
|
||||
$account->accountType()->associate($accountType);
|
||||
$account->save();
|
||||
|
||||
// for successful binding with the account to show:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
|
||||
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
// test view:
|
||||
View::shouldReceive('make')->once()->with('accounts.show')->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('account', m::any())->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('show', [])->andReturn(m::self())
|
||||
->shouldReceive('with')->once()->with('title', 'Details for account "' . $account->name . '"');
|
||||
|
||||
$this->_accounts->shouldReceive('show')->once()->andReturn([]);
|
||||
|
||||
|
||||
$this->action('GET', 'AccountController@show', $account->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::store
|
||||
*/
|
||||
public function testStore()
|
||||
{
|
||||
/** @var \Account $account */
|
||||
$account = f::create('Account');
|
||||
|
||||
/** @var \AccountType $accountType */
|
||||
$accountType = \AccountType::whereType('Default account')->first();
|
||||
$account->accountType()->associate($accountType);
|
||||
$account->save();
|
||||
|
||||
$this->_repository->shouldReceive('store')->andReturn($account);
|
||||
$this->action('POST', 'AccountController@store');
|
||||
$this->assertRedirectedToRoute('accounts.index');
|
||||
$this->assertSessionHas('success');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::store
|
||||
*/
|
||||
public function testStoreFails()
|
||||
{
|
||||
/** @var \Account $account */
|
||||
$account = f::create('Account');
|
||||
|
||||
/** @var \AccountType $accountType */
|
||||
$accountType = \AccountType::whereType('Default account')->first();
|
||||
$account->accountType()->associate($accountType);
|
||||
$account->save();
|
||||
|
||||
unset($account->name);
|
||||
$this->_repository->shouldReceive('store')->andReturn($account);
|
||||
$this->action('POST', 'AccountController@store');
|
||||
$this->assertRedirectedToRoute('accounts.create');
|
||||
$this->assertSessionHas('error');
|
||||
}
|
||||
|
||||
public function testStoreRecreate()
|
||||
{
|
||||
/** @var \Account $account */
|
||||
$account = f::create('Account');
|
||||
|
||||
/** @var \AccountType $accountType */
|
||||
$accountType = \AccountType::whereType('Default account')->first();
|
||||
$account->accountType()->associate($accountType);
|
||||
$account->save();
|
||||
|
||||
$this->_repository->shouldReceive('store')->andReturn($account);
|
||||
$this->action('POST', 'AccountController@store', ['create' => '1']);
|
||||
$this->assertRedirectedToRoute('accounts.create');
|
||||
$this->assertSessionHas('success');
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
/** @var \Account $account */
|
||||
$account = f::create('Account');
|
||||
|
||||
/** @var \AccountType $accountType */
|
||||
$accountType = \AccountType::whereType('Default account')->first();
|
||||
$account->accountType()->associate($accountType);
|
||||
$account->save();
|
||||
|
||||
// for successful binding with the account to update:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
|
||||
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
// test
|
||||
$this->_repository->shouldReceive('update')->andReturn($account);
|
||||
|
||||
$this->action('POST', 'AccountController@update', $account->id);
|
||||
$this->assertRedirectedToRoute('accounts.index');
|
||||
$this->assertSessionHas('success');
|
||||
|
||||
}
|
||||
|
||||
public function testUpdateFails()
|
||||
{
|
||||
/** @var \Account $account */
|
||||
$account = f::create('Account');
|
||||
|
||||
/** @var \AccountType $accountType */
|
||||
$accountType = \AccountType::whereType('Default account')->first();
|
||||
$account->accountType()->associate($accountType);
|
||||
$account->save();
|
||||
|
||||
unset($account->name);
|
||||
|
||||
// for successful binding with the account to show:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user)->between(1, 3);
|
||||
Auth::shouldReceive('check')->andReturn(true)->between(1, 2);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($account->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
// test
|
||||
$this->_repository->shouldReceive('update')->andReturn($account);
|
||||
|
||||
$this->action('POST', 'AccountController@update', $account->id);
|
||||
$this->assertRedirectedToRoute('accounts.edit', $account->id);
|
||||
$this->assertSessionHas('error');
|
||||
|
||||
}
|
||||
}
|
@@ -1,274 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class BudgetControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class BudgetControllerTest extends TestCase
|
||||
{
|
||||
protected $_repository;
|
||||
protected $_user;
|
||||
protected $_budgets;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_repository = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
||||
$this->_budgets = $this->mock('Firefly\Helper\Controllers\BudgetInterface');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
Mockery::close();
|
||||
}
|
||||
|
||||
public function testCreate()
|
||||
{
|
||||
$this->action('GET', 'BudgetController@create');
|
||||
$this->assertResponseOk();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
|
||||
$budget = f::create('Budget');
|
||||
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'BudgetController@delete', $budget->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testDestroy()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
Event::shouldReceive('fire')->once()->with('budgets.destroy', [$budget]);
|
||||
$this->_repository->shouldReceive('destroy')->once()->andReturn(true);
|
||||
|
||||
$this->action('POST', 'BudgetController@destroy', $budget->id);
|
||||
$this->assertRedirectedToRoute('budgets.index.budget');
|
||||
$this->assertSessionHas('success');
|
||||
}
|
||||
|
||||
public function testDestroyByDate()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
Event::shouldReceive('fire')->once()->with('budgets.destroy', [$budget]);
|
||||
$this->_repository->shouldReceive('destroy')->once()->andReturn(true);
|
||||
|
||||
$this->action('POST', 'BudgetController@destroy', [$budget->id, 'from' => 'date']);
|
||||
$this->assertRedirectedToRoute('budgets.index');
|
||||
$this->assertSessionHas('success');
|
||||
}
|
||||
|
||||
public function testDestroyFails()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
Event::shouldReceive('fire')->once()->with('budgets.destroy', [$budget]);
|
||||
$this->_repository->shouldReceive('destroy')->once()->andReturn(false);
|
||||
|
||||
|
||||
$this->action('POST', 'BudgetController@destroy', $budget->id);
|
||||
$this->assertRedirectedToRoute('budgets.index');
|
||||
$this->assertSessionHas('error');
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'BudgetController@edit', $budget->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testIndexByBudget()
|
||||
{
|
||||
$this->_repository->shouldReceive('get')->once()->andReturn([]);
|
||||
$this->action('GET', 'BudgetController@indexByBudget');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testIndexByDate()
|
||||
{
|
||||
$collection = new Collection();
|
||||
$this->_repository->shouldReceive('get')->once()->andReturn($collection);
|
||||
$this->_budgets->shouldReceive('organizeByDate')->with($collection)->andReturn([]);
|
||||
$this->action('GET', 'BudgetController@indexByDate');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testShow()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn($budget->email);
|
||||
|
||||
|
||||
$this->session(['start' => new Carbon, 'end' => new Carbon]);
|
||||
|
||||
$this->_budgets->shouldReceive('organizeRepetitions')->once()->andReturn([]);
|
||||
$this->action('GET', 'BudgetController@show', $budget->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testShowNoEnvelope()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn($budget->email);
|
||||
|
||||
|
||||
$this->session(['start' => new Carbon, 'end' => new Carbon]);
|
||||
|
||||
$this->_budgets->shouldReceive('outsideRepetitions')->once()->andReturn([]);
|
||||
$this->action('GET', 'BudgetController@show', [$budget->id, 'noenvelope' => 'true']);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testShowWithRep()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn($budget->email);
|
||||
|
||||
|
||||
$this->session(['start' => new Carbon, 'end' => new Carbon]);
|
||||
|
||||
// $this->_budgets->shouldReceive('show')->once()->andReturn([]);
|
||||
$arr = [0 => ['limitrepetition' => null, 'limit' => null, 'date' => '']];
|
||||
$this->_budgets->shouldReceive('organizeRepetition')->once()->andReturn($arr);
|
||||
$this->action('GET', 'BudgetController@show', [$budget->id, 'rep' => '1']);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testStore()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
$this->_repository->shouldReceive('store')->andReturn($budget);
|
||||
$this->action('POST', 'BudgetController@store');
|
||||
$this->assertRedirectedToRoute('budgets.index.budget');
|
||||
}
|
||||
|
||||
public function testStoreFromDate()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
$this->_repository->shouldReceive('store')->andReturn($budget);
|
||||
$this->action('POST', 'BudgetController@store', ['from' => 'date']);
|
||||
$this->assertRedirectedToRoute('budgets.index');
|
||||
}
|
||||
|
||||
public function testStoreFails()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
unset($budget->name);
|
||||
$this->_repository->shouldReceive('store')->andReturn($budget);
|
||||
$this->action('POST', 'BudgetController@store', ['from' => 'budget']);
|
||||
$this->assertRedirectedToRoute('budgets.create');
|
||||
}
|
||||
|
||||
public function testStoreRecreate()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
$this->_repository->shouldReceive('store')->andReturn($budget);
|
||||
$this->action('POST', 'BudgetController@store', ['from' => 'budget', 'create' => '1']);
|
||||
$this->assertRedirectedToRoute('budgets.create', ['from' => 'budget']);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
$this->_repository->shouldReceive('update')->andReturn($budget);
|
||||
Event::shouldReceive('fire')->with('budgets.update', [$budget]);
|
||||
|
||||
$this->action('POST', 'BudgetController@update', $budget->id);
|
||||
$this->assertRedirectedToRoute('budgets.index.budget');
|
||||
|
||||
}
|
||||
|
||||
public function testUpdateFromDate()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
$this->_repository->shouldReceive('update')->andReturn($budget);
|
||||
Event::shouldReceive('fire')->with('budgets.update', [$budget]);
|
||||
//$this->_user->shouldReceive('budgets')->andReturn([]); // trigger
|
||||
|
||||
$this->action('POST', 'BudgetController@update', [$budget->id, 'from' => 'date']);
|
||||
$this->assertRedirectedToRoute('budgets.index');
|
||||
|
||||
}
|
||||
|
||||
public function testUpdateFails()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
unset($budget->name);
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($budget->user_id);
|
||||
$this->_repository->shouldReceive('update')->andReturn($budget);
|
||||
|
||||
$this->action('POST', 'BudgetController@update', $budget->id);
|
||||
$this->assertRedirectedToRoute('budgets.edit', $budget->id);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,183 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class CategoryControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class CategoryControllerTest extends TestCase
|
||||
{
|
||||
protected $_repository;
|
||||
protected $_user;
|
||||
protected $_category;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_repository = $this->mock('Firefly\Storage\Category\CategoryRepositoryInterface');
|
||||
$this->_category = $this->mock('Firefly\Helper\Controllers\CategoryInterface');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
Mockery::close();
|
||||
}
|
||||
|
||||
public function testCreate()
|
||||
{
|
||||
$this->action('GET', 'CategoryController@create');
|
||||
$this->assertResponseOk();
|
||||
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
|
||||
$category = f::create('Category');
|
||||
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($category->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'CategoryController@delete', $category->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testDestroy()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($category->user_id);
|
||||
$this->_repository->shouldReceive('destroy')->once()->andReturn(true);
|
||||
|
||||
$this->action('POST', 'CategoryController@destroy', $category->id);
|
||||
$this->assertRedirectedToRoute('categories.index');
|
||||
$this->assertSessionHas('success');
|
||||
}
|
||||
|
||||
public function testDestroyFails()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($category->user_id);
|
||||
$this->_repository->shouldReceive('destroy')->once()->andReturn(false);
|
||||
|
||||
$this->action('POST', 'CategoryController@destroy', $category->id);
|
||||
$this->assertRedirectedToRoute('categories.index');
|
||||
$this->assertSessionHas('error');
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($category->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'CategoryController@edit', $category->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
$collection = new Collection();
|
||||
$collection->add($category);
|
||||
|
||||
$this->_repository->shouldReceive('get')->with()->once()->andReturn($collection);
|
||||
$this->action('GET', 'CategoryController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testShow()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($category->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn($category->email);
|
||||
$this->session(['start' => new Carbon, 'end' => new Carbon]);
|
||||
|
||||
|
||||
$this->_category->shouldReceive('journalsInRange')->once()->andReturn([]);
|
||||
$this->action('GET', 'CategoryController@show', $category->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testStore()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
$this->_repository->shouldReceive('store')->andReturn($category);
|
||||
$this->action('POST', 'CategoryController@store');
|
||||
$this->assertRedirectedToRoute('categories.index');
|
||||
}
|
||||
|
||||
public function testStoreFails()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
unset($category->name);
|
||||
$this->_repository->shouldReceive('store')->andReturn($category);
|
||||
$this->action('POST', 'CategoryController@store');
|
||||
$this->assertRedirectedToRoute('categories.create');
|
||||
}
|
||||
|
||||
public function testStoreRecreate()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
$this->_repository->shouldReceive('store')->andReturn($category);
|
||||
$this->action('POST', 'CategoryController@store', ['create' => '1']);
|
||||
$this->assertRedirectedToRoute('categories.create');
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($category->user_id);
|
||||
$this->_repository->shouldReceive('update')->andReturn($category);
|
||||
|
||||
$this->action('POST', 'CategoryController@update', $category->id);
|
||||
$this->assertRedirectedToRoute('categories.index');
|
||||
|
||||
}
|
||||
|
||||
public function testUpdateFails()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
unset($category->name);
|
||||
// for successful binding.
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($category->user_id);
|
||||
$this->_repository->shouldReceive('update')->andReturn($category);
|
||||
|
||||
$this->action('POST', 'CategoryController@update', [$category->id]);
|
||||
$this->assertResponseStatus(302);
|
||||
|
||||
}
|
||||
}
|
@@ -1,138 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
|
||||
/**
|
||||
* Class ChartControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class ChartControllerTest extends TestCase
|
||||
{
|
||||
protected $_user;
|
||||
// protected $_repository;
|
||||
protected $_accounts;
|
||||
protected $_charts;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$this->_charts = $this->mock('Firefly\Helper\Controllers\ChartInterface');
|
||||
// $this->_category = $this->mock('Firefly\Helper\Controllers\CategoryInterface');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
Mockery::close();
|
||||
}
|
||||
|
||||
public function testCategoryShowChart()
|
||||
{
|
||||
$this->session(['start' => new Carbon, 'end' => new Carbon, 'range' => '1M']);
|
||||
$category = f::create('Category');
|
||||
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($category->user_id);
|
||||
|
||||
$this->_charts->shouldReceive('categoryShowChart')->once()->andReturn([]);
|
||||
|
||||
|
||||
$this->action('GET', 'ChartController@categoryShowChart', $category->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testHomeAccount()
|
||||
{
|
||||
$account = f::create('Account');
|
||||
$collection = new Collection();
|
||||
$collection->add($account);
|
||||
$this->session(['start' => new Carbon, 'end' => new Carbon, 'range' => '1M']);
|
||||
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('bla@bla');
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn(1);
|
||||
$this->_accounts->shouldReceive('getByIds')->andReturn($collection);
|
||||
|
||||
$this->_charts->shouldReceive('account')->once()->andReturn([]);
|
||||
|
||||
|
||||
$this->action('GET', 'ChartController@homeAccount');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testHomeAccountInfo()
|
||||
{
|
||||
$account = f::create('Account');
|
||||
$accountType = \AccountType::whereType('Default account')->first();
|
||||
$account->accounttype()->associate($accountType);
|
||||
$account->save();
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($account->user()->first());
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('bla@bla');
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($account->user_id);
|
||||
$this->_accounts->shouldReceive('findByName')->andReturn($account);
|
||||
|
||||
$this->_charts->shouldReceive('accountDailySummary')->once()->andReturn(['rows' => [], 'sum' => 0]);
|
||||
|
||||
$this->call('GET', 'chart/home/info/' . $account->name . '/01/08/2014');
|
||||
$this->assertResponseOk();
|
||||
|
||||
}
|
||||
|
||||
public function testHomeAccountWithAccount()
|
||||
{
|
||||
$account = f::create('Account');
|
||||
$this->session(['start' => new Carbon, 'end' => new Carbon, 'range' => '1M']);
|
||||
|
||||
// for successful binding:
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('bla@bla');
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($account->user_id);
|
||||
|
||||
$this->_charts->shouldReceive('account')->once()->andReturn([]);
|
||||
|
||||
|
||||
$this->action('GET', 'ChartController@homeAccount', $account->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testHomeBudgets()
|
||||
{
|
||||
$date = new Carbon;
|
||||
$this->session(['start' => $date]);
|
||||
$this->_charts->shouldReceive('budgets')->once()->with($date)->andReturn([]);
|
||||
|
||||
$this->action('GET', 'ChartController@homeBudgets');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testHomeCategories()
|
||||
{
|
||||
$start = new Carbon;
|
||||
$end = new Carbon;
|
||||
|
||||
$this->_charts->shouldReceive('categories')->once()->with($start, $end)->andReturn([]);
|
||||
|
||||
$this->session(['start' => $start, 'end' => $end]);
|
||||
$this->action('GET', 'ChartController@homeCategories');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,142 +0,0 @@
|
||||
<?php
|
||||
use Carbon\Carbon as Carbon;
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class HomeControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class HomeControllerTest extends TestCase
|
||||
{
|
||||
protected $_accounts;
|
||||
protected $_repository;
|
||||
protected $_preferences;
|
||||
protected $_journals;
|
||||
protected $_reminders;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_accounts = $this->mock('Firefly\Helper\Controllers\AccountInterface');
|
||||
$this->_repository = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$this->_preferences = $this->mock('Firefly\Helper\Preferences\PreferencesHelperInterface');
|
||||
$this->_journals = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||
$this->_reminders = $this->mock('Firefly\Storage\Reminder\ReminderRepositoryInterface');
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
Mockery::close();
|
||||
}
|
||||
|
||||
public function testFlush()
|
||||
{
|
||||
$this->action('GET', 'HomeController@flush');
|
||||
$this->assertRedirectedToRoute('index');
|
||||
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
// mock preference:
|
||||
$preference = $this->mock('Preference');
|
||||
$preference->shouldReceive('getAttribute')->with('data')->andReturn([]);
|
||||
|
||||
Event::shouldReceive('fire')->with('limits.check');
|
||||
Event::shouldReceive('fire')->with('piggybanks.check');
|
||||
Event::shouldReceive('fire')->with('recurring.check');
|
||||
|
||||
$this->_reminders->shouldReceive('getCurrentRecurringReminders')->once()->andReturn([]);
|
||||
|
||||
// mock accounts:
|
||||
$this->_repository->shouldReceive('count')->once()->andReturn(0);
|
||||
$this->_repository->shouldReceive('getActiveDefault')->once()->andReturn([]);
|
||||
|
||||
// mock preferences:
|
||||
$this->_preferences->shouldReceive('get')->with('frontpageAccounts', [])->andReturn($preference);
|
||||
|
||||
$this->action('GET', 'HomeController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testIndexWithAccount()
|
||||
{
|
||||
$account = f::create('Account');
|
||||
$start = new Carbon;
|
||||
$end = new Carbon;
|
||||
$this->session(['start' => $start, 'end' => $end]);
|
||||
|
||||
|
||||
// mock preference:
|
||||
$preference = $this->mock('Preference');
|
||||
$preference->shouldReceive('getAttribute')->with('data')->andReturn([$account->id]);
|
||||
|
||||
Event::shouldReceive('fire')->with('limits.check');
|
||||
Event::shouldReceive('fire')->with('piggybanks.check');
|
||||
Event::shouldReceive('fire')->with('recurring.check');
|
||||
|
||||
$this->_reminders->shouldReceive('getCurrentRecurringReminders')->once()->andReturn([]);
|
||||
|
||||
|
||||
// mock accounts:
|
||||
$this->_repository->shouldReceive('count')->once()->andReturn(0);
|
||||
$this->_repository->shouldReceive('getByIds')->with([$account->id])->once()->andReturn([$account]);
|
||||
|
||||
// mock preferences:
|
||||
$this->_preferences->shouldReceive('get')->with('frontpageAccounts', [])->andReturn($preference);
|
||||
|
||||
// mock journals:
|
||||
$this->_journals->shouldReceive('getByAccountInDateRange')->once()->with($account, 10, $start, $end)->andReturn(
|
||||
[1, 2]
|
||||
);
|
||||
|
||||
$this->action('GET', 'HomeController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testIndexWithAccounts()
|
||||
{
|
||||
$accountOne = f::create('Account');
|
||||
$accountTwo = f::create('Account');
|
||||
$accounThree = f::create('Account');
|
||||
$set = [$accountOne, $accountTwo, $accounThree];
|
||||
$ids = [$accountOne->id, $accountTwo->id, $accounThree->id];
|
||||
$start = new Carbon;
|
||||
$end = new Carbon;
|
||||
$this->session(['start' => $start, 'end' => $end]);
|
||||
|
||||
|
||||
// mock preference:
|
||||
$preference = $this->mock('Preference');
|
||||
$preference->shouldReceive('getAttribute')->with('data')->andReturn($ids);
|
||||
|
||||
Event::shouldReceive('fire')->with('limits.check');
|
||||
Event::shouldReceive('fire')->with('piggybanks.check');
|
||||
Event::shouldReceive('fire')->with('recurring.check');
|
||||
|
||||
$this->_reminders->shouldReceive('getCurrentRecurringReminders')->once()->andReturn([]);
|
||||
|
||||
|
||||
// mock accounts:
|
||||
$this->_repository->shouldReceive('count')->once()->andReturn(0);
|
||||
$this->_repository->shouldReceive('getByIds')->with($ids)->once()->andReturn(
|
||||
$set
|
||||
);
|
||||
|
||||
// mock preferences:
|
||||
$this->_preferences->shouldReceive('get')->with('frontpageAccounts', [])->andReturn($preference);
|
||||
|
||||
// mock journals:
|
||||
$this->_journals->shouldReceive('getByAccountInDateRange')->andReturn([1, 2]);
|
||||
|
||||
$this->action('GET', 'HomeController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
|
||||
/**
|
||||
* Class JsonControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class JsonControllerTest extends TestCase
|
||||
{
|
||||
protected $_accounts;
|
||||
protected $_categories;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$this->_categories = $this->mock('Firefly\Storage\Category\CategoryRepositoryInterface');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
Mockery::close();
|
||||
}
|
||||
|
||||
public function testBeneficiaries()
|
||||
{
|
||||
$beneficiary = f::create('Account');
|
||||
|
||||
$this->_accounts->shouldReceive('getBeneficiaries')->once()->andReturn([$beneficiary]);
|
||||
$this->action('GET', 'JsonController@beneficiaries');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testCategories()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
$this->_categories->shouldReceive('get')->once()->andReturn([$category]);
|
||||
$this->action('GET', 'JsonController@categories');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
}
|
@@ -1,245 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class LimitControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class LimitControllerTest extends TestCase
|
||||
{
|
||||
|
||||
protected $_budgets;
|
||||
protected $_limits;
|
||||
protected $_user;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
$this->_budgets = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
||||
$this->_limits = $this->mock('Firefly\Storage\Limit\LimitRepositoryInterface');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
Mockery::close();
|
||||
}
|
||||
|
||||
public function testCreate()
|
||||
{
|
||||
$this->_budgets->shouldReceive('getAsSelectList')->andReturn([]);
|
||||
$this->action('GET', 'LimitController@create');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($limit->budget()->first()->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'LimitController@delete', $limit->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testDestroy()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($limit->budget()->first()->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->_limits->shouldReceive('destroy')->once()->andReturn(true);
|
||||
|
||||
$this->action('POST', 'LimitController@destroy', $limit->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testDestroyFails()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($limit->budget()->first()->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->_limits->shouldReceive('destroy')->once()->andReturn(false);
|
||||
|
||||
$this->action('POST', 'LimitController@destroy', $limit->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testDestroyRedirect()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($limit->budget()->first()->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->_limits->shouldReceive('destroy')->once()->andReturn(true);
|
||||
|
||||
$this->action('POST', 'LimitController@destroy', [$limit->id, 'from' => 'date']);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
|
||||
$this->_budgets->shouldReceive('getAsSelectList')->andReturn([]);
|
||||
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($limit->budget()->first()->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'LimitController@edit', $limit->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testStore()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
|
||||
$this->_limits->shouldReceive('store')->once()->andReturn($limit);
|
||||
$this->action('POST', 'LimitController@store');
|
||||
$this->assertRedirectedToRoute('budgets.index.budget');
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testStoreFails()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
$limit = f::create('Limit');
|
||||
$limit->budget()->associate($budget);
|
||||
$limit->save();
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
unset($limit->startdate);
|
||||
unset($limit->component_id);
|
||||
|
||||
|
||||
$this->_limits->shouldReceive('store')->once()->andReturn($limit);
|
||||
$this->action('POST', 'LimitController@store', $budget->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testStoreRedirect()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
$limit = f::create('Limit');
|
||||
$limit->budget()->associate($budget);
|
||||
$limit->save();
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
|
||||
$this->_limits->shouldReceive('store')->once()->andReturn($limit);
|
||||
$this->action('POST', 'LimitController@store', [$budget->id, 'from' => 'date']);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($limit->budget()->first()->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->_limits->shouldReceive('update')->once()->andReturn($limit);
|
||||
|
||||
|
||||
$this->action(
|
||||
'POST', 'LimitController@update',
|
||||
[$limit->id,
|
||||
'date' => '02-02-2012',
|
||||
'period' => 'monthly',
|
||||
'repeats' => 0,
|
||||
'amount' => '0.01'
|
||||
|
||||
]
|
||||
);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testUpdateFails()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($limit->budget()->first()->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
unset($limit->amount);
|
||||
$this->_limits->shouldReceive('update')->once()->andReturn($limit);
|
||||
|
||||
|
||||
$this->action(
|
||||
'POST', 'LimitController@update',
|
||||
$limit->id
|
||||
);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testUpdateRedirect()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$limitrepetition = f::create('LimitRepetition');
|
||||
$limit->limitrepetitions()->save($limitrepetition);
|
||||
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($limit->budget()->first()->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->_limits->shouldReceive('update')->once()->andReturn($limit);
|
||||
|
||||
|
||||
$this->action(
|
||||
'POST', 'LimitController@update',
|
||||
[$limit->id,
|
||||
'date' => '02-02-2012',
|
||||
'period' => 'monthly',
|
||||
'repeats' => 0,
|
||||
'amount' => '0.01',
|
||||
'from' => 'date'
|
||||
|
||||
]
|
||||
);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,440 +0,0 @@
|
||||
<?php
|
||||
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
|
||||
/**
|
||||
* Class PiggybankControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class PiggybankControllerTest extends TestCase
|
||||
{
|
||||
protected $_accounts;
|
||||
protected $_piggybanks;
|
||||
protected $_user;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
$this->_accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$this->_piggybanks = $this->mock('Firefly\Storage\Piggybank\PiggybankRepositoryInterface');
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
m::close();
|
||||
}
|
||||
|
||||
public function testAddMoneyGET()
|
||||
{
|
||||
$piggyBank = f::create('Piggybank');
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn(
|
||||
$piggyBank->account()->first()->user_id
|
||||
);
|
||||
$this->_piggybanks->shouldReceive('leftOnAccount')->andReturn(1);
|
||||
|
||||
$this->action('GET', 'PiggybankController@addMoney', $piggyBank->id);
|
||||
$this->assertResponseOk();
|
||||
|
||||
}
|
||||
|
||||
public function testCreatePiggybank()
|
||||
{
|
||||
$this->_accounts->shouldReceive('getActiveDefaultAsSelectList')->once()->andReturn([]);
|
||||
$this->action('GET', 'PiggybankController@createPiggybank');
|
||||
$this->assertResponseOk();
|
||||
|
||||
}
|
||||
|
||||
public function testCreateRepeated()
|
||||
{
|
||||
$this->_accounts->shouldReceive('getActiveDefaultAsSelectList')->once()->andReturn([]);
|
||||
$this->action('GET', 'PiggybankController@createRepeated');
|
||||
$this->assertResponseOk();
|
||||
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$piggyBank = f::create('Piggybank');
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn(
|
||||
$piggyBank->account()->first()->user_id
|
||||
);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
|
||||
|
||||
|
||||
$this->action('GET', 'PiggybankController@delete', $piggyBank->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testDestroy()
|
||||
{
|
||||
$piggyBank = f::create('Piggybank');
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn(
|
||||
$piggyBank->account()->first()->user_id
|
||||
);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
$this->_piggybanks->shouldReceive('destroy')->andReturn(true);
|
||||
Event::shouldReceive('fire')->with('piggybanks.destroy', [$piggyBank]);
|
||||
|
||||
|
||||
$this->action('POST', 'PiggybankController@destroy', $piggyBank->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$piggyBank = f::create('Piggybank');
|
||||
|
||||
$this->_accounts->shouldReceive('getActiveDefaultAsSelectList')->once()->andReturn([]);
|
||||
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn(
|
||||
$piggyBank->account()->first()->user_id
|
||||
);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
|
||||
|
||||
|
||||
$this->action('GET', 'PiggybankController@edit', $piggyBank->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testEditRepeated()
|
||||
{
|
||||
$piggyBank = f::create('Piggybank');
|
||||
$piggyBank->repeats = 1;
|
||||
$piggyBank->save();
|
||||
|
||||
|
||||
$this->_accounts->shouldReceive('getActiveDefaultAsSelectList')->once()->andReturn([]);
|
||||
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn(
|
||||
$piggyBank->account()->first()->user_id
|
||||
);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'PiggybankController@edit', $piggyBank->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
$aOne = f::create('Account');
|
||||
$aTwo = f::create('Account');
|
||||
|
||||
$one = f::create('Piggybank');
|
||||
$one->account()->associate($aOne);
|
||||
$two = f::create('Piggybank');
|
||||
$two->account()->associate($aOne);
|
||||
$three = f::create('Piggybank');
|
||||
$three->account()->associate($aTwo);
|
||||
$this->_piggybanks->shouldReceive('get')->andReturn([$one, $two, $three]);
|
||||
$this->_piggybanks->shouldReceive('countRepeating')->andReturn(0);
|
||||
$this->_piggybanks->shouldReceive('leftOnAccount')->andReturn(0);
|
||||
$this->_piggybanks->shouldReceive('countNonrepeating')->andReturn(0);
|
||||
Event::shouldReceive('fire')->with('piggybanks.change');
|
||||
|
||||
|
||||
$this->action('GET', 'PiggybankController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testModifyMoneyAddPOST()
|
||||
{
|
||||
$piggyBank = f::create('Piggybank');
|
||||
$piggyBank->targetamount = 200;
|
||||
$piggyBank->save();
|
||||
$input = [
|
||||
$piggyBank->id,
|
||||
'amount' => 10.0,
|
||||
'what' => 'add'
|
||||
];
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn(
|
||||
$piggyBank->account()->first()->user_id
|
||||
);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
Event::shouldReceive('fire'); //->with('piggybanks.modifyAmountAdd', [$piggyBank, 10.0]);
|
||||
$this->_piggybanks->shouldReceive('modifyAmount')->once();
|
||||
|
||||
$this->_piggybanks->shouldReceive('leftOnAccount')->once()->andReturn(200);
|
||||
|
||||
|
||||
$this->action('POST', 'PiggybankController@modMoney', $input);
|
||||
$this->assertSessionHas('success');
|
||||
$this->assertResponseStatus(302);
|
||||
|
||||
}
|
||||
|
||||
public function testModifyMoneyAddPOSTFails()
|
||||
{
|
||||
$piggyBank = f::create('Piggybank');
|
||||
$piggyBank->targetamount = 200;
|
||||
$piggyBank->save();
|
||||
$input = [
|
||||
$piggyBank->id,
|
||||
'amount' => 10.0,
|
||||
'what' => 'add'
|
||||
];
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($piggyBank->account()->first()->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
Event::shouldReceive('fire')->with('piggybanks.modifyAmountAdd', [$piggyBank, -10.0]);
|
||||
$this->_piggybanks->shouldReceive('leftOnAccount')->once()->andReturn(5);
|
||||
|
||||
|
||||
$this->action('POST', 'PiggybankController@modMoney', $input);
|
||||
$this->assertSessionHas('warning');
|
||||
$this->assertResponseStatus(302);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Firefly\Exception\FireflyException
|
||||
*/
|
||||
public function testModifyMoneyPOSTException()
|
||||
{
|
||||
$piggyBank = f::create('Piggybank');
|
||||
$piggyBank->targetamount = 200;
|
||||
$piggyBank->save();
|
||||
$input = [
|
||||
$piggyBank->id,
|
||||
'amount' => 10.0,
|
||||
'what' => 'yomoma'
|
||||
];
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($piggyBank->account()->first()->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
|
||||
$this->action('POST', 'PiggybankController@modMoney', $input);
|
||||
$this->assertSessionHas('warning');
|
||||
$this->assertResponseStatus(302);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testModifyMoneyRemovePOST()
|
||||
{
|
||||
$pig = $this->mock('Piggybank');
|
||||
$piggybank = f::create('Piggybank');
|
||||
$rep = f::create('PiggybankRepetition');
|
||||
$rep->piggybank_id = $piggybank->id;
|
||||
$rep->save();
|
||||
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn(
|
||||
$rep->piggybank()->first()->account()->first()->user_id
|
||||
);
|
||||
$pig->shouldReceive('currentRelevantRep')->andReturn($rep);
|
||||
$this->_piggybanks->shouldReceive('leftOnAccount')->andReturn(11);
|
||||
$this->_piggybanks->shouldReceive('modifyAmount')->once();
|
||||
|
||||
$input = [
|
||||
$rep->piggybank()->first()->id,
|
||||
'amount' => 10.0,
|
||||
'what' => 'remove'
|
||||
];
|
||||
|
||||
$this->action('POST', 'PiggybankController@modMoney', $input);
|
||||
$this->assertSessionHas('success');
|
||||
$this->assertResponseStatus(302);
|
||||
|
||||
}
|
||||
|
||||
public function testModifyMoneyRemovePOSTFails()
|
||||
{
|
||||
$pig = $this->mock('Piggybank');
|
||||
$piggybank = f::create('Piggybank');
|
||||
$rep = f::create('PiggybankRepetition');
|
||||
$rep->piggybank_id = $piggybank->id;
|
||||
$rep->currentAmount = 5;
|
||||
$rep->save();
|
||||
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn(
|
||||
$rep->piggybank()->first()->account()->first()->user_id
|
||||
);
|
||||
$pig->shouldReceive('currentRelevantRep')->andReturn($rep);
|
||||
|
||||
$input = [
|
||||
$rep->piggybank()->first()->id,
|
||||
'amount' => 10.0,
|
||||
'what' => 'remove'
|
||||
];
|
||||
|
||||
$this->action('POST', 'PiggybankController@modMoney', $input);
|
||||
$this->assertSessionHas('warning');
|
||||
$this->assertResponseStatus(302);
|
||||
|
||||
}
|
||||
|
||||
public function testRemoveMoneyGET()
|
||||
{
|
||||
$pig = $this->mock('Piggybank');
|
||||
$piggybank = f::create('Piggybank');
|
||||
$rep = f::create('PiggybankRepetition');
|
||||
$rep->piggybank_id = $piggybank->id;
|
||||
$rep->save();
|
||||
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn(
|
||||
$rep->piggybank()->first()->account()->first()->user_id
|
||||
);
|
||||
$pig->shouldReceive('currentRelevantRep')->andReturn($rep);
|
||||
|
||||
$this->_piggybanks->shouldReceive('leftOnAccount')->andReturn(1)->once();
|
||||
|
||||
$this->action('GET', 'PiggybankController@removeMoney', $piggybank->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testShow()
|
||||
{
|
||||
$pig = $this->mock('Piggybank');
|
||||
$piggybank = f::create('Piggybank');
|
||||
$rep = f::create('PiggybankRepetition');
|
||||
$rep->piggybank_id = $piggybank->id;
|
||||
$rep->save();
|
||||
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn(
|
||||
$piggybank->account()->first()->user_id
|
||||
);
|
||||
$this->_user->shouldReceive('getAttribute')->andReturn('some@email');
|
||||
|
||||
$pig->shouldReceive('currentRelevantRep')->andReturn($rep);
|
||||
|
||||
// repos:
|
||||
$this->_piggybanks->shouldReceive('leftOnAccount');
|
||||
|
||||
$this->action('GET', 'PiggybankController@show', $piggybank->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testStoreRepeated()
|
||||
{
|
||||
$piggy = f::create('Piggybank');
|
||||
$piggy->repeats = 1;
|
||||
$piggy->save();
|
||||
Event::shouldReceive('fire')->with('piggybanks.store', [$piggy])->once();
|
||||
$this->_piggybanks->shouldReceive('store')->once()->andReturn($piggy);
|
||||
$this->action('POST', 'PiggybankController@storeRepeated');
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testStoreRepeatedFails()
|
||||
{
|
||||
$piggy = f::create('Piggybank');
|
||||
unset($piggy->id);
|
||||
$this->_piggybanks->shouldReceive('store')->once()->andReturn($piggy);
|
||||
$this->action('POST', 'PiggybankController@storeRepeated');
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$piggyBank = f::create('Piggybank');
|
||||
|
||||
$this->_piggybanks->shouldReceive('update')->andReturn($piggyBank);
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn(
|
||||
$piggyBank->account()->first()->user_id
|
||||
);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
Event::shouldReceive('fire')->with('piggybanks.update', [$piggyBank]);
|
||||
|
||||
$this->action('POST', 'PiggybankController@update', $piggyBank->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testUpdateFails()
|
||||
{
|
||||
$piggyBank = f::create('Piggybank');
|
||||
unset($piggyBank->name);
|
||||
|
||||
$this->_piggybanks->shouldReceive('update')->andReturn($piggyBank);
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn(
|
||||
$piggyBank->account()->first()->user_id
|
||||
);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
Event::shouldReceive('fire')->with('piggybanks.change');
|
||||
|
||||
$this->action('POST', 'PiggybankController@update', $piggyBank->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function teststorePiggybank()
|
||||
{
|
||||
$piggy = f::create('Piggybank');
|
||||
$piggy->repeats = 0;
|
||||
$piggy->save();
|
||||
Event::shouldReceive('fire')->with('piggybanks.store', [$piggy])->once();
|
||||
|
||||
|
||||
$this->_piggybanks->shouldReceive('store')->once()->andReturn($piggy);
|
||||
$this->action('POST', 'PiggybankController@storePiggybank');
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function teststorePiggybankFails()
|
||||
{
|
||||
$piggy = f::create('Piggybank');
|
||||
unset($piggy->id);
|
||||
$this->_piggybanks->shouldReceive('store')->once()->andReturn($piggy);
|
||||
$this->action('POST', 'PiggybankController@storePiggybank');
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class PreferencesControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class PreferencesControllerTest extends TestCase
|
||||
{
|
||||
|
||||
protected $_user;
|
||||
protected $_helper;
|
||||
protected $_accounts;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
$this->_helper = $this->mock('Firefly\Helper\Preferences\PreferencesHelperInterface');
|
||||
$this->_accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
m::close();
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
$viewRange = $this->mock('Preference');
|
||||
$viewRange->shouldReceive('getAttribute')->with('data')->andReturn('1M');
|
||||
|
||||
$this->_accounts->shouldReceive('getDefault')->andReturn([]);
|
||||
$this->_helper->shouldReceive('get')->with('viewRange', '1M')->andReturn($viewRange);
|
||||
$this->_helper->shouldReceive('get')->with('frontpageAccounts', [])->andReturn([]);
|
||||
|
||||
|
||||
$this->action('GET', 'PreferencesController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostIndex()
|
||||
{
|
||||
$this->_helper->shouldReceive('set')->with('frontpageAccounts', [1]);
|
||||
$this->_helper->shouldReceive('set')->with('viewRange', '1M');
|
||||
$this->action('POST', 'PreferencesController@postIndex', ['frontpageAccounts' => [1], 'viewRange' => '1M']);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
}
|
@@ -1,135 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class ProfileControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class ProfileControllerTest extends TestCase
|
||||
{
|
||||
protected $_user;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
m::close();
|
||||
}
|
||||
|
||||
|
||||
public function testChangePassword()
|
||||
{
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($this->_user->id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'ProfileController@changePassword');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($this->_user->id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'ProfileController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostChangePasswordDifferentNew()
|
||||
{
|
||||
$user = f::create('User');
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($user->id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn($user->email);
|
||||
$this->_user->shouldReceive('getAttribute')->with('password')->andReturn($user->password);
|
||||
|
||||
$this->action(
|
||||
'POST', 'ProfileController@postChangePassword',
|
||||
['old' => 'sander', 'new1' => 'sander1', 'new2' => 'sander2']
|
||||
);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostChangePasswordOK()
|
||||
{
|
||||
$user = f::create('User');
|
||||
$user->password = 'sander';
|
||||
$user->save();
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($user->id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn($user->email);
|
||||
$this->_user->shouldReceive('getAttribute')->with('password')->andReturn($user->password);
|
||||
|
||||
$this->action(
|
||||
'POST', 'ProfileController@postChangePassword',
|
||||
['old' => 'sander', 'new1' => 'sander2', 'new2' => 'sander2']
|
||||
);
|
||||
$this->assertSessionHas('success');
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
|
||||
public function testPostChangePasswordNoCurrent()
|
||||
{
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($this->_user->id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
$this->_user->shouldReceive('getAttribute')->with('password')->andReturn('Blablabla');
|
||||
|
||||
$this->action('POST', 'ProfileController@postChangePassword', ['old' => '']);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostChangePasswordNoMatchNew()
|
||||
{
|
||||
$user = f::create('User');
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($user->id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn($user->email);
|
||||
$this->_user->shouldReceive('getAttribute')->with('password')->andReturn($user->password);
|
||||
|
||||
$this->action(
|
||||
'POST', 'ProfileController@postChangePassword', ['old' => 'sander', 'new1' => 'sander', 'new2' => 'sander']
|
||||
);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostChangePasswordSame()
|
||||
{
|
||||
$user = f::create('User');
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($user->id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn($user->email);
|
||||
$this->_user->shouldReceive('getAttribute')->with('password')->andReturn($user->password);
|
||||
|
||||
$this->action('POST', 'ProfileController@postChangePassword', ['old' => 'sander']);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
}
|
@@ -1,178 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class RecurringControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class RecurringControllerTest extends TestCase
|
||||
{
|
||||
protected $_user;
|
||||
protected $_repository;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
$this->_repository = $this->mock(
|
||||
'Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
m::close();
|
||||
}
|
||||
|
||||
public function testCreate()
|
||||
{
|
||||
$this->action('GET', 'RecurringController@create');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$recurringTransaction = f::create('RecurringTransaction');
|
||||
|
||||
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($recurringTransaction->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
|
||||
|
||||
|
||||
$this->action('GET', 'RecurringController@delete', $recurringTransaction->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testDestroy()
|
||||
{
|
||||
$recurringTransaction = f::create('RecurringTransaction');
|
||||
|
||||
Event::shouldReceive('fire')->with('recurring.destroy',m::any());
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($recurringTransaction->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
$this->_repository->shouldReceive('destroy')->andReturn(true);
|
||||
|
||||
$this->action('POST', 'RecurringController@destroy', $recurringTransaction->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testDestroyFails()
|
||||
{
|
||||
$recurringTransaction = f::create('RecurringTransaction');
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
Event::shouldReceive('fire')->with('recurring.destroy',m::any());
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($recurringTransaction->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
$this->_repository->shouldReceive('destroy')->andReturn(false);
|
||||
|
||||
$this->action('POST', 'RecurringController@destroy', $recurringTransaction->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$recurringTransaction = f::create('RecurringTransaction');
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($recurringTransaction->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->once()->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'RecurringController@edit', $recurringTransaction->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
|
||||
$this->_repository->shouldReceive('get')->andReturn([]);
|
||||
|
||||
$this->action('GET', 'RecurringController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testShow()
|
||||
{
|
||||
$recurringTransaction = f::create('RecurringTransaction');
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($recurringTransaction->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
|
||||
$this->action('GET', 'RecurringController@show', $recurringTransaction->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testStore()
|
||||
{
|
||||
$recurringTransaction = f::create('RecurringTransaction');
|
||||
|
||||
Event::shouldReceive('fire')->with('recurring.store',m::any());
|
||||
|
||||
$this->_repository->shouldReceive('store')->andReturn($recurringTransaction);
|
||||
$this->action('POST', 'RecurringController@store');
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testStoreRedirect()
|
||||
{
|
||||
$recurringTransaction = f::create('RecurringTransaction');
|
||||
|
||||
Event::shouldReceive('fire')->with('recurring.store',m::any());
|
||||
|
||||
$this->_repository->shouldReceive('store')->andReturn($recurringTransaction);
|
||||
$this->action('POST', 'RecurringController@store', ['create' => '1']);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testStoreFails()
|
||||
{
|
||||
$recurringTransaction = f::create('RecurringTransaction');
|
||||
unset($recurringTransaction->active);
|
||||
unset($recurringTransaction->automatch);
|
||||
|
||||
$this->_repository->shouldReceive('store')->andReturn($recurringTransaction);
|
||||
$this->action('POST', 'RecurringController@store', ['create' => '1']);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$recurringTransaction = f::create('RecurringTransaction');
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->andReturn($recurringTransaction->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
Event::shouldReceive('fire')->with('recurring.update',m::any());
|
||||
|
||||
$this->_repository->shouldReceive('update')->andReturn($recurringTransaction);
|
||||
|
||||
|
||||
$this->action('POST', 'RecurringController@update', $recurringTransaction->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class ReportControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class ReportControllerTest extends TestCase
|
||||
{
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
m::close();
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
$this->action('GET', 'ReportController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class SearchControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class SearchControllerTest extends TestCase
|
||||
{
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
m::close();
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
$this->action('GET', 'SearchController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
}
|
@@ -1,312 +0,0 @@
|
||||
<?php
|
||||
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* Class TransactionControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class TransactionControllerTest extends TestCase
|
||||
{
|
||||
protected $_user;
|
||||
protected $_repository;
|
||||
|
||||
protected $_accounts;
|
||||
protected $_budgets;
|
||||
protected $_piggies;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
$this->_repository = $this->mock('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface');
|
||||
$this->_accounts = $this->mock('Firefly\Storage\Account\AccountRepositoryInterface');
|
||||
$this->_budgets = $this->mock('Firefly\Storage\Budget\BudgetRepositoryInterface');
|
||||
$this->_piggies = $this->mock('Firefly\Storage\Piggybank\PiggybankRepositoryInterface');
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
m::close();
|
||||
}
|
||||
|
||||
public function testCreateDeposit()
|
||||
{
|
||||
$this->_accounts->shouldReceive('getActiveDefaultAsSelectList')->andReturn([]);
|
||||
$this->_budgets->shouldReceive('getAsSelectList')->andReturn([]);
|
||||
$this->_piggies->shouldReceive('get')->andReturn([]);
|
||||
|
||||
$this->action('GET', 'TransactionController@create', ['what' => 'deposit']);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testCreateTransfer()
|
||||
{
|
||||
$this->_accounts->shouldReceive('getActiveDefaultAsSelectList')->andReturn([]);
|
||||
$this->_budgets->shouldReceive('getAsSelectList')->andReturn([]);
|
||||
$this->_piggies->shouldReceive('get')->andReturn([]);
|
||||
$this->action('GET', 'TransactionController@create', ['what' => 'transfer']);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testCreateWithdrawal()
|
||||
{
|
||||
$this->_accounts->shouldReceive('getActiveDefaultAsSelectList')->andReturn([]);
|
||||
$this->_budgets->shouldReceive('getAsSelectList')->andReturn([]);
|
||||
$this->_piggies->shouldReceive('get')->andReturn([]);
|
||||
$this->action('GET', 'TransactionController@create', ['what' => 'withdrawal']);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($journal->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'TransactionController@delete', $journal->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testDestroy()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($journal->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->action('POST', 'TransactionController@destroy', $journal->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testEdit()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
$type = f::create('TransactionType');
|
||||
$type->type = 'Withdrawal';
|
||||
$type->save();
|
||||
$journal->transactiontype()->associate($type);
|
||||
$journal->save();
|
||||
|
||||
$category = f::create('Category');
|
||||
$journal->categories()->save($category);
|
||||
|
||||
$budget = f::create('Budget');
|
||||
$journal->budgets()->save($budget);
|
||||
|
||||
$one = f::create('Transaction');
|
||||
$two = f::create('Transaction');
|
||||
$one->transactionjournal()->associate($journal);
|
||||
$two->transactionjournal()->associate($journal);
|
||||
$one->save();
|
||||
$two->save();
|
||||
|
||||
$this->_accounts->shouldReceive('getActiveDefaultAsSelectList')->andReturn([]);
|
||||
$this->_budgets->shouldReceive('getAsSelectList')->andReturn([]);
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($journal->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->_piggies->shouldReceive('get')->once()->andReturn([]);
|
||||
|
||||
$this->action('GET', 'TransactionController@edit', $journal->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testEditDeposit()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
$type = f::create('TransactionType');
|
||||
$type->type = 'Deposit';
|
||||
$type->save();
|
||||
$journal->transactiontype()->associate($type);
|
||||
$journal->save();
|
||||
|
||||
$category = f::create('Category');
|
||||
$journal->categories()->save($category);
|
||||
|
||||
$budget = f::create('Budget');
|
||||
$journal->budgets()->save($budget);
|
||||
|
||||
$one = f::create('Transaction');
|
||||
$two = f::create('Transaction');
|
||||
$one->transactionjournal()->associate($journal);
|
||||
$two->transactionjournal()->associate($journal);
|
||||
$one->save();
|
||||
$two->save();
|
||||
|
||||
$this->_accounts->shouldReceive('getActiveDefaultAsSelectList')->andReturn([]);
|
||||
$this->_budgets->shouldReceive('getAsSelectList')->andReturn([]);
|
||||
|
||||
$this->_piggies->shouldReceive('get')->once()->andReturn([]);
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($journal->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'TransactionController@edit', $journal->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testEditTransfer()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
$type = f::create('TransactionType');
|
||||
$type->type = 'Transfer';
|
||||
$type->save();
|
||||
$journal->transactiontype()->associate($type);
|
||||
$journal->save();
|
||||
|
||||
$category = f::create('Category');
|
||||
$journal->categories()->save($category);
|
||||
|
||||
$budget = f::create('Budget');
|
||||
$journal->budgets()->save($budget);
|
||||
|
||||
$one = f::create('Transaction');
|
||||
$two = f::create('Transaction');
|
||||
$one->transactionjournal()->associate($journal);
|
||||
$two->transactionjournal()->associate($journal);
|
||||
$one->save();
|
||||
$two->save();
|
||||
|
||||
$this->_accounts->shouldReceive('getActiveDefaultAsSelectList')->andReturn([]);
|
||||
$this->_budgets->shouldReceive('getAsSelectList')->andReturn([]);
|
||||
$this->_piggies->shouldReceive('get')->once()->andReturn([]);
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($journal->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'TransactionController@edit', $journal->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
|
||||
$journal = f::create('TransactionJournal');
|
||||
$type = f::create('TransactionType');
|
||||
$type->type = 'Withdrawal';
|
||||
$type->save();
|
||||
$journal->transactiontype()->associate($type);
|
||||
$journal->save();
|
||||
|
||||
$one = f::create('Transaction');
|
||||
$two = f::create('Transaction');
|
||||
$one->transactionjournal()->associate($journal);
|
||||
$two->transactionjournal()->associate($journal);
|
||||
$one->save();
|
||||
$two->save();
|
||||
|
||||
// make a paginator
|
||||
$paginator = Paginator::make([$journal], 1, 1);
|
||||
|
||||
|
||||
$this->_repository->shouldReceive('paginate')->with(25)->andReturn($paginator);
|
||||
$this->_repository->shouldReceive('get')->andReturn([]);
|
||||
$this->action('GET', 'TransactionController@index');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testShow()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($journal->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->action('GET', 'TransactionController@show', $journal->id);
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testStore()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
|
||||
$this->_repository->shouldReceive('store')->andReturn($journal);
|
||||
|
||||
$this->action('POST', 'TransactionController@store', ['what' => 'deposit']);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testStoreFails()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
unset($journal->description);
|
||||
|
||||
$this->_repository->shouldReceive('store')->andReturn($journal);
|
||||
|
||||
$this->action('POST', 'TransactionController@store', ['what' => 'deposit', 'create' => '1']);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testStoreRedirect()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
|
||||
$this->_repository->shouldReceive('store')->andReturn($journal);
|
||||
|
||||
$this->action('POST', 'TransactionController@store', ['what' => 'deposit', 'create' => '1']);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($journal->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$this->_repository->shouldReceive('update')->andReturn($journal);
|
||||
|
||||
$this->action('POST', 'TransactionController@update', $journal->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testUpdateFailed()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
|
||||
|
||||
// for binding
|
||||
Auth::shouldReceive('user')->andReturn($this->_user);
|
||||
Auth::shouldReceive('check')->andReturn(true);
|
||||
$this->_user->shouldReceive('getAttribute')->with('id')->once()->andReturn($journal->user_id);
|
||||
$this->_user->shouldReceive('getAttribute')->with('email')->andReturn('some@email');
|
||||
|
||||
$journal->description = null;
|
||||
|
||||
$this->_repository->shouldReceive('update')->andReturn($journal);
|
||||
|
||||
$this->action('POST', 'TransactionController@update', $journal->id);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
}
|
@@ -1,167 +0,0 @@
|
||||
<?php
|
||||
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
use Mockery as m;
|
||||
|
||||
|
||||
/**
|
||||
* Class UserControllerTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
* @SuppressWarnings(PHPMD.CamelCasePropertyName)
|
||||
*/
|
||||
class UserControllerTest extends TestCase
|
||||
{
|
||||
protected $_user;
|
||||
protected $_users;
|
||||
protected $_email;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
$this->_user = m::mock('User', 'Eloquent');
|
||||
$this->_users = $this->mock('Firefly\Storage\User\UserRepositoryInterface');
|
||||
$this->_email = $this->mock('Firefly\Helper\Email\EmailHelperInterface');
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
m::close();
|
||||
}
|
||||
|
||||
public function testLogin()
|
||||
{
|
||||
$this->action('GET', 'UserController@login');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testLogout()
|
||||
{
|
||||
$this->action('GET', 'UserController@logout');
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testPostLogin()
|
||||
{
|
||||
$input = [
|
||||
'email' => 'bla@bla',
|
||||
'password' => 'something',
|
||||
];
|
||||
|
||||
Auth::shouldReceive('attempt')->with($input, false)->andReturn(true);
|
||||
|
||||
$this->action('POST', 'UserController@postLogin', $input);
|
||||
$this->assertResponseStatus(302);
|
||||
}
|
||||
|
||||
public function testPostLoginFails()
|
||||
{
|
||||
|
||||
$this->action('POST', 'UserController@postLogin');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostRegister()
|
||||
{
|
||||
Config::set('auth.allow_register', true);
|
||||
$user = f::create('User');
|
||||
$this->_users->shouldReceive('register')->andReturn($user);
|
||||
$this->_email->shouldReceive('sendPasswordMail')->with($user);
|
||||
$this->action('POST', 'UserController@postRegister');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostRegisterFails()
|
||||
{
|
||||
Config::set('auth.allow_register', true);
|
||||
$this->_users->shouldReceive('register')->andReturn(false);
|
||||
$this->action('POST', 'UserController@postRegister');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostRegisterNotAllowed()
|
||||
{
|
||||
Config::set('auth.allow_register', false);
|
||||
$this->action('POST', 'UserController@postRegister');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostRegisterVerify()
|
||||
{
|
||||
Config::set('auth.allow_register', true);
|
||||
Config::set('auth.verify_mail', true);
|
||||
$user = f::create('User');
|
||||
$this->_users->shouldReceive('register')->andReturn($user);
|
||||
$this->_email->shouldReceive('sendVerificationMail')->with($user);
|
||||
$this->action('POST', 'UserController@postRegister');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostRemindme()
|
||||
{
|
||||
$user = f::create('User');
|
||||
Config::set('auth.verify_reset', true);
|
||||
$this->_users->shouldReceive('findByEmail')->andReturn($user);
|
||||
$this->_email->shouldReceive('sendResetVerification');
|
||||
$this->action('POST', 'UserController@postRemindme');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostRemindmeNoVerify()
|
||||
{
|
||||
$user = f::create('User');
|
||||
Config::set('auth.verify_reset', false);
|
||||
$this->_users->shouldReceive('findByEmail')->andReturn($user);
|
||||
$this->_email->shouldReceive('sendPasswordMail');
|
||||
$this->action('POST', 'UserController@postRemindme');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testPostRemindmeFails()
|
||||
{
|
||||
Config::set('auth.verify_reset', true);
|
||||
$this->_users->shouldReceive('findByEmail')->andReturn(false);
|
||||
$this->action('POST', 'UserController@postRemindme');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testRegister()
|
||||
{
|
||||
$this->action('GET', 'UserController@register');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testRegisterNotAllowed()
|
||||
{
|
||||
Config::set('auth.allow_register', false);
|
||||
$this->action('GET', 'UserController@register');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testRemindme()
|
||||
{
|
||||
$this->action('GET', 'UserController@remindme');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$user = f::create('User');
|
||||
|
||||
$this->_users->shouldReceive('findByReset')->andReturn($user);
|
||||
$this->_email->shouldReceive('sendPasswordMail');
|
||||
$this->action('GET', 'UserController@reset');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
|
||||
public function testResetNoUser()
|
||||
{
|
||||
$this->_users->shouldReceive('findByReset')->andReturn(false);
|
||||
$this->action('GET', 'UserController@reset');
|
||||
$this->assertResponseOk();
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'Account',
|
||||
[
|
||||
'user_id' => 'factory|User',
|
||||
'account_type_id' => 'factory|AccountType',
|
||||
'name' => 'word',
|
||||
'active' => 'boolean'
|
||||
]
|
||||
);
|
@@ -1,10 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'AccountType',
|
||||
[
|
||||
'type' => 'unique:word',
|
||||
'editable' => 1
|
||||
]
|
||||
);
|
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'Budget',
|
||||
[
|
||||
'name' => 'word',
|
||||
'user_id' => 'factory|User',
|
||||
'class' => 'Budget'
|
||||
]
|
||||
);
|
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'Category',
|
||||
[
|
||||
'name' => 'word',
|
||||
'user_id' => 'factory|User',
|
||||
'class' => 'Category'
|
||||
]
|
||||
);
|
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'Component',
|
||||
[
|
||||
'name' => 'word',
|
||||
'user_id' => 'factory|User',
|
||||
'class' => 'Component'
|
||||
]
|
||||
);
|
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'Limit',
|
||||
[
|
||||
|
||||
'component_id' => 'factory|Budget',
|
||||
'startdate' => function () {
|
||||
$start = new Carbon;
|
||||
$start->startOfMonth();
|
||||
|
||||
return $start;
|
||||
},
|
||||
'amount' => 100,
|
||||
'repeats' => 'boolean',
|
||||
'repeat_freq' => function () {
|
||||
$frequencies = ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'];
|
||||
|
||||
return $frequencies[rand(0, 5)];
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
);
|
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'LimitRepetition',
|
||||
[
|
||||
|
||||
'limit_id' => 'factory|Limit',
|
||||
'startdate' => function () {
|
||||
$start = new Carbon;
|
||||
$start->startOfMonth();
|
||||
|
||||
return $start;
|
||||
|
||||
},
|
||||
'enddate' => function () {
|
||||
$end = new Carbon;
|
||||
$end->endOfMonth();
|
||||
|
||||
return $end;
|
||||
|
||||
},
|
||||
'amount' => 100
|
||||
|
||||
|
||||
]
|
||||
);
|
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'Piggybank',
|
||||
[
|
||||
|
||||
'account_id' => 'factory|Account',
|
||||
'name' => 'word',
|
||||
'targetamount' => 'integer',
|
||||
'startdate' => function () {
|
||||
$start = new Carbon;
|
||||
$start->startOfMonth();
|
||||
|
||||
return $start;
|
||||
},
|
||||
'targetdate' => function () {
|
||||
$end = new Carbon;
|
||||
$end->endOfMonth();
|
||||
|
||||
return $end;
|
||||
},
|
||||
'repeats' => 0,
|
||||
'rep_length' => null,
|
||||
'rep_times' => 0,
|
||||
'rep_every' => 0,
|
||||
'reminder' => null,
|
||||
'reminder_skip' => 0,
|
||||
'order' => 1,
|
||||
]
|
||||
);
|
@@ -1,14 +0,0 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'PiggybankEvent',
|
||||
[
|
||||
|
||||
'piggybank_id' => 'factory|Piggybank',
|
||||
'date' => new Carbon,
|
||||
'amount' => 10
|
||||
|
||||
]
|
||||
);
|
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'PiggybankRepetition',
|
||||
[
|
||||
|
||||
|
||||
'piggybank_id' => 'factory|Piggybank',
|
||||
'startdate' => function () {
|
||||
$start = new Carbon;
|
||||
$start->startOfMonth();
|
||||
|
||||
return $start;
|
||||
},
|
||||
'targetdate' => function () {
|
||||
$end = new Carbon;
|
||||
$end->endOfMonth();
|
||||
|
||||
return $end;
|
||||
},
|
||||
'currentamount' => 200
|
||||
]
|
||||
);
|
@@ -1,12 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'Preference',
|
||||
[
|
||||
|
||||
'user_id' => 'factory|User',
|
||||
'name' => 'word',
|
||||
'data' => 'word'
|
||||
]
|
||||
);
|
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
// TODO better factory.
|
||||
|
||||
Facade::define(
|
||||
'RecurringTransaction',
|
||||
[
|
||||
|
||||
'user_id' => 'factory|User',
|
||||
'name' => 'string',
|
||||
'match' => 'string',
|
||||
'amount_max' => 100,
|
||||
'amount_min' => 50,
|
||||
'date' => new Carbon,
|
||||
'active' => 'boolean',
|
||||
'automatch' => 'boolean',
|
||||
'repeat_freq' => 'monthly',
|
||||
'skip' => 'boolean',
|
||||
|
||||
]
|
||||
);
|
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'Transaction',
|
||||
[
|
||||
'account_id' => 'factory|Account',
|
||||
'piggybank_id' => null,
|
||||
'transaction_journal_id' => 'factory|TransactionJournal',
|
||||
'description' => 'string',
|
||||
'amount' => 'integer:5',
|
||||
]
|
||||
);
|
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'TransactionCurrency',
|
||||
[
|
||||
'code' => 'EUR'
|
||||
]
|
||||
);
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'TransactionJournal',
|
||||
[
|
||||
'transaction_type_id' => 'factory|TransactionType',
|
||||
'transaction_currency_id' => 'factory|TransactionCurrency',
|
||||
'description' => 'word',
|
||||
'completed' => 'boolean',
|
||||
'user_id' => 'factory|User',
|
||||
'date' => new Carbon
|
||||
]
|
||||
);
|
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'TransactionType',
|
||||
[
|
||||
'type' => function () {
|
||||
$types = ['Withdrawal', 'Deposit', 'Transfer', 'Opening balance'];
|
||||
|
||||
return $types[rand(0, 3)];
|
||||
}
|
||||
]
|
||||
);
|
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
use League\FactoryMuffin\Facade;
|
||||
|
||||
Facade::define(
|
||||
'User',
|
||||
[
|
||||
'email' => 'safeEmail',
|
||||
'password' => function () {
|
||||
return \Str::random(60);
|
||||
},
|
||||
'reset' => function () {
|
||||
return \Str::random(32);
|
||||
},
|
||||
'remember_token' => null,
|
||||
'migrated' => 'boolean'
|
||||
]
|
||||
);
|
@@ -1,417 +0,0 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use League\FactoryMuffin\Facade as f;
|
||||
|
||||
/**
|
||||
* Class ModelTest
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||
*/
|
||||
class ModelTest extends TestCase
|
||||
{
|
||||
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
Artisan::call('migrate');
|
||||
Artisan::call('db:seed');
|
||||
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
Mockery::close();
|
||||
}
|
||||
|
||||
public function testAccount()
|
||||
{
|
||||
$account = f::create('Account');
|
||||
$user = f::create('User');
|
||||
$type = f::create('AccountType');
|
||||
$piggybank = f::create('Piggybank');
|
||||
$account->user()->associate($user);
|
||||
$account->accounttype()->associate($type);
|
||||
$account->piggybanks()->save($piggybank);
|
||||
|
||||
|
||||
$this->assertEquals($account->predict(new Carbon), null);
|
||||
$this->assertEquals($account->balance(new Carbon), null);
|
||||
$this->assertEquals($account->user_id, $user->id);
|
||||
$this->assertEquals($piggybank->account_id, $account->id);
|
||||
$this->assertEquals($account->account_type_id, $type->id);
|
||||
|
||||
}
|
||||
|
||||
public function testAccountType()
|
||||
{
|
||||
$account = f::create('Account');
|
||||
$type = f::create('AccountType');
|
||||
$type->accounts()->save($account);
|
||||
|
||||
$this->assertEquals($account->account_type_id, $type->id);
|
||||
}
|
||||
|
||||
public function testBudget()
|
||||
{
|
||||
$budget = f::create('Budget');
|
||||
$limit = f::create('Limit');
|
||||
$journal = f::create('TransactionJournal');
|
||||
$budget->limits()->save($limit);
|
||||
$budget->transactionjournals()->save($journal);
|
||||
|
||||
$this->assertEquals($limit->component_id, $budget->id);
|
||||
$this->assertEquals($journal->budgets()->first()->id, $budget->id);
|
||||
}
|
||||
|
||||
public function testCategory()
|
||||
{
|
||||
$category = f::create('Category');
|
||||
$journal = f::create('TransactionJournal');
|
||||
$category->transactionjournals()->save($journal);
|
||||
|
||||
$this->assertEquals($journal->categories()->first()->id, $category->id);
|
||||
}
|
||||
|
||||
public function testComponent()
|
||||
{
|
||||
$component = f::create('Component');
|
||||
$limit = f::create('Limit');
|
||||
$component->limits()->save($limit);
|
||||
$component->save();
|
||||
|
||||
$transaction = f::create('Transaction');
|
||||
$journal = f::create('TransactionJournal');
|
||||
$user = f::create('User');
|
||||
|
||||
|
||||
$component->transactions()->save($transaction);
|
||||
$component->transactionjournals()->save($journal);
|
||||
$component->user()->associate($user);
|
||||
|
||||
$this->assertEquals($transaction->components()->first()->id, $component->id);
|
||||
$this->assertEquals($journal->components()->first()->id, $component->id);
|
||||
$this->assertEquals($limit->component()->first()->id, $component->id);
|
||||
$this->assertEquals($component->user_id, $user->id);
|
||||
|
||||
}
|
||||
|
||||
public function testLimit()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$budget = f::create('Budget');
|
||||
$rep = f::create('LimitRepetition');
|
||||
$limit->budget()->associate($budget);
|
||||
$limit->limitrepetitions()->save($rep);
|
||||
$rep->save();
|
||||
$limit->save();
|
||||
|
||||
$this->assertEquals($rep->limit_id, $limit->id);
|
||||
$this->assertEquals($limit->component_id, $budget->id);
|
||||
|
||||
// create repetition:
|
||||
$start = new Carbon;
|
||||
$list = ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'];
|
||||
foreach ($list as $entry) {
|
||||
$limit->repeat_freq = $entry;
|
||||
$limit->createRepetition($start);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @expectedException \Firefly\Exception\FireflyException
|
||||
// */
|
||||
// public function testLimitrepetition()
|
||||
// {
|
||||
// $limit = f::create('Limit');
|
||||
// $rep = f::create('LimitRepetition');
|
||||
// $budget = f::create('Budget');
|
||||
// $journal = f::create('TransactionJournal');
|
||||
// $one = f::create('Transaction');
|
||||
// $two = f::create('Transaction');
|
||||
// $one->amount = 300;
|
||||
// $two->amount = -300;
|
||||
//
|
||||
// $rep->limit()->associate($limit);
|
||||
// $limit->budget()->associate($budget);
|
||||
// $journal->transactions()->save($one);
|
||||
// $journal->transactions()->save($two);
|
||||
// $journal->budgets()->save($budget);
|
||||
//
|
||||
// $this->assertEquals(($rep->amount - 300), $rep->left());
|
||||
//
|
||||
// // repeat frequency (not present) for periodOrder
|
||||
// $testDate = new Carbon;
|
||||
// $testDate->startOfMonth();
|
||||
// $rep->repeat_freq = null;
|
||||
//
|
||||
// // this test will FAIL because nowadays the $rep has a random thing.
|
||||
// // TODO
|
||||
//
|
||||
//
|
||||
// //$this->assertEquals($testDate->format('Ymd') . '-3', $rep->periodOrder());
|
||||
//
|
||||
// // repeat frequency (present) for periodOrder
|
||||
// $list = ['yearly', 'half-year', 'quarterly', 'monthly', 'weekly', 'daily'];
|
||||
// foreach ($list as $index => $entry) {
|
||||
// $rep->repeat_freq = $entry;
|
||||
// $this->assertEquals($testDate->format('Ymd') . '-' . $index, $rep->periodOrder());
|
||||
// }
|
||||
//
|
||||
// // repeat freq (invalid) for periodOrder
|
||||
// $rep->repeat_freq = 'bad';
|
||||
// $rep->periodOrder();
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* @expectedException \Firefly\Exception\FireflyException
|
||||
*/
|
||||
public function testLimitrepetitionContinued()
|
||||
{
|
||||
$limit = f::create('Limit');
|
||||
$rep = f::create('LimitRepetition');
|
||||
$budget = f::create('Budget');
|
||||
$journal = f::create('TransactionJournal');
|
||||
$one = f::create('Transaction');
|
||||
$two = f::create('Transaction');
|
||||
$one->amount = 300;
|
||||
$two->amount = -300;
|
||||
|
||||
$rep->limit()->associate($limit);
|
||||
$limit->budget()->associate($budget);
|
||||
$journal->transactions()->save($one);
|
||||
$journal->transactions()->save($two);
|
||||
$journal->budgets()->save($budget);
|
||||
|
||||
// repeat frequency (not present) for periodShow
|
||||
$testDate = new Carbon;
|
||||
$testDate->startOfMonth();
|
||||
$rep->repeat_freq = null;
|
||||
// TODO cannot test this with the new factories.
|
||||
// $this->assertEquals($testDate->format('F Y'), $rep->periodShow());
|
||||
|
||||
// repeat frequency (present) for periodOrder
|
||||
$list = ['yearly', 'half-year', 'quarterly', 'monthly', 'weekly', 'daily'];
|
||||
foreach ($list as $entry) {
|
||||
$rep->repeat_freq = $entry;
|
||||
$this->assertGreaterThan(0, strlen($rep->periodShow()));
|
||||
}
|
||||
|
||||
// repeat freq (invalid) for periodOrder
|
||||
$rep->repeat_freq = 'bad';
|
||||
$rep->periodShow();
|
||||
}
|
||||
|
||||
public function testPiggybank()
|
||||
{
|
||||
$piggy = f::create('Piggybank');
|
||||
$account = f::create('Account');
|
||||
$piggy->account()->associate($account);
|
||||
$this->assertEquals($account->id, $piggy->account_id);
|
||||
|
||||
$repetition = f::create('PiggybankRepetition');
|
||||
$repetition->piggybank()->associate($piggy);
|
||||
$repetition->save();
|
||||
$list = ['day', 'week', 'month', 'year'];
|
||||
|
||||
// with a start date, so next reminder is built from a loop:
|
||||
foreach ($list as $reminder) {
|
||||
$piggy->reminder = $reminder;
|
||||
$repetition->save();
|
||||
$piggy->nextReminderDate();
|
||||
}
|
||||
// set the reminder period to be invalid, should return NULL
|
||||
$piggy->reminder = 'invalid';
|
||||
$piggy->save();
|
||||
$this->assertNull($piggy->nextReminderDate());
|
||||
|
||||
// set the start date to zero, give a valid $reminder, retry:
|
||||
$repetition->startdate = null;
|
||||
$piggy->reminder = 'month';
|
||||
$repetition->save();
|
||||
foreach ($list as $reminder) {
|
||||
$piggy->reminder = $reminder;
|
||||
$repetition->save();
|
||||
$piggy->nextReminderDate();
|
||||
}
|
||||
// set the reminder to be invalid again:
|
||||
$piggy->reminder = 'invalid';
|
||||
$piggy->save();
|
||||
$piggy->nextReminderDate();
|
||||
|
||||
// set it to be NULL
|
||||
$piggy->reminder = null;
|
||||
$piggy->save();
|
||||
$piggy->nextReminderDate();
|
||||
|
||||
|
||||
// remove the repetition, retry:
|
||||
$piggy->reminder = 'month';
|
||||
$piggy->save();
|
||||
$repetition->delete();
|
||||
$piggy->nextReminderDate();
|
||||
|
||||
$event = f::create('PiggybankEvent');
|
||||
$event->piggybank()->associate($piggy);
|
||||
$event->save();
|
||||
$this->assertEquals($piggy->piggybankevents()->first()->id, $event->id);
|
||||
|
||||
$this->assertNull($piggy->repetitionForDate(new Carbon('2012-02-02')));
|
||||
|
||||
$transaction = f::create('Transaction');
|
||||
$transaction->piggybank()->associate($piggy);
|
||||
$transaction->save();
|
||||
$this->assertEquals($transaction->piggybank_id, $piggy->id);
|
||||
$this->assertEquals($piggy->transactions()->first()->id, $transaction->id);
|
||||
|
||||
$repetition->pct();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testPreference()
|
||||
{
|
||||
$pref = f::create('Preference');
|
||||
$user = f::create('User');
|
||||
$pref->user()->associate($user);
|
||||
$this->assertEquals($pref->user_id, $user->id);
|
||||
$pref->data = 'Hello';
|
||||
$this->assertEquals($pref->data, 'Hello');
|
||||
}
|
||||
|
||||
public function testRecurringtransaction()
|
||||
{
|
||||
$rec = f::create('RecurringTransaction');
|
||||
$user = f::create('User');
|
||||
$rec->user()->associate($user);
|
||||
$this->assertEquals($rec->user_id, $user->id);
|
||||
|
||||
$list = ['yearly', 'half-year', 'quarterly', 'monthly', 'weekly', 'daily'];
|
||||
foreach ($list as $entry) {
|
||||
$start = clone $rec->date;
|
||||
$rec->repeat_freq = $entry;
|
||||
$end = $rec->next();
|
||||
$this->assertTrue($end > $start);
|
||||
}
|
||||
}
|
||||
|
||||
public function testTransaction()
|
||||
{
|
||||
$transaction = f::create('Transaction');
|
||||
$journal = f::create('TransactionJournal');
|
||||
$component = f::create('Component');
|
||||
$budget = f::create('Budget');
|
||||
$category = f::create('Category');
|
||||
$account = f::create('Account');
|
||||
$piggy = f::create('Piggybank');
|
||||
|
||||
$transaction->transactionJournal()->associate($journal);
|
||||
$this->assertEquals($transaction->transaction_journal_id, $journal->id);
|
||||
$transaction->components()->save($component);
|
||||
$this->assertEquals($transaction->components()->first()->id, $component->id);
|
||||
$transaction->budgets()->save($budget);
|
||||
$this->assertEquals($transaction->budgets()->first()->id, $budget->id);
|
||||
$transaction->categories()->save($category);
|
||||
$this->assertEquals($transaction->categories()->first()->id, $category->id);
|
||||
$transaction->account()->associate($account);
|
||||
$this->assertEquals($transaction->account_id, $account->id);
|
||||
$transaction->piggybank()->associate($piggy);
|
||||
$this->assertEquals($transaction->piggybank_id, $piggy->id);
|
||||
}
|
||||
|
||||
public function testTransactionCurrency()
|
||||
{
|
||||
$cur = f::create('TransactionCurrency');
|
||||
$journal = f::create('TransactionJournal');
|
||||
$cur->transactionjournals()->save($journal);
|
||||
$journal->save();
|
||||
$cur->save();
|
||||
$this->assertEquals($cur->id, $journal->transaction_currency_id);
|
||||
}
|
||||
|
||||
public function testTransactionJournal()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
$type = f::create('TransactionType');
|
||||
$user = f::create('User');
|
||||
$cur = f::create('TransactionCurrency');
|
||||
$transaction = f::create('Transaction');
|
||||
$component = f::create('Component');
|
||||
$budget = f::create('Budget');
|
||||
$category = f::create('Category');
|
||||
|
||||
$journal->transactionType()->associate($type);
|
||||
$this->assertEquals($type->id, $journal->transaction_type_id);
|
||||
|
||||
$journal->user()->associate($user);
|
||||
$this->assertEquals($user->id, $journal->user_id);
|
||||
|
||||
$journal->transactionCurrency()->associate($cur);
|
||||
$this->assertEquals($cur->id, $journal->transaction_currency_id);
|
||||
|
||||
$journal->transactions()->save($transaction);
|
||||
$this->assertEquals($journal->transactions()->first()->id, $transaction->id);
|
||||
|
||||
$journal->components()->save($component);
|
||||
$this->assertEquals($journal->components()->first()->id, $component->id);
|
||||
|
||||
$journal->budgets()->save($budget);
|
||||
$this->assertEquals($journal->budgets()->first()->id, $budget->id);
|
||||
|
||||
$journal->categories()->save($category);
|
||||
$this->assertEquals($journal->categories()->first()->id, $category->id);
|
||||
}
|
||||
|
||||
public function testTransactionType()
|
||||
{
|
||||
$journal = f::create('TransactionJournal');
|
||||
$type = f::create('TransactionType');
|
||||
|
||||
$type->transactionjournals()->save($journal);
|
||||
$this->assertEquals($type->transactionJournals()->first()->id, $journal->id);
|
||||
|
||||
}
|
||||
|
||||
public function testUser()
|
||||
{
|
||||
$user = f::create('User');
|
||||
|
||||
$account = f::create('Account');
|
||||
$bud = f::create('Budget');
|
||||
$cat = f::create('Category');
|
||||
$comp = f::create('Component');
|
||||
$pref = f::create('Preference');
|
||||
$rec = f::create('RecurringTransaction');
|
||||
$journal = f::create('TransactionJournal');
|
||||
$piggy = f::create('Piggybank');
|
||||
|
||||
$user->accounts()->save($account);
|
||||
$this->assertEquals($account->id, $user->accounts()->first()->id);
|
||||
|
||||
$user->components()->save($comp);
|
||||
$this->assertEquals($comp->id, $user->components()->first()->id);
|
||||
|
||||
$user->budgets()->save($bud);
|
||||
$this->assertEquals($bud->id, $user->budgets()->first()->id);
|
||||
|
||||
$user->categories()->save($cat);
|
||||
$this->assertEquals($cat->id, $user->categories()->first()->id);
|
||||
|
||||
$user->preferences()->save($pref);
|
||||
$this->assertEquals($pref->id, $user->preferences()->first()->id);
|
||||
|
||||
$user->recurringtransactions()->save($rec);
|
||||
$this->assertEquals($rec->id, $user->recurringtransactions()->first()->id);
|
||||
|
||||
$user->transactionjournals()->save($journal);
|
||||
$this->assertEquals($journal->id, $user->transactionjournals()->first()->id);
|
||||
|
||||
$piggy->account()->associate($account);
|
||||
$piggy->save();
|
||||
$this->assertCount(1, $user->piggybanks()->get());
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -72,21 +72,21 @@
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if(count($show['statistics']['categories']) > 0)
|
||||
@if(isset($show['statistics']['Category']) && count($show['statistics']['Category']) > 0)
|
||||
<tr>
|
||||
<td>Related categories</td>
|
||||
<td>
|
||||
@foreach($show['statistics']['categories'] as $cat)
|
||||
@foreach($show['statistics']['Category'] as $cat)
|
||||
<a href="{{route('categories.show',$cat->id)}}" class="btn btn-default btn-xs">{{{$cat->name}}}</a>
|
||||
@endforeach
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if(count($show['statistics']['budgets']) > 0)
|
||||
@if(isset($show['statistics']['Budget']) && count($show['statistics']['Budget']) > 0)
|
||||
<tr>
|
||||
<td>Related budgets</td>
|
||||
<td>
|
||||
@foreach($show['statistics']['budgets'] as $bud)
|
||||
@foreach($show['statistics']['Budget'] as $bud)
|
||||
<a href="{{route('budgets.show',$bud->id)}}?useSession=true" class="btn btn-default btn-xs">{{{$bud->name}}}</a>
|
||||
@endforeach
|
||||
</td>
|
||||
|
@@ -81,7 +81,7 @@
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<small>
|
||||
<a href="{{route('budgets.show',$budget->id)}}?rep={{$rep->id}}">
|
||||
<a href="{{route('budgets.show',$budget->id,$rep->id)}}">
|
||||
{{$rep->periodShow()}}
|
||||
</a>
|
||||
</small>
|
||||
|
@@ -35,7 +35,7 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<h3><a href="{{route('transactions.index')}}?startdate={{$entry['start']->format('Y-m-d')}}&enddate={{$entry['end']->format('Y-m-d')}}">{{$entry['date']}}</a>
|
||||
<a class="btn btn-default btn-xs" href ="{{route('budgets.limits.create')}}?startdate={{$entry['dateObject']->format('Y-m-d')}}"><span class="glyphicon glyphicon-plus-sign"></span> Create a new envelope for {{$entry['date']}}</a>
|
||||
<a class="btn btn-default btn-xs" href ="{{route('budgets.limits.create')}}?startdate={{$entry['start']->format('Y-m-d')}}"><span class="glyphicon glyphicon-plus-sign"></span> Create a new envelope for {{$entry['date']}}</a>
|
||||
</h3>
|
||||
<table class="table table-bordered table-striped">
|
||||
<tr>
|
||||
@@ -53,7 +53,7 @@
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{route('budgets.show',$repetition->limit->budget->id)}}?rep={{$repetition->id}}">
|
||||
<a href="{{route('budgets.show',[$repetition->limit->budget->id,$repetition->id])}}">
|
||||
{{{$repetition->limit->budget->name}}}
|
||||
</a>
|
||||
</td>
|
||||
|
@@ -6,39 +6,37 @@
|
||||
<small>Overview for budget "{{{$budget->name}}}"</small>
|
||||
</h1>
|
||||
<p class="lead">Budgets can help you cut back on spending.</p>
|
||||
|
||||
@if($view == 1)
|
||||
<!-- warning for selected limit -->
|
||||
@if(isset($filters[0]) && is_object($filters[0]) && get_class($filters[0]) == 'Limit')
|
||||
<p class="bg-primary" style="padding:15px;">
|
||||
This view is filtered to show only the envelope from
|
||||
{{{$repetitions[0]['limitrepetition']->periodShow()}}},
|
||||
which contains {{mf($repetitions[0]['limit']->amount,false)}}.
|
||||
</p>
|
||||
<p class="bg-info" style="padding:15px;">
|
||||
<a href="{{route('budgets.show',$budget->id)}}" class="text-info">Reset the filter(s).</a>
|
||||
</p>
|
||||
|
||||
@endif
|
||||
|
||||
|
||||
@if($view == 2)
|
||||
<!-- warning for non-caught only -->
|
||||
@if(isset($filters[0]) && $filters[0] == 'no_envelope')
|
||||
<p class="bg-primary" style="padding:15px;">
|
||||
This view is filtered to show transactions not in an envelope only.
|
||||
</p>
|
||||
<p class="bg-info" style="padding:15px;">
|
||||
<a href="{{route('budgets.show',$budget->id)}}" class="text-info">Reset the filter(s).</a>
|
||||
</p>
|
||||
@endif
|
||||
|
||||
@if($view == 3)
|
||||
<!-- warning for session date -->
|
||||
@if($useSessionDates == true)
|
||||
<p class="bg-primary" style="padding:15px;">
|
||||
This view is filtered to only show transactions between {{Session::get('start')->format('d M Y')}}
|
||||
and {{Session::get('end')->format('d M Y')}}.
|
||||
</p>
|
||||
|
||||
<p class="bg-info" style="padding:15px;">
|
||||
<a href="{{route('budgets.show',$budget->id)}}" class="text-info">Reset the filter(s).</a>
|
||||
</p>
|
||||
@endif
|
||||
@if($view != 4)
|
||||
<p class="bg-info" style="padding:15px;">
|
||||
<a class="btn btn-default btn-sm" href="{{route('budgets.show',$budget->id)}}">Reset the filter</a>
|
||||
</p>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -46,17 +44,22 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<div id="chart"></div>
|
||||
@if(isset($filters[0]) && is_object($filters[0]) && get_class($filters[0]) == 'Limit')
|
||||
@if($view == 1)
|
||||
<div id="instr" data-type="envelope" data-envelope="{{$repetitions[0]['limitrepetition']->id}}"></div>
|
||||
@elseif(isset($filters[0]) && $filters[0] == 'no_envelope')
|
||||
<div id="instr" data-type="no_envelope" data-budget="{{$budget->id}}"></div>
|
||||
@elseif($useSessionDates == true)
|
||||
<div id="instr" data-type="session" data-budget="{{$budget->id}}"></div>
|
||||
@else
|
||||
<div id="instr" data-type="default" data-budget="{{$budget->id}}"></div>
|
||||
@endif
|
||||
|
||||
|
||||
@if($view == 2)
|
||||
<div id="instr" data-type="no_envelope" data-budget="{{$budget->id}}"></div>
|
||||
@endif
|
||||
|
||||
@if($view == 3)
|
||||
<div id="instr" data-type="session" data-budget="{{$budget->id}}"></div>
|
||||
@endif
|
||||
|
||||
@if($view == 4)
|
||||
<div id="instr" data-type="default" data-budget="{{$budget->id}}"></div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -73,7 +76,7 @@
|
||||
{{$repetition['date']}}</a> <small>paginated</small></h4>
|
||||
@else
|
||||
<h4>
|
||||
<a href="{{route('budgets.show',$budget->id)}}?rep={{$repetition['limitrepetition']->id}}">
|
||||
<a href="{{route('budgets.show',$budget->id,$repetition['limitrepetition']->id)}}">
|
||||
{{$repetition['date']}}
|
||||
</a>
|
||||
</h4>
|
||||
@@ -100,13 +103,18 @@
|
||||
|
||||
@stop
|
||||
@section('scripts')
|
||||
@if(isset($filters[0]) && is_object($filters[0]) && get_class($filters[0]) == 'Limit')
|
||||
@if($view == 1)
|
||||
<?php echo javascript_include_tag('budgets-limit'); ?>
|
||||
@elseif(isset($filters[0]) && $filters[0] == 'no_envelope')
|
||||
@endif
|
||||
|
||||
@if($view == 2)
|
||||
<?php echo javascript_include_tag('budgets-nolimit'); ?>
|
||||
@elseif($useSessionDates == true)
|
||||
@endif
|
||||
|
||||
@if($view == 3)
|
||||
<?php echo javascript_include_tag('budgets-session'); ?>
|
||||
@else
|
||||
@endif
|
||||
@if($view == 4)
|
||||
<?php echo javascript_include_tag('budgets-default'); ?>
|
||||
@endif
|
||||
|
||||
|
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<h2><a href="#">Migrate from Firefly II</a></h2>
|
||||
<h2><a href="{{route('migrate.index')}}">Migrate from Firefly II</a></h2>
|
||||
|
||||
<p>
|
||||
Use this option if you have a JSON file from your current Firefly II installation.
|
||||
|
@@ -38,6 +38,10 @@
|
||||
<a href="{{route('categories.show',$component->id)}}?highlight={{$journal->id}}"><span class="glyphicon glyphicon-tag" title="Category: {{{$component->name}}}"></span></a>
|
||||
@endif
|
||||
@endforeach
|
||||
<!-- recurring transaction -->
|
||||
@if(!is_null($journal->recurringTransaction))
|
||||
<a href="{{route('recurring.show',$journal->recurring_transaction_id)}}" title="{{{$journal->recurringTransaction->name}}}"><span title="{{{$journal->recurringTransaction->name}}}" class="glyphicon glyphicon-refresh"></span></a>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
{{$journal->date->format('d F Y')}}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user