More tests

This commit is contained in:
James Cole 2015-04-07 17:51:22 +02:00
parent 192db4bb6e
commit 1932bf277a
9 changed files with 282 additions and 78 deletions

View File

@ -1,6 +1,5 @@
<?php namespace FireflyIII\Http\Controllers;
use App;
use Carbon\Carbon;
use Crypt;
use DB;
@ -19,6 +18,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use Grumpydictator\Gchart\GChart;
use Illuminate\Support\Collection;
use Navigation;
@ -348,37 +348,22 @@ class GoogleChartController extends Controller
}
/**
* @param Budget $budget
* @param int $year
* @param GChart $chart
* @param BudgetRepositoryInterface $repository
*
* @param Budget $budget
*
* @param int $year
*
* @return \Illuminate\Http\JsonResponse
* @return \Symfony\Component\HttpFoundation\Response
*/
public function budgetsAndSpending(Budget $budget, $year = 0)
public function budgetsAndSpending(Budget $budget, $year = 0, GChart $chart, BudgetRepositoryInterface $repository)
{
$chart = App::make('Grumpydictator\Gchart\GChart');
$repository = App::make('FireflyIII\Repositories\Budget\BudgetRepository');
$chart->addColumn('Month', 'date');
$chart->addColumn('Budgeted', 'number');
$chart->addColumn('Spent', 'number');
if ($year == 0) {
// grab the first budgetlimit ever:
$firstLimit = $budget->budgetlimits()->orderBy('startdate', 'ASC')->first();
if ($firstLimit) {
$start = new Carbon($firstLimit->startdate);
} else {
$start = Carbon::now()->startOfYear();
}
// grab the last budget limit ever:
$lastLimit = $budget->budgetlimits()->orderBy('startdate', 'DESC')->first();
if ($lastLimit) {
$end = new Carbon($lastLimit->startdate);
} else {
$end = Carbon::now()->endOfYear();
}
if ($year == 0) {
$start = $repository->getFirstBudgetLimitDate($budget);
$end = $repository->getLastBudgetLimitDate($budget);
} else {
$start = Carbon::createFromDate(intval($year), 1, 1);
$end = clone $start;
@ -386,19 +371,8 @@ class GoogleChartController extends Controller
}
while ($start <= $end) {
$spent = $repository->spentInMonth($budget, $start);
$repetition = LimitRepetition::leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
->where('limit_repetitions.startdate', $start->format('Y-m-d 00:00:00'))
->where('budget_limits.budget_id', $budget->id)
->first(['limit_repetitions.*']);
if ($repetition) {
$budgeted = floatval($repetition->amount);
\Log::debug('Found a repetition on ' . $start->format('Y-m-d') . ' for budget ' . $budget->name . '!');
} else {
\Log::debug('No repetition on ' . $start->format('Y-m-d') . ' for budget ' . $budget->name);
$budgeted = null;
}
$spent = $repository->spentInMonth($budget, $start);
$budgeted = $repository->getLimitAmountOnDate($budget, $start);
$chart->addRow(clone $start, $budgeted, $spent);
$start->addMonth();
}
@ -416,12 +390,11 @@ class GoogleChartController extends Controller
*
* @return \Illuminate\Http\JsonResponse
*/
public function categoryOverviewChart(Category $category, GChart $chart)
public function categoryOverviewChart(Category $category, GChart $chart, CategoryRepositoryInterface $repository)
{
// oldest transaction in category:
/** @var TransactionJournal $first */
$first = $category->transactionjournals()->orderBy('date', 'ASC')->first();
$start = $first->date;
$start = $repository->getFirstActivityDate($category);
/** @var Preference $range */
$range = Preferences::get('viewRange', '1M');
// jump to start of week / month / year / etc (TODO).
@ -434,13 +407,12 @@ class GoogleChartController extends Controller
while ($start <= $end) {
$currentEnd = Navigation::endOfPeriod($start, $range->data);
$spent = floatval($category->transactionjournals()->before($currentEnd)->after($start)->lessThan(0)->sum('amount')) * -1;
$spent = $repository->spentInPeriodSum($category, $start, $currentEnd);
$chart->addRow(clone $start, $spent);
$start = Navigation::addPeriod($start, $range->data, 0);
}
$chart->generate();
return Response::json($chart->getData());
@ -454,17 +426,15 @@ class GoogleChartController extends Controller
*
* @return \Illuminate\Http\JsonResponse
*/
public function categoryPeriodChart(Category $category, GChart $chart)
public function categoryPeriodChart(Category $category, GChart $chart, CategoryRepositoryInterface $repository)
{
// oldest transaction in category:
/** @var TransactionJournal $first */
$start = clone Session::get('start');
$start = clone Session::get('start', Carbon::now()->startOfMonth());
$chart->addColumn('Period', 'date');
$chart->addColumn('Spent', 'number');
$end = Session::get('end');
$end = Session::get('end', Carbon::now()->endOfMonth());
while ($start <= $end) {
$spent = floatval($category->transactionjournals()->onDate($start)->lessThan(0)->sum('amount')) * -1;
$spent = $repository->spentOnDaySum($category, $start);
$chart->addRow(clone $start, $spent);
$start->addDay();
}
@ -482,13 +452,13 @@ class GoogleChartController extends Controller
*
* @return \Illuminate\Http\JsonResponse
*/
public function piggyBankHistory(PiggyBank $piggyBank, GChart $chart)
public function piggyBankHistory(PiggyBank $piggyBank, GChart $chart, PiggyBankRepositoryInterface $repository)
{
$chart->addColumn('Date', 'date');
$chart->addColumn('Balance', 'number');
/** @var Collection $set */
$set = DB::table('piggy_bank_events')->where('piggy_bank_id', $piggyBank->id)->groupBy('date')->get(['date', DB::Raw('SUM(`amount`) AS `sum`')]);
$set = $repository->getEventSummarySet($piggyBank);
$sum = 0;
foreach ($set as $entry) {

View File

@ -7,9 +7,9 @@ use Carbon\Carbon;
use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\LimitRepetition;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Database\Query\Builder as QueryBuilder;
/**
* Class BudgetRepository
@ -56,6 +56,17 @@ class BudgetRepository implements BudgetRepositoryInterface
return true;
}
/**
* @param Budget $budget
* @param Carbon $date
*
* @return float
*/
public function expensesOnDay(Budget $budget, Carbon $date)
{
return floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($date)->sum('amount'));
}
/**
* @return Collection
*/
@ -117,6 +128,21 @@ class BudgetRepository implements BudgetRepositoryInterface
return $budget->limitrepetitions()->where('limit_repetitions.startdate', $date)->first(['limit_repetitions.*']);
}
/**
* @param Budget $budget
*
* @return Carbon
*/
public function getFirstBudgetLimitDate(Budget $budget)
{
$limit = $budget->budgetlimits()->orderBy('startdate', 'ASC')->first();
if ($limit) {
return $limit->startdate;
}
return Carbon::now()->startOfYear();
}
/**
* @return Collection
*/
@ -158,6 +184,41 @@ class BudgetRepository implements BudgetRepositoryInterface
return new LengthAwarePaginator($set, $count, $take, $offset);
}
/**
* @param Budget $budget
*
* @return Carbon
*/
public function getLastBudgetLimitDate(Budget $budget)
{
$limit = $budget->budgetlimits()->orderBy('startdate', 'DESC')->first();
if ($limit) {
return $limit->startdate;
}
return Carbon::now()->startOfYear();
}
/**
* @param Budget $budget
* @param Carbon $date
*
* @return float|null
*/
public function getLimitAmountOnDate(Budget $budget, Carbon $date)
{
$repetition = LimitRepetition::leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
->where('limit_repetitions.startdate', $date->format('Y-m-d 00:00:00'))
->where('budget_limits.budget_id', $budget->id)
->first(['limit_repetitions.*']);
if ($repetition) {
return floatval($repetition->amount);
}
return null;
}
/**
* @param Carbon $start
* @param Carbon $end
@ -204,6 +265,7 @@ class BudgetRepository implements BudgetRepositoryInterface
->lessThan(0)
->transactionTypes(['Withdrawal'])
->get();
return floatval($noBudgetSet->sum('amount')) * -1;
}
@ -308,15 +370,4 @@ class BudgetRepository implements BudgetRepositoryInterface
}
/**
* @param Budget $budget
* @param Carbon $date
*
* @return float
*/
public function expensesOnDay(Budget $budget, Carbon $date)
{
return floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($date)->sum('amount'));
}
}

View File

@ -26,6 +26,14 @@ interface BudgetRepositoryInterface
*/
public function destroy(Budget $budget);
/**
* @param Budget $budget
* @param Carbon $date
*
* @return float
*/
public function expensesOnDay(Budget $budget, Carbon $date);
/**
* @return Collection
*/
@ -60,6 +68,13 @@ interface BudgetRepositoryInterface
*/
public function getCurrentRepetition(Budget $budget, Carbon $date);
/**
* @param Budget $budget
*
* @return Carbon
*/
public function getFirstBudgetLimitDate(Budget $budget);
/**
* @return Collection
*/
@ -76,6 +91,21 @@ interface BudgetRepositoryInterface
*/
public function getJournals(Budget $budget, LimitRepetition $repetition = null, $take = 50);
/**
* @param Budget $budget
*
* @return Carbon
*/
public function getLastBudgetLimitDate(Budget $budget);
/**
* @param Budget $budget
* @param Carbon $date
*
* @return float
*/
public function getLimitAmountOnDate(Budget $budget, Carbon $date);
/**
* @param Carbon $start
* @param Carbon $end
@ -107,14 +137,6 @@ interface BudgetRepositoryInterface
*/
public function store(array $data);
/**
* @param Budget $budget
* @param Carbon $date
*
* @return float
*/
public function expensesOnDay(Budget $budget, Carbon $date);
/**
* @param Budget $budget
* @param Carbon $start

View File

@ -79,6 +79,23 @@ class CategoryRepository implements CategoryRepositoryInterface
->get(['categories.id', 'categories.encrypted', 'categories.name', DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]);
}
/**
* @param Category $category
*
* @return Carbon
*/
public function getFirstActivityDate(Category $category)
{
/** @var TransactionJournal $first */
$first = $category->transactionjournals()->orderBy('date', 'ASC')->first();
if ($first) {
return $first->date;
}
return new Carbon;
}
/**
* @param Category $category
* @param int $page
@ -138,6 +155,18 @@ class CategoryRepository implements CategoryRepositoryInterface
->get(['transaction_journals.*']);
}
/**
* @param Category $category
* @param Carbon $start
* @param Carbon $end
*
* @return float
*/
public function spentInPeriodSum(Category $category, Carbon $start, Carbon $end)
{
return floatval($category->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1;
}
/**
* @param array $data
*
@ -170,4 +199,15 @@ class CategoryRepository implements CategoryRepositoryInterface
return $category;
}
/**
* @param Category $category
* @param Carbon $date
*
* @return float
*/
public function spentOnDaySum(Category $category, Carbon $date)
{
return floatval($category->transactionjournals()->onDate($date)->lessThan(0)->sum('amount')) * -1;
}
}

View File

@ -40,6 +40,13 @@ interface CategoryRepositoryInterface
*/
public function getCategoriesAndExpenses($start, $end);
/**
* @param Category $category
*
* @return Carbon
*/
public function getFirstActivityDate(Category $category);
/**
* @param Category $category
* @param int $page
@ -63,6 +70,23 @@ interface CategoryRepositoryInterface
*/
public function getWithoutCategory(Carbon $start, Carbon $end);
/**
* @param Category $category
* @param Carbon $start
* @param Carbon $end
*
* @return float
*/
public function spentInPeriodSum(Category $category, Carbon $start, Carbon $end);
/**
* @param Category $category
* @param Carbon $date
*
* @return float
*/
public function spentOnDaySum(Category $category, Carbon $date);
/**
* @param array $data
*

View File

@ -86,6 +86,16 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
return $part;
}
/**
* @param PiggyBank $piggyBank
*
* @return Collection
*/
public function getEventSummarySet(PiggyBank $piggyBank)
{
return DB::table('piggy_bank_events')->where('piggy_bank_id', $piggyBank->id)->groupBy('date')->get(['date', DB::Raw('SUM(`amount`) AS `sum`')]);
}
/**
* Set all piggy banks to order 0.
*

View File

@ -35,6 +35,13 @@ interface PiggyBankRepositoryInterface
*/
public function createPiggyBankPart(array $data);
/**
* @param PiggyBank $piggyBank
*
* @return Collection
*/
public function getEventSummarySet(PiggyBank $piggyBank);
/**
* Set all piggy banks to order 0.
*

View File

@ -190,8 +190,10 @@ class GoogleChartControllerTest extends TestCase
public function testBudgetLimitSpending()
{
$repetition = FactoryMuffin::create('FireflyIII\Models\LimitRepetition');
$budget = $repetition->budgetlimit->budget;
$repetition = FactoryMuffin::create('FireflyIII\Models\LimitRepetition');
$repetition->startdate = Carbon::now()->startOfMonth();
$repetition->enddate = Carbon::now()->endOfMonth();
$budget = $repetition->budgetlimit->budget;
$this->be($budget->user);
///chart/budget/{budget}/{limitrepetition}
@ -206,22 +208,86 @@ class GoogleChartControllerTest extends TestCase
public function testBudgetsAndSpending()
{
$this->markTestIncomplete();
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$this->be($budget->user);
$repository = $this->mock('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$repository->shouldReceive('spentInMonth')->andReturn(100);
$repository->shouldReceive('getLimitAmountOnDate')->andReturn(100);
$repository->shouldReceive('getFirstBudgetLimitDate')->andReturn(Carbon::now()->startOfMonth());
$repository->shouldReceive('getLastBudgetLimitDate')->andReturn(Carbon::now()->endOfYear());
// /chart/budget/{budget}/spending/{year?}
$this->call('GET', '/chart/budget/' . $budget->id . '/spending/0');
$this->assertResponseOk();
}
public function testBudgetsAndSpendingWithYear()
{
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
$this->be($budget->user);
$repository = $this->mock('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$repository->shouldReceive('spentInMonth')->andReturn(100);
$repository->shouldReceive('getLimitAmountOnDate')->andReturn(100);
// /chart/budget/{budget}/spending/{year?}
$this->call('GET', '/chart/budget/' . $budget->id . '/spending/2015');
$this->assertResponseOk();
}
public function testCategoryOverviewChart()
{
$this->markTestIncomplete();
$category = FactoryMuffin::create('FireflyIII\Models\Category');
$pref = FactoryMuffin::create('FireflyIII\Models\Preference');
$this->be($category->user);
$start = new Carbon();
$start->subDay();
$end = new Carbon;
$end->addWeek();
// mock!
$repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
$repository->shouldReceive('getFirstActivityDate')->andReturn($start);
$repository->shouldReceive('spentInPeriodSum')->andReturn(rand(1, 100));
Preferences::shouldReceive('get')->andReturn($pref);
Navigation::shouldReceive('startOfPeriod')->andReturn($start);
Navigation::shouldReceive('endOfPeriod')->andReturn($start);
Navigation::shouldReceive('addPeriod')->andReturn($end);
$this->call('GET', '/chart/category/' . $category->id . '/overview');
$this->assertResponseOk();
}
public function testCategoryPeriodChart()
{
$this->markTestIncomplete();
$category = FactoryMuffin::create('FireflyIII\Models\Category');
$this->be($category->user);
// mock!
$repository = $this->mock('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
$repository->shouldReceive('spentOnDaySum')->andReturn(rand(1, 100));
$this->call('GET', '/chart/category/' . $category->id . '/period');
$this->assertResponseOk();
}
public function testPiggyBankHistory()
{
$this->markTestIncomplete();
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
$this->be($piggyBank->account->user);
$obj = new stdClass;
$obj->sum = 12;
$obj->date = new Carbon;
$collection = new Collection([$obj]);
$repository = $this->mock('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface');
$repository->shouldReceive('getEventSummarySet')->andReturn($collection);
$this->call('GET', '/chart/piggy-history/' . $piggyBank->id);
$this->assertResponseOk();
}
public function testYearInExp()

View File

@ -160,6 +160,20 @@ FactoryMuffin::define(
]
);
FactoryMuffin::define(
'FireflyIII\Models\PiggyBank',
[
'account_id' => 'factory|FireflyIII\Models\Account',
'name' => 'sentence',
'targetamount' => 'integer',
'startdate' => 'date',
'targetdate' => 'date',
'reminder_skip' => 0,
'remind_me' => 0,
'order' => 0,
]
);
FactoryMuffin::define(
'FireflyIII\Models\TransactionType',
[