Budget report thing.

This commit is contained in:
James Cole
2015-05-16 14:14:22 +02:00
parent e7285c6499
commit bca2ddd529
6 changed files with 393 additions and 71 deletions

View File

@@ -1,14 +1,147 @@
<?php <?php
/**
* Created by PhpStorm.
* User: sander
* Date: 16/05/15
* Time: 13:09
*/
namespace FireflyIII\Helpers\Collection; namespace FireflyIII\Helpers\Collection;
use Illuminate\Support\Collection;
/**
* Class Budget
*
* @package FireflyIII\Helpers\Collection
*/
class Budget
{
/** @var Collection */
protected $budgetLines;
/** @var float */
protected $budgeted = 0;
/** @var float */
protected $left = 0;
/** @var float */
protected $overspent = 0;
/** @var float */
protected $spent = 0;
/**
*
*/
public function __construct()
{
$this->budgetLines = new Collection;
}
/**
* @param BudgetLine $budgetLine
*/
public function addBudgetLine(BudgetLine $budgetLine)
{
$this->budgetLines->push($budgetLine);
}
/**
* @param float $add
*/
public function addBudgeted($add)
{
$this->budgeted += floatval($add);
}
/**
* @param float $add
*/
public function addLeft($add)
{
$this->left += floatval($add);
}
/**
* @param float $add
*/
public function addOverspent($add)
{
$this->overspent += floatval($add);
}
/**
* @param float $add
*/
public function addSpent($add)
{
$this->spent += floatval($add);
}
/**
* @return float
*/
public function getBudgeted()
{
return $this->budgeted;
}
/**
* @param float $budgeted
*/
public function setBudgeted($budgeted)
{
$this->budgeted = $budgeted;
}
/**
* @return float
*/
public function getLeft()
{
return $this->left;
}
/**
* @param float $left
*/
public function setLeft($left)
{
$this->left = $left;
}
/**
* @return float
*/
public function getOverspent()
{
return $this->overspent;
}
/**
* @param float $overspent
*/
public function setOverspent($overspent)
{
$this->overspent = $overspent;
}
/**
* @return float
*/
public function getSpent()
{
return $this->spent;
}
/**
* @param float $spent
*/
public function setSpent($spent)
{
$this->spent = $spent;
}
/**
* @return \Illuminate\Support\Collection
*/
public function getBudgetLines()
{
return $this->budgetLines;
}
class Budget {
} }

View File

@@ -0,0 +1,132 @@
<?php
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Budget as BudgetModel;
use FireflyIII\Models\LimitRepetition;
/**
* Class BudgetLine
*
* @package FireflyIII\Helpers\Collection
*/
class BudgetLine
{
/** @var BudgetModel */
protected $budget;
/** @var LimitRepetition */
protected $repetition;
/** @var float */
protected $budgeted = 0;
/** @var float */
protected $left = 0;
/** @var float */
protected $overspent = 0;
/** @var float */
protected $spent = 0;
/**
* @return BudgetModel
*/
public function getBudget()
{
return $this->budget;
}
/**
* @param BudgetModel $budget
*/
public function setBudget($budget)
{
$this->budget = $budget;
}
/**
* @return float
*/
public function getBudgeted()
{
return $this->budgeted;
}
/**
* @param float $budgeted
*/
public function setBudgeted($budgeted)
{
$this->budgeted = $budgeted;
}
/**
* @return float
*/
public function getLeft()
{
return $this->left;
}
/**
* @param float $left
*/
public function setLeft($left)
{
$this->left = $left;
}
/**
* @return float
*/
public function getOverspent()
{
return $this->overspent;
}
/**
* @param float $overspent
*/
public function setOverspent($overspent)
{
$this->overspent = $overspent;
}
/**
* @return float
*/
public function getSpent()
{
return $this->spent;
}
/**
* @param float $spent
*/
public function setSpent($spent)
{
$this->spent = $spent;
}
/**
* @return LimitRepetition
*/
public function getRepetition()
{
return $this->repetition;
}
/**
* @param LimitRepetition $repetition
*/
public function setRepetition($repetition)
{
$this->repetition = $repetition;
}
}

View File

@@ -2,13 +2,16 @@
namespace FireflyIII\Helpers\Report; namespace FireflyIII\Helpers\Report;
use App;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Helpers\Collection\Account as AccountCollection; use FireflyIII\Helpers\Collection\Account as AccountCollection;
use FireflyIII\Helpers\Collection\Budget as BudgetCollection; use FireflyIII\Helpers\Collection\Budget as BudgetCollection;
use FireflyIII\Helpers\Collection\BudgetLine;
use FireflyIII\Helpers\Collection\Category as CategoryCollection; use FireflyIII\Helpers\Collection\Category as CategoryCollection;
use FireflyIII\Helpers\Collection\Expense; use FireflyIII\Helpers\Collection\Expense;
use FireflyIII\Helpers\Collection\Income; use FireflyIII\Helpers\Collection\Income;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\LimitRepetition;
/** /**
* Class ReportHelper * Class ReportHelper
@@ -75,7 +78,60 @@ class ReportHelper implements ReportHelperInterface
*/ */
public function getBudgetReport(Carbon $start, Carbon $end, $shared) public function getBudgetReport(Carbon $start, Carbon $end, $shared)
{ {
return null; $object = new BudgetCollection;
/** @var \FireflyIII\Repositories\Budget\BudgetRepositoryInterface $repository */
$repository = App::make('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$set = $repository->getBudgets();
foreach ($set as $budget) {
$repetitions = $repository->getBudgetLimitRepetitions($budget, $start, $end);
// no repetition(s) for this budget:
if ($repetitions->count() == 0) {
$spent = $repository->spentInPeriod($budget, $start, $end, $shared);
$budgetLine = new BudgetLine;
$budgetLine->setBudget($budget);
$budgetLine->setOverspent($spent);
$object->addOverspent($spent);
$object->addBudgetLine($budgetLine);
continue;
}
// one or more repetitions for budget:
/** @var LimitRepetition $repetition */
foreach ($repetitions as $repetition) {
$budgetLine = new BudgetLine;
$budgetLine->setBudget($budget);
$budgetLine->setRepetition($repetition);
$expenses = $repository->spentInPeriod($budget, $repetition->startdate, $repetition->enddate, $shared);
$left = $expenses < floatval($repetition->amount) ? floatval($repetition->amount) - $expenses : 0;
$spent = $expenses > floatval($repetition->amount) ? 0 : $expenses;
$overspent = $expenses > floatval($repetition->amount) ? $expenses - floatval($repetition->amount) : 0;
$budgetLine->setLeft($left);
$budgetLine->setSpent($spent);
$budgetLine->setOverspent($overspent);
$budgetLine->setBudgeted($repetition->amount);
$object->addBudgeted($repetition->amount);
$object->addSpent($spent);
$object->addLeft($left);
$object->addOverspent($overspent);
$object->addBudgetLine($budgetLine);
}
}
// stuff outside of budgets:
$noBudget = $repository->getWithoutBudgetSum($start, $end);
$budgetLine = new BudgetLine;
$budgetLine->setOverspent($noBudget);
$object->addOverspent($noBudget);
$object->addBudgetLine($budgetLine);
return $object;
} }
/** /**

View File

@@ -99,8 +99,6 @@ class BudgetRepository implements BudgetRepositoryInterface
public function getBudgets() public function getBudgets()
{ {
$budgets = Auth::user()->budgets()->get(); $budgets = Auth::user()->budgets()->get();
$budgets->sortBy('name');
return $budgets; return $budgets;
} }

View File

@@ -0,0 +1,62 @@
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-tasks fa-fw"></i>
{{ 'budgets'|_ }}
</div>
<table class="table table-bordered">
<tr>
<th>{{ 'budget'|_ }}</th>
<th>{{ 'date'|_ }}</th>
<th>{{ 'budgeted'|_ }}</th>
<th>{{ 'spent'|_ }}</th>
<th>{{ 'left'|_ }}</th>
<th>{{ 'overspent'|_ }}</th>
</tr>
{% for budgetLine in budgets.getBudgetLines %}
<tr>
<td>
{% if budgetLine.getBudget %}
<a href="{{route('budgets.show',budgetLine.getBudget.id)}}">{{ budgetLine.getBudget.name }}</a>
{% else %}
<em>{{ 'noBudget'|_ }}</em>
{% endif %}
</td>
<td>
{% if budgetLine.getRepetition %}
{{ budgetLine.getRepetition.startdate.formatLocalized(monthAndDayFormat) }}
{% endif %}
</td>
<td>
{% if budgetLine.getRepetition %}
{{ budgetLine.getRepetition.amount|formatAmount }}
{% else %}
{{ 0|formatAmount }}
{% endif %}
</td>
<td>
{% if budgetLine.getSpent != 0 %}
{{ budgetLine.getSpent|formatAmount }}
{% endif %}
</td>
<td>
{% if budgetLine.getLeft != 0 %}
{{ budgetLine.getLeft|formatAmount }}
{% endif %}
</td>
<td>
{% if budgetLine.getOverspent != 0 %}
<span class="text-danger">{{ budgetLine.getOverspent|formatAmountPlain }}</span>
{% endif %}
</td>
</tr>
{% endfor %}
<tr>
<td colspan="2"><em>{{ 'sum'|_ }}</em></td>
<td>{{ budgets.getBudgeted|formatAmount }}</td>
<td>{{ budgets.getSpent|formatAmount }}</td>
<td>{{ budgets.getLeft|formatAmount }}</td>
<td><span class="text-danger">{{ budgets.getOverspent|formatAmountPlain }}</span></td>
</tr>
</table>
</div>

View File

@@ -32,67 +32,8 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-8 col-md-8 col-sm-12"> <div class="col-lg-8 col-md-8 col-sm-12">
<div class="panel panel-default"> <!-- budgets -->
<div class="panel-heading"> {% include 'partials/reports/budgets.twig' %}
<i class="fa fa-tasks fa-fw"></i>
{{ 'budgets'|_ }}
</div>
<table class="table table-bordered">
<tr>
<th>{{ 'budget'|_ }}</th>
<th>{{ 'date'|_ }}</th>
<th>{{ 'budgeted'|_ }}</th>
<th>{{ 'spent'|_ }}</th>
<th>{{ 'left'|_ }}</th>
<th>{{ 'overspent'|_ }}</th>
</tr>
{% for data in budgets %}
<tr>
<td>
{% if data[0] %}
<a href="{{route('budgets.show',data[0].id)}}">{{ data[0].name }}</a>
{% else %}
<em>{{ 'noBudget'|_ }}</em>
{% endif %}
</td>
<td>
{% if data[1] %}
{{ data[1].startdate.formatLocalized(monthAndDayFormat) }}
{% endif %}
</td>
<td>
{% if data[1] %}
{{ data[1].amount|formatAmount }}
{% else %}
{{ 0|formatAmount }}
{% endif %}
</td>
<td>
{% if data[3] != 0 %}
{{ data[3]|formatAmount }}
{% endif %}
</td>
<td>
{% if data[2] != 0 %}
{{ data[2]|formatAmount }}
{% endif %}
</td>
<td>
{% if data[4] != 0 %}
<span class="text-danger">{{ data[4]|formatAmountPlain }}</span>
{% endif %}
</td>
</tr>
{% endfor %}
<tr>
<td colspan="2"><em>{{ 'sum'|_ }}</em></td>
<td>{{ budgetSums.budgeted|formatAmount }}</td>
<td>{{ budgetSums.spent|formatAmount }}</td>
<td>{{ budgetSums.left|formatAmount }}</td>
<td><span class="text-danger">{{ budgetSums.overspent|formatAmountPlain }}</span></td>
</tr>
</table>
</div>
</div> </div>
<div class="col-lg-4 col-md-4 col-sm-12"> <div class="col-lg-4 col-md-4 col-sm-12">
<div class="panel panel-default"> <div class="panel panel-default">