First attempt at functional category chart.

This commit is contained in:
James Cole
2015-12-16 13:08:26 +01:00
parent 6a8bf0aa62
commit 1b3d208540
12 changed files with 390 additions and 28 deletions

View File

@@ -19,6 +19,13 @@ interface CategoryChartGenerator
*/
public function all(Collection $entries);
/**
* @param Collection $entries
*
* @return array
*/
public function multiYear(Collection $entries);
/**
* @param Collection $entries
*

View File

@@ -158,4 +158,37 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator
return $data;
}
/**
* @param Collection $entries
*
* @return array
*/
public function multiYear(Collection $entries)
{
// dataset:
$data = [
'count' => 0,
'labels' => [],
'datasets' => [],
];
// get labels from one of the categories (assuming there's at least one):
$first = $entries->first();
foreach ($first['spent'] as $year => $noInterest) {
$data['labels'][] = strval($year);
}
// then, loop all entries and create datasets:
foreach ($entries as $entry) {
$name = $entry['name'];
$spent = $entry['spent'];
$earned = $entry['earned'];
$data['datasets'][] = ['label' => 'Spent in category ' . $name, 'data' => array_values($spent)];
$data['datasets'][] = ['label' => 'Earned in category ' . $name, 'data' => array_values($earned)];
}
$data['count'] = count($data['datasets']);
return $data;
}
}

View File

@@ -56,7 +56,7 @@ class BudgetController extends Controller
$cache->addProperty('multiYearBudget');
if ($cache->has()) {
// return Response::json($cache->get()); // @codeCoverageIgnore
return Response::json($cache->get()); // @codeCoverageIgnore
}
/**

View File

@@ -121,6 +121,84 @@ class CategoryController extends Controller
);
$set = new Collection($array);
$data = $this->generator->frontpage($set);
$cache->store($data);
return Response::json($data);
}
/**
* @param CategoryRepositoryInterface $repository
* @param $report_type
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
* @param Collection $categories
*/
public function multiYear(CategoryRepositoryInterface $repository, $report_type, Carbon $start, Carbon $end, Collection $accounts, Collection $categories)
{
// chart properties for cache:
$cache = new CacheProperties();
$cache->addProperty($report_type);
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($accounts);
$cache->addProperty($categories);
$cache->addProperty('multiYearCategory');
if ($cache->has()) {
return Response::json($cache->get()); // @codeCoverageIgnore
}
/**
* category
* year:
* spent: x
* earned: x
* year
* spent: x
* earned: x
*/
$entries = new Collection;
// go by budget, not by year.
/** @var Category $category */
foreach ($categories as $category) {
$entry = ['name' => '', 'spent' => [], 'earned' => []];
$currentStart = clone $start;
while ($currentStart < $end) {
// fix the date:
$currentEnd = clone $currentStart;
$currentEnd->endOfYear();
// get data:
if (is_null($category->id)) {
$name = trans('firefly.noCategory');
$spent = $repository->spentNoCategoryForAccounts($accounts, $currentStart, $currentEnd);
$earned = $repository->earnedNoCategoryForAccounts($accounts, $currentStart, $currentEnd);
} else {
$name = $category->name;
$spent = $repository->spentInPeriodForAccounts($category, $accounts, $currentStart, $currentEnd);
$earned = $repository->earnedInPeriodForAccounts($category, $accounts, $currentStart, $currentEnd);
}
// save to array:
$year = $currentStart->year;
$entry['name'] = $name;
$entry['spent'][$year] = ($spent * -1);
$entry['earned'][$year] = $earned;
// jump to next year.
$currentStart = clone $currentEnd;
$currentStart->addDay();
}
$entries->push($entry);
}
// generate chart with data:
$data = $this->generator->multiYear($entries);
$cache->store($data);
return Response::json($data);

View File

@@ -56,13 +56,13 @@ Route::bind(
if (Auth::check()) {
$ids = explode(',', $value);
/** @var \Illuminate\Support\Collection $object */
$object = Budget::where('budgets.active', 1)
->whereIn('budgets.id', $ids)
->where('budgets.user_id', Auth::user()->id)
->get(['budgets.*']);
$object = Budget::where('active', 1)
->whereIn('id', $ids)
->where('user_id', Auth::user()->id)
->get();
// add empty budget if applicable.
if(in_array('0', $ids)) {
if (in_array('0', $ids)) {
$object->push(new Budget);
}
@@ -74,6 +74,30 @@ Route::bind(
}
);
// category list
Route::bind(
'categoryList',
function ($value) {
if (Auth::check()) {
$ids = explode(',', $value);
/** @var \Illuminate\Support\Collection $object */
$object = Category::whereIn('id', $ids)
->where('user_id', Auth::user()->id)
->get();
// add empty budget if applicable.
if (in_array('0', $ids)) {
$object->push(new Category);
}
if ($object->count() > 0) {
return $object;
}
}
throw new NotFoundHttpException;
}
);
// Date
Route::bind(
'start_date',
@@ -244,7 +268,7 @@ Route::get('/cron/sendgrid', ['uses' => 'CronController@sendgrid']);
Route::controllers(
[
'auth' => 'Auth\AuthController',
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]
);
@@ -390,10 +414,12 @@ Route::group(
// categories:
Route::get('/chart/category/frontpage', ['uses' => 'Chart\CategoryController@frontpage']);
// both charts are for reports:
// these three charts are for reports:
Route::get('/chart/category/spent-in-year/{report_type}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\CategoryController@spentInYear']);
Route::get('/chart/category/earned-in-year/{report_type}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\CategoryController@earnedInYear']);
Route::get(
'/chart/category/multi-year/{report_type}/{start_date}/{end_date}/{accountList}/{categoryList}', ['uses' => 'Chart\CategoryController@multiYear']
);
Route::get('/chart/category/{category}/period', ['uses' => 'Chart\CategoryController@currentPeriod']);
Route::get('/chart/category/{category}/period/{date}', ['uses' => 'Chart\CategoryController@specificPeriod']);
@@ -403,7 +429,9 @@ Route::group(
Route::get('/chart/piggyBank/{piggyBank}', ['uses' => 'Chart\PiggyBankController@history']);
// reports:
Route::get('/chart/report/in-out/{report_type}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\ReportController@yearInOut'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']);
Route::get('/chart/report/in-out/{report_type}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\ReportController@yearInOut'])->where(
['year' => '[0-9]{4}', 'shared' => 'shared']
);
Route::get('/chart/report/in-out-sum/{report_type}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\ReportController@yearInOutSummarized'])->where(
['year' => '[0-9]{4}', 'shared' => 'shared']
);
@@ -472,10 +500,10 @@ Route::group(
* Report Controller
*/
Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']);
// Route::post('/reports/select', ['uses' => 'ReportController@select', 'as' => 'reports.select']);
// Route::post('/reports/select', ['uses' => 'ReportController@select', 'as' => 'reports.select']);
Route::get('/reports/report/{report_type}/{start_date}/{end_date}/{accountList}', ['uses' => 'ReportController@report', 'as' => 'reports.report']);
// Route::get('/reports/{year}/{shared?}', ['uses' => 'ReportController@year', 'as' => 'reports.year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']);
// Route::get('/reports/{year}/{month}/{shared?}', ['uses' => 'ReportController@month', 'as' => 'reports.month'])->where(['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared']);
// Route::get('/reports/{year}/{shared?}', ['uses' => 'ReportController@year', 'as' => 'reports.year'])->where(['year' => '[0-9]{4}', 'shared' => 'shared']);
// Route::get('/reports/{year}/{month}/{shared?}', ['uses' => 'ReportController@month', 'as' => 'reports.month'])->where(['year' => '[0-9]{4}', 'month' => '[0-9]{1,2}', 'shared' => 'shared']);
// pop ups for budget report:

View File

@@ -59,6 +59,71 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
return $set;
}
/**
* Returns the amount earned without category by accounts in period.
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function earnedNoCategoryForAccounts(Collection $accounts, Carbon $start, Carbon $end)
{
$accountIds = [];
foreach ($accounts as $account) {
$accountIds[] = $account->id;
}
// is deposit AND account_from is in the list of $accounts
// not from any of the accounts in the list?
return Auth::user()
->transactionjournals()
->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->whereNull('category_transaction_journal.id')
->before($end)
->after($start)
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->whereIn('transactions.account_id', $accountIds)
->transactionTypes([TransactionType::DEPOSIT])
->get(['transaction_journals.*'])->sum('amount');
}
/**
* Returns the amount spent without category by accounts in period.
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function spentNoCategoryForAccounts(Collection $accounts, Carbon $start, Carbon $end)
{
$accountIds = [];
foreach ($accounts as $account) {
$accountIds[] = $account->id;
}
// is withdrawal or transfer AND account_from is in the list of $accounts
return Auth::user()
->transactionjournals()
->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->whereNull('category_transaction_journal.id')
->before($end)
->after($start)
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->whereIn('transactions.account_id', $accountIds)
->transactionTypes([TransactionType::WITHDRAWAL])
->get(['transaction_journals.*'])->sum('amount');
}
/**
*
@@ -385,4 +450,65 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito
{
return $category->transactionjournals()->transactionTypes([TransactionType::DEPOSIT])->onDate($date)->get(['transaction_journals.*'])->sum('amount');
}
/**
* Calculates how much is spent in this period.
*
* @param Category $category
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function spentInPeriodForAccounts(Category $category, Collection $accounts, Carbon $start, Carbon $end)
{
$accountIds = [];
foreach ($accounts as $account) {
$accountIds[] = $account->id;
}
$sum
= $category
->transactionjournals()
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->after($start)
->before($end)
->whereIn('transactions.account_id', $accountIds)
->transactionTypes([TransactionType::WITHDRAWAL])
->get(['transaction_journals.*'])
->sum('amount');
return $sum;
}
/**
* Calculate how much is earned in this period.
*
* @param Category $category
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function earnedInPeriodForAccounts(Category $category, Collection $accounts, Carbon $start, Carbon $end)
{
$accountIds = [];
foreach ($accounts as $account) {
$accountIds[] = $account->id;
}
$sum
= $category
->transactionjournals()
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->before($end)
->whereIn('transactions.account_id', $accountIds)
->transactionTypes([TransactionType::DEPOSIT])
->after($start)
->get(['transaction_journals.*'])
->sum('amount');
return $sum;
}
}

View File

@@ -39,6 +39,53 @@ interface CategoryRepositoryInterface
*/
public function getCategories();
/**
* Calculates how much is spent in this period.
*
* @param Category $category
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function spentInPeriodForAccounts(Category $category, Collection $accounts, Carbon $start, Carbon $end);
/**
* Calculate how much is earned in this period.
*
* @param Category $category
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function earnedInPeriodForAccounts(Category $category, Collection $accounts, Carbon $start, Carbon $end);
/**
* Returns the amount spent without category by accounts in period.
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function spentNoCategoryForAccounts(Collection $accounts, Carbon $start, Carbon $end);
/**
* Returns the amount earned without category by accounts in period.
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function earnedNoCategoryForAccounts(Collection $accounts, Carbon $start, Carbon $end);
/**
* Corrected for tags.
*