diff --git a/app/Http/Controllers/Report/ExpenseController.php b/app/Http/Controllers/Report/ExpenseController.php
index 3b2e2002a0..1aa3354107 100644
--- a/app/Http/Controllers/Report/ExpenseController.php
+++ b/app/Http/Controllers/Report/ExpenseController.php
@@ -59,6 +59,60 @@ class ExpenseController extends Controller
);
}
+ /**
+ * @param Collection $accounts
+ * @param Collection $expense
+ * @param Carbon $start
+ * @param Carbon $end
+ *
+ * @return string
+ * @throws \Throwable
+ */
+ public function budget(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
+ {
+ // Properties for cache:
+ $cache = new CacheProperties;
+ $cache->addProperty($start);
+ $cache->addProperty($end);
+ $cache->addProperty('expense-budget');
+ $cache->addProperty($accounts->pluck('id')->toArray());
+ $cache->addProperty($expense->pluck('id')->toArray());
+ if ($cache->has()) {
+ return $cache->get(); // @codeCoverageIgnore
+ }
+ $combined = $this->combineAccounts($expense);
+ $all = new Collection;
+ foreach ($combined as $name => $combi) {
+ $all = $all->merge($combi);
+ }
+ // now find spent / earned:
+ $spent = $this->spentByBudget($accounts, $all, $start, $end);
+ // do some merging to get the budget info ready.
+ $together = [];
+ foreach ($spent as $budgetId => $spentInfo) {
+ if (!isset($together[$budgetId])) {
+ $together[$budgetId]['spent'] = $spentInfo;
+ // get category info:
+ $first = reset($spentInfo);
+ $together[$budgetId]['budget'] = $first['budget'];
+ }
+ }
+
+ $result = view('reports.partials.exp-budgets', compact('together'))->render();
+ $cache->store($result);
+
+ return $result;
+ }
+
+ /**
+ * @param Collection $accounts
+ * @param Collection $expense
+ * @param Carbon $start
+ * @param Carbon $end
+ *
+ * @return string
+ * @throws \Throwable
+ */
public function category(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
{
// Properties for cache:
@@ -82,20 +136,20 @@ class ExpenseController extends Controller
// join arrays somehow:
$together = [];
- foreach($spent as $categoryId => $spentInfo) {
- if(!isset($together[$categoryId])) {
+ foreach ($spent as $categoryId => $spentInfo) {
+ if (!isset($together[$categoryId])) {
$together[$categoryId]['spent'] = $spentInfo;
// get category info:
- $first = reset($spentInfo);
+ $first = reset($spentInfo);
$together[$categoryId]['category'] = $first['category'];
}
}
- foreach($earned as $categoryId => $earnedInfo) {
- if(!isset($together[$categoryId])) {
+ foreach ($earned as $categoryId => $earnedInfo) {
+ if (!isset($together[$categoryId])) {
$together[$categoryId]['earned'] = $earnedInfo;
// get category info:
- $first = reset($earnedInfo);
+ $first = reset($earnedInfo);
$together[$categoryId]['category'] = $first['category'];
}
}
@@ -223,6 +277,58 @@ class ExpenseController extends Controller
return $combined;
}
+ /**
+ * @param Collection $assets
+ * @param Collection $opposing
+ * @param Carbon $start
+ * @param Carbon $end
+ *
+ * @return string
+ */
+ protected function earnedByCategory(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
+ {
+ /** @var JournalCollectorInterface $collector */
+ $collector = app(JournalCollectorInterface::class);
+ $collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setAccounts($assets);
+ $collector->setOpposingAccounts($opposing)->withCategoryInformation();
+ $set = $collector->getJournals();
+ $sum = [];
+ // loop to support multi currency
+ foreach ($set as $transaction) {
+ $currencyId = $transaction->transaction_currency_id;
+ $categoryName = $transaction->transaction_category_name;
+ $categoryId = intval($transaction->transaction_category_id);
+ // if null, grab from journal:
+ if ($categoryId === 0) {
+ $categoryName = $transaction->transaction_journal_category_name;
+ $categoryId = intval($transaction->transaction_journal_category_id);
+ }
+ if ($categoryId !== 0) {
+ $categoryName = app('steam')->tryDecrypt($categoryName);
+ }
+
+ // if not set, set to zero:
+ if (!isset($sum[$categoryId][$currencyId])) {
+ $sum[$categoryId][$currencyId] = [
+ 'sum' => '0',
+ 'category' => [
+ 'id' => $categoryId,
+ 'name' => $categoryName,
+ ],
+ 'currency' => [
+ 'symbol' => $transaction->transaction_currency_symbol,
+ 'dp' => $transaction->transaction_currency_dp,
+ ],
+ ];
+ }
+
+ // add amount
+ $sum[$categoryId][$currencyId]['sum'] = bcadd($sum[$categoryId][$currencyId]['sum'], $transaction->transaction_amount);
+ }
+
+ return $sum;
+ }
+
protected function earnedInPeriod(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
{
/** @var JournalCollectorInterface $collector */
@@ -259,37 +365,34 @@ class ExpenseController extends Controller
* @param Carbon $start
* @param Carbon $end
*
- * @return string
+ * @return array
*/
- protected function earnedByCategory(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
+ protected function spentByBudget(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
{
/** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class);
- $collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setAccounts($assets);
- $collector->setOpposingAccounts($opposing)->withCategoryInformation();
+ $collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setAccounts($assets);
+ $collector->setOpposingAccounts($opposing)->withBudgetInformation();
$set = $collector->getJournals();
$sum = [];
// loop to support multi currency
foreach ($set as $transaction) {
- $currencyId = $transaction->transaction_currency_id;
- $categoryName = $transaction->transaction_category_name;
- $categoryId = intval($transaction->transaction_category_id);
+ $currencyId = $transaction->transaction_currency_id;
+ $budgetName = $transaction->transaction_budget_name;
+ $budgetId = intval($transaction->transaction_budget_id);
// if null, grab from journal:
- if ($categoryId === 0) {
- $categoryName = $transaction->transaction_journal_category_name;
- $categoryId = intval($transaction->transaction_journal_category_id);
- }
- if($categoryId !== 0) {
- $categoryName = app('steam')->tryDecrypt($categoryName);
+ if ($budgetId === 0) {
+ $budgetName = $transaction->transaction_journal_budget_name;
+ $budgetId = intval($transaction->transaction_journal_budget_id);
}
// if not set, set to zero:
- if (!isset($sum[$categoryId][$currencyId])) {
- $sum[$categoryId][$currencyId] = [
+ if (!isset($sum[$budgetId][$currencyId])) {
+ $sum[$budgetId][$currencyId] = [
'sum' => '0',
- 'category' => [
- 'id' => $categoryId,
- 'name' => $categoryName,
+ 'budget' => [
+ 'id' => $budgetId,
+ 'name' => $budgetName,
],
'currency' => [
'symbol' => $transaction->transaction_currency_symbol,
@@ -299,7 +402,7 @@ class ExpenseController extends Controller
}
// add amount
- $sum[$categoryId][$currencyId]['sum'] = bcadd($sum[$categoryId][$currencyId]['sum'], $transaction->transaction_amount);
+ $sum[$budgetId][$currencyId]['sum'] = bcadd($sum[$budgetId][$currencyId]['sum'], $transaction->transaction_amount);
}
return $sum;
@@ -354,7 +457,6 @@ class ExpenseController extends Controller
return $sum;
}
-
/**
* @param Collection $assets
* @param Collection $opposing
diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php
index 7f3180faf9..9afe0998a8 100644
--- a/resources/lang/en_US/firefly.php
+++ b/resources/lang/en_US/firefly.php
@@ -20,6 +20,7 @@
*/
declare(strict_types=1);
+
return [
// general stuff:
'close' => 'Close',
@@ -716,6 +717,7 @@ return [
'mass_edit_journals' => 'Edit a number of transactions',
'cannot_edit_other_fields' => 'You cannot mass-edit other fields than the ones here, because there is no room to show them. Please follow the link and edit them by one-by-one, if you need to edit these fields.',
'no_budget' => 'none',
+ 'no_budget_squared' => '(no budget)',
'perm-delete-many' => 'Deleting many items in one go can be very disruptive. Please be cautious.',
'mass_deleted_transactions_success' => 'Deleted :amount transaction(s).',
'mass_edited_transactions_success' => 'Updated :amount transaction(s)',
diff --git a/resources/views/reports/partials/exp-budgets.twig b/resources/views/reports/partials/exp-budgets.twig
new file mode 100644
index 0000000000..1d5e382ce9
--- /dev/null
+++ b/resources/views/reports/partials/exp-budgets.twig
@@ -0,0 +1,31 @@
+
+
+
+ {{ 'budget'|_ }} |
+ {{ 'spent'|_ }} |
+
+
+
+ {% for budgetId, entry in together %}
+
+
+
+ {% if entry.budget.name|length ==0 %}
+ {{ 'no_budget_squared'|_ }}
+ {% else %}
+ {{ entry.budget.name }}
+ {% endif %}
+ |
+
+ {% if entry.spent|length ==0 %}
+ {{ '0'|formatAmount }}
+ {% else %}
+ {% for expense in entry.spent %}
+ {{ formatAmountBySymbol(expense.sum, expense.currency.symbol, expense.currency.dp) }}
+ {% endfor %}
+ {% endif %}
+ |
+
+ {% endfor %}
+
+
diff --git a/resources/views/reports/partials/exp-categories.twig b/resources/views/reports/partials/exp-categories.twig
index 8934902b14..1e62c3055a 100644
--- a/resources/views/reports/partials/exp-categories.twig
+++ b/resources/views/reports/partials/exp-categories.twig
@@ -1,16 +1,20 @@
- {{ 'category'|_ }} |
- {{ 'spent'|_ }} |
- {{ 'earned'|_ }} |
+ {{ 'category'|_ }} |
+ {{ 'spent'|_ }} |
+ {{ 'earned'|_ }} |
{% for categoryId, entry in together %}
-
- {% if entry.category.name|length ==0 %}{{ 'noCategory'|_ }}{% else %}{{ entry.category.name }}{% endif %}
+ |
+ {% if entry.category.name|length ==0 %}
+ {{ 'noCategory'|_ }}
+ {% else %}
+ {{ entry.category.name }}
+ {% endif %}
|
{% if entry.spent|length ==0 %}
diff --git a/resources/views/reports/partials/exp-grouped.twig b/resources/views/reports/partials/exp-grouped.twig
index b2bb66271f..a5b4ea4936 100644
--- a/resources/views/reports/partials/exp-grouped.twig
+++ b/resources/views/reports/partials/exp-grouped.twig
@@ -1,10 +1,10 @@
- {{ 'name'|_ }} |
- {{ 'period'|_ }} |
- {{ 'spent'|_ }} |
- {{ 'earned'|_ }} |
+ {{ 'name'|_ }} |
+ {{ 'period'|_ }} |
+ {{ 'spent'|_ }} |
+ {{ 'earned'|_ }} |
diff --git a/resources/views/reports/partials/exp-not-grouped.twig b/resources/views/reports/partials/exp-not-grouped.twig
index 7a231112f3..c946e8e307 100644
--- a/resources/views/reports/partials/exp-not-grouped.twig
+++ b/resources/views/reports/partials/exp-not-grouped.twig
@@ -1,9 +1,9 @@
- {{ 'name'|_ }} |
- {{ 'spent'|_ }} |
- {{ 'earned'|_ }} |
+ {{ 'name'|_ }} |
+ {{ 'spent'|_ }} |
+ {{ 'earned'|_ }} |
|