diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php index 5173ebc8da..3b3fe04310 100644 --- a/app/Http/Controllers/Chart/BudgetController.php +++ b/app/Http/Controllers/Chart/BudgetController.php @@ -32,7 +32,6 @@ use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; -use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\Support\CacheProperties; use FireflyIII\Support\Http\Controllers\AugumentData; use FireflyIII\Support\Http\Controllers\DateCalculation; @@ -492,8 +491,6 @@ class BudgetController extends Controller } - - /** @noinspection MoreThanThreeArgumentsInspection */ /** * Get the expenses for a budget in a date range. * diff --git a/app/Http/Controllers/Chart/BudgetReportController.php b/app/Http/Controllers/Chart/BudgetReportController.php index de8da30cfd..dfe4e4a3ed 100644 --- a/app/Http/Controllers/Chart/BudgetReportController.php +++ b/app/Http/Controllers/Chart/BudgetReportController.php @@ -25,17 +25,12 @@ namespace FireflyIII\Http\Controllers\Chart; use Carbon\Carbon; use FireflyIII\Generator\Chart\Basic\GeneratorInterface; use FireflyIII\Helpers\Chart\MetaPieChartInterface; -use FireflyIII\Helpers\Collector\JournalCollectorInterface; -use FireflyIII\Helpers\Filter\OpposingAccountFilter; -use FireflyIII\Helpers\Filter\PositiveAmountFilter; -use FireflyIII\Helpers\Filter\TransferFilter; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Budget; -use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Support\CacheProperties; use FireflyIII\Support\Http\Controllers\AugumentData; +use FireflyIII\Support\Http\Controllers\TransactionCalculation; use Illuminate\Http\JsonResponse; use Illuminate\Support\Collection; @@ -48,7 +43,7 @@ use Illuminate\Support\Collection; */ class BudgetReportController extends Controller { - use AugumentData; + use AugumentData, TransactionCalculation; /** @var BudgetRepositoryInterface The budget repository */ private $budgetRepository; /** @var GeneratorInterface Chart generation methods. */ @@ -187,7 +182,7 @@ class BudgetReportController extends Controller while ($currentStart < $end) { $currentEnd = clone $currentStart; $currentEnd = $currentEnd->$function(); - $expenses = $this->groupByBudget($this->getExpenses($accounts, $budgets, $currentStart, $currentEnd)); + $expenses = $this->groupByBudget($this->getExpensesInBudgets($accounts, $budgets, $currentStart, $currentEnd)); $label = $currentStart->formatLocalized($format); /** @var Budget $budget */ @@ -218,52 +213,4 @@ class BudgetReportController extends Controller return response()->json($data); } - - /** @noinspection MoreThanThreeArgumentsInspection */ - /** - * Helper function that collects expenses for the given budgets. - * - * @param Collection $accounts - * @param Collection $budgets - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - protected function getExpenses(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): Collection // get data + augment with info - { - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class); - $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) - ->setBudgets($budgets)->withOpposingAccount(); - $collector->removeFilter(TransferFilter::class); - - $collector->addFilter(OpposingAccountFilter::class); - $collector->addFilter(PositiveAmountFilter::class); - - return $collector->getJournals(); - } - - /** - * Helper function that groups expenses. - * - * @param Collection $set - * - * @return array - */ - protected function groupByBudget(Collection $set): array // filter + group data - { - // group by category ID: - $grouped = []; - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - $jrnlBudId = (int)$transaction->transaction_journal_budget_id; - $transBudId = (int)$transaction->transaction_budget_id; - $budgetId = max($jrnlBudId, $transBudId); - $grouped[$budgetId] = $grouped[$budgetId] ?? '0'; - $grouped[$budgetId] = bcadd($transaction->transaction_amount, $grouped[$budgetId]); - } - - return $grouped; - } } diff --git a/app/Http/Controllers/Chart/CategoryReportController.php b/app/Http/Controllers/Chart/CategoryReportController.php index 1bc16f6f70..1cee0797c9 100644 --- a/app/Http/Controllers/Chart/CategoryReportController.php +++ b/app/Http/Controllers/Chart/CategoryReportController.php @@ -25,16 +25,11 @@ namespace FireflyIII\Http\Controllers\Chart; use Carbon\Carbon; use FireflyIII\Generator\Chart\Basic\GeneratorInterface; use FireflyIII\Helpers\Chart\MetaPieChartInterface; -use FireflyIII\Helpers\Collector\JournalCollectorInterface; -use FireflyIII\Helpers\Filter\NegativeAmountFilter; -use FireflyIII\Helpers\Filter\OpposingAccountFilter; -use FireflyIII\Helpers\Filter\PositiveAmountFilter; -use FireflyIII\Helpers\Filter\TransferFilter; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Category; -use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionType; use FireflyIII\Support\CacheProperties; +use FireflyIII\Support\Http\Controllers\AugumentData; +use FireflyIII\Support\Http\Controllers\TransactionCalculation; use Illuminate\Http\JsonResponse; use Illuminate\Support\Collection; @@ -45,6 +40,8 @@ use Illuminate\Support\Collection; */ class CategoryReportController extends Controller { + use AugumentData, TransactionCalculation; + /** @var GeneratorInterface Chart generation methods. */ private $generator; @@ -244,8 +241,8 @@ class CategoryReportController extends Controller while ($currentStart < $end) { $currentEnd = clone $currentStart; $currentEnd = $currentEnd->$function(); - $expenses = $this->groupByCategory($this->getExpenses($accounts, $categories, $currentStart, $currentEnd)); - $income = $this->groupByCategory($this->getIncome($accounts, $categories, $currentStart, $currentEnd)); + $expenses = $this->groupByCategory($this->getExpensesInCategories($accounts, $categories, $currentStart, $currentEnd)); + $income = $this->groupByCategory($this->getIncomeForCategories($accounts, $categories, $currentStart, $currentEnd)); $label = $currentStart->formatLocalized($format); /** @var Category $category */ @@ -289,77 +286,5 @@ class CategoryReportController extends Controller return response()->json($data); } - /** @noinspection MoreThanThreeArgumentsInspection */ - /** - * Get all expenses in a period for categories. - * - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - * - * - */ - protected function getExpenses(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): Collection // get data + augument - { - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class); - $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) - ->setCategories($categories)->withOpposingAccount(); - $collector->removeFilter(TransferFilter::class); - $collector->addFilter(OpposingAccountFilter::class); - $collector->addFilter(PositiveAmountFilter::class); - - return $collector->getJournals(); - } - - /** @noinspection MoreThanThreeArgumentsInspection */ - /** - * Get all income for a period and a bunch of categories. - * - * @param Collection $accounts - * @param Collection $categories - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - protected function getIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): Collection // get data + augument - { - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class); - $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]) - ->setCategories($categories)->withOpposingAccount(); - - $collector->addFilter(OpposingAccountFilter::class); - $collector->addFilter(NegativeAmountFilter::class); - - return $collector->getJournals(); - } - - /** - * Group transactions by category. - * - * @param Collection $set - * - * @return array - */ - protected function groupByCategory(Collection $set): array // filter + group data - { - // group by category ID: - $grouped = []; - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - $jrnlCatId = (int)$transaction->transaction_journal_category_id; - $transCatId = (int)$transaction->transaction_category_id; - $categoryId = max($jrnlCatId, $transCatId); - $grouped[$categoryId] = $grouped[$categoryId] ?? '0'; - $grouped[$categoryId] = bcadd($transaction->transaction_amount, $grouped[$categoryId]); - } - - return $grouped; - } } diff --git a/app/Http/Controllers/Chart/ExpenseReportController.php b/app/Http/Controllers/Chart/ExpenseReportController.php index 603efa3b54..9103a9b64c 100644 --- a/app/Http/Controllers/Chart/ExpenseReportController.php +++ b/app/Http/Controllers/Chart/ExpenseReportController.php @@ -25,14 +25,12 @@ namespace FireflyIII\Http\Controllers\Chart; use Carbon\Carbon; use FireflyIII\Generator\Chart\Basic\GeneratorInterface; -use FireflyIII\Helpers\Collector\JournalCollectorInterface; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Support\CacheProperties; +use FireflyIII\Support\Http\Controllers\AugumentData; +use FireflyIII\Support\Http\Controllers\TransactionCalculation; use Illuminate\Http\JsonResponse; use Illuminate\Support\Collection; @@ -43,6 +41,7 @@ use Illuminate\Support\Collection; */ class ExpenseReportController extends Controller { + use AugumentData, TransactionCalculation; /** @var AccountRepositoryInterface The account repository */ protected $accountRepository; /** @var GeneratorInterface Chart generation methods. */ @@ -104,6 +103,10 @@ class ExpenseReportController extends Controller } // prep chart data: + /** + * @var string $name + * @var Collection $combi + */ foreach ($combined as $name => $combi) { // first is always expense account: /** @var Account $exp */ @@ -145,8 +148,8 @@ class ExpenseReportController extends Controller $currentEnd = $currentEnd->$function(); // get expenses grouped by opposing name: - $expenses = $this->groupByName($this->getExpenses($accounts, $all, $currentStart, $currentEnd)); - $income = $this->groupByName($this->getIncome($accounts, $all, $currentStart, $currentEnd)); + $expenses = $this->groupByName($this->getExpensesForOpposing($accounts, $all, $currentStart, $currentEnd)); + $income = $this->groupByName($this->getIncomeForOpposing($accounts, $all, $currentStart, $currentEnd)); $label = $currentStart->formatLocalized($format); foreach ($combined as $name => $combi) { @@ -191,89 +194,4 @@ class ExpenseReportController extends Controller return response()->json($data); } - - /** - * Searches for the opposing account. - * - * @param Collection $accounts - * - * @return array - */ - protected function combineAccounts(Collection $accounts): array // filter + group data - { - $combined = []; - /** @var Account $expenseAccount */ - foreach ($accounts as $expenseAccount) { - $collection = new Collection; - $collection->push($expenseAccount); - - $revenue = $this->accountRepository->findByName($expenseAccount->name, [AccountType::REVENUE]); - if (null !== $revenue) { - $collection->push($revenue); - } - $combined[$expenseAccount->name] = $collection; - } - - return $combined; - } - - /** - * Get all expenses for a set of accounts. - * - * @param Collection $accounts - * @param Collection $opposing - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - protected function getExpenses(Collection $accounts, Collection $opposing, Carbon $start, Carbon $end): Collection // get data + augument - { - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class); - $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setOpposingAccounts($opposing); - - return $collector->getJournals(); - } - - /** - * Get the income for a set of accounts. - * - * @param Collection $accounts - * @param Collection $opposing - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - */ - protected function getIncome(Collection $accounts, Collection $opposing, Carbon $start, Carbon $end): Collection // get data + augument - { - /** @var JournalCollectorInterface $collector */ - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class); - $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setOpposingAccounts($opposing); - - return $collector->getJournals(); - } - - /** - * Group set of transactions by name of opposing account. - * - * @param Collection $set - * - * @return array - */ - protected function groupByName(Collection $set): array // filter + group data - { - // group by opposing account name. - $grouped = []; - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - $name = $transaction->opposing_account_name; - $grouped[$name] = $grouped[$name] ?? '0'; - $grouped[$name] = bcadd($transaction->transaction_amount, $grouped[$name]); - } - - return $grouped; - } } diff --git a/app/Http/Controllers/Chart/TagReportController.php b/app/Http/Controllers/Chart/TagReportController.php index cef0cd5abd..a69d179c1c 100644 --- a/app/Http/Controllers/Chart/TagReportController.php +++ b/app/Http/Controllers/Chart/TagReportController.php @@ -18,7 +18,6 @@ * You should have received a copy of the GNU General Public License * along with Firefly III. If not, see . */ -/** @noinspection MoreThanThreeArgumentsInspection */ declare(strict_types=1); namespace FireflyIII\Http\Controllers\Chart; @@ -26,16 +25,11 @@ namespace FireflyIII\Http\Controllers\Chart; use Carbon\Carbon; use FireflyIII\Generator\Chart\Basic\GeneratorInterface; use FireflyIII\Helpers\Chart\MetaPieChartInterface; -use FireflyIII\Helpers\Collector\JournalCollectorInterface; -use FireflyIII\Helpers\Filter\NegativeAmountFilter; -use FireflyIII\Helpers\Filter\OpposingAccountFilter; -use FireflyIII\Helpers\Filter\PositiveAmountFilter; -use FireflyIII\Helpers\Filter\TransferFilter; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Tag; -use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionType; use FireflyIII\Support\CacheProperties; +use FireflyIII\Support\Http\Controllers\AugumentData; +use FireflyIII\Support\Http\Controllers\TransactionCalculation; use Illuminate\Http\JsonResponse; use Illuminate\Support\Collection; @@ -44,6 +38,7 @@ use Illuminate\Support\Collection; */ class TagReportController extends Controller { + use AugumentData, TransactionCalculation; /** @var GeneratorInterface Chart generation methods. */ protected $generator; @@ -239,8 +234,8 @@ class TagReportController extends Controller while ($currentStart < $end) { $currentEnd = clone $currentStart; $currentEnd = $currentEnd->$function(); - $expenses = $this->groupByTag($this->getExpenses($accounts, $tags, $currentStart, $currentEnd)); - $income = $this->groupByTag($this->getIncome($accounts, $tags, $currentStart, $currentEnd)); + $expenses = $this->groupByTag($this->getExpensesForTags($accounts, $tags, $currentStart, $currentEnd)); + $income = $this->groupByTag($this->getIncomeForTags($accounts, $tags, $currentStart, $currentEnd)); $label = $currentStart->formatLocalized($format); /** @var Tag $tag */ @@ -341,83 +336,4 @@ class TagReportController extends Controller return response()->json($data); } - - /** @noinspection MoreThanThreeArgumentsInspection */ - /** - * Get all expenses by tags. - * - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - * - * @SuppressWarnings(PHPMD.ExcessiveParameterList) - */ - protected function getExpenses(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): Collection // get data + augument - { - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class); - $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) - ->setTags($tags)->withOpposingAccount(); - $collector->removeFilter(TransferFilter::class); - - $collector->addFilter(OpposingAccountFilter::class); - $collector->addFilter(PositiveAmountFilter::class); - - return $collector->getJournals(); - } - - /** @noinspection MoreThanThreeArgumentsInspection */ - /** - * Get all income by tag. - * - * @param Collection $accounts - * @param Collection $tags - * @param Carbon $start - * @param Carbon $end - * - * @return Collection - * - * @SuppressWarnings(PHPMD.ExcessiveParameterList) - */ - protected function getIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): Collection // get data + augument - { - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class); - $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]) - ->setTags($tags)->withOpposingAccount(); - - $collector->addFilter(OpposingAccountFilter::class); - $collector->addFilter(NegativeAmountFilter::class); - - return $collector->getJournals(); - } - - /** - * Group transactions by tag. - * - * @param Collection $set - * - * @return array - */ - protected function groupByTag(Collection $set): array // filter + group data - { - // group by category ID: - $grouped = []; - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - $journal = $transaction->transactionJournal; - $journalTags = $journal->tags; - /** @var Tag $journalTag */ - foreach ($journalTags as $journalTag) { - $journalTagId = $journalTag->id; - $grouped[$journalTagId] = $grouped[$journalTagId] ?? '0'; - $grouped[$journalTagId] = bcadd($transaction->transaction_amount, $grouped[$journalTagId]); - } - } - - return $grouped; - } } diff --git a/app/Http/Controllers/Report/CategoryController.php b/app/Http/Controllers/Report/CategoryController.php index 14dc4cf999..7214d556cb 100644 --- a/app/Http/Controllers/Report/CategoryController.php +++ b/app/Http/Controllers/Report/CategoryController.php @@ -63,7 +63,7 @@ class CategoryController extends Controller $categories = $repository->getCategories(); $data = $repository->periodExpenses($categories, $accounts, $start, $end); $data[0] = $repository->periodExpensesNoCategory($accounts, $start, $end); - $report = $this->filterReport($data); + $report = $this->filterPeriodReport($data); $periods = app('navigation')->listOfPeriods($start, $end); try { $result = view('reports.partials.category-period', compact('report', 'periods'))->render(); diff --git a/app/Http/Controllers/Report/ExpenseController.php b/app/Http/Controllers/Report/ExpenseController.php index f09959b3f5..8157fdbf56 100644 --- a/app/Http/Controllers/Report/ExpenseController.php +++ b/app/Http/Controllers/Report/ExpenseController.php @@ -31,6 +31,7 @@ use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Support\CacheProperties; +use FireflyIII\Support\Http\Controllers\AugumentData; use Illuminate\Support\Collection; use Log; use Throwable; @@ -42,6 +43,8 @@ use Throwable; */ class ExpenseController extends Controller { + use AugumentData; + /** @var AccountRepositoryInterface The account repository */ protected $accountRepository; @@ -328,30 +331,7 @@ class ExpenseController extends Controller return $result; } - /** - * Combine accounts into a single list. - * - * @param Collection $accounts - * - * @return array - */ - protected function combineAccounts(Collection $accounts): array // filter + group data - { - $combined = []; - /** @var Account $expenseAccount */ - foreach ($accounts as $expenseAccount) { - $collection = new Collection; - $collection->push($expenseAccount); - $revenue = $this->accountRepository->findByName($expenseAccount->name, [AccountType::REVENUE]); - if (null !== $revenue) { - $collection->push($revenue); - } - $combined[$expenseAccount->name] = $collection; - } - - return $combined; - } /** @noinspection MoreThanThreeArgumentsInspection */ /** diff --git a/app/Http/Controllers/TagController.php b/app/Http/Controllers/TagController.php index 615249cc62..e32cc3c384 100644 --- a/app/Http/Controllers/TagController.php +++ b/app/Http/Controllers/TagController.php @@ -29,7 +29,6 @@ use FireflyIII\Helpers\Filter\InternalTransferFilter; use FireflyIII\Http\Requests\TagFormRequest; use FireflyIII\Models\Tag; use FireflyIII\Repositories\Tag\TagRepositoryInterface; -use FireflyIII\Support\CacheProperties; use FireflyIII\Support\Http\Controllers\PeriodOverview; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; diff --git a/app/Support/Http/Controllers/AugumentData.php b/app/Support/Http/Controllers/AugumentData.php index fdd3702259..07183f108a 100644 --- a/app/Support/Http/Controllers/AugumentData.php +++ b/app/Support/Http/Controllers/AugumentData.php @@ -24,9 +24,12 @@ declare(strict_types=1); namespace FireflyIII\Support\Http\Controllers; use Carbon\Carbon; +use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; +use FireflyIII\Models\Tag; +use FireflyIII\Models\Transaction; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; @@ -39,6 +42,61 @@ use Illuminate\Support\Collection; */ trait AugumentData { + /** + * Searches for the opposing account. + * + * @param Collection $accounts + * + * @return array + */ + protected function combineAccounts(Collection $accounts): array // filter + group data + { + /** @var AccountRepositoryInterface $repository */ + $repository = app(AccountRepositoryInterface::class); + $combined = []; + /** @var Account $expenseAccount */ + foreach ($accounts as $expenseAccount) { + $collection = new Collection; + $collection->push($expenseAccount); + + $revenue = $repository->findByName($expenseAccount->name, [AccountType::REVENUE]); + if (null !== $revenue) { + $collection->push($revenue); + } + $combined[$expenseAccount->name] = $collection; + } + + return $combined; + } + + /** + * Returns the budget limits belonging to the given budget and valid on the given day. + * + * @param Collection $budgetLimits + * @param Budget $budget + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + protected function filterBudgetLimits(Collection $budgetLimits, Budget $budget, Carbon $start, Carbon $end): Collection // filter data + { + $set = $budgetLimits->filter( + function (BudgetLimit $budgetLimit) use ($budget, $start, $end) { + if ($budgetLimit->budget_id === $budget->id + && $budgetLimit->start_date->lte($start) // start of budget limit is on or before start + && $budgetLimit->end_date->gte($end) // end of budget limit is on or after end + ) { + return $budgetLimit; + } + + return false; + } + ); + + return $set; + } + /** * Get the account names belonging to a bunch of account ID's. * @@ -111,33 +169,96 @@ trait AugumentData return $return; } - - /** @noinspection MoreThanThreeArgumentsInspection */ /** - * Returns the budget limits belonging to the given budget and valid on the given day. + * Helper function that groups expenses. * - * @param Collection $budgetLimits - * @param Budget $budget - * @param Carbon $start - * @param Carbon $end + * @param Collection $set * - * @return Collection + * @return array */ - protected function filterBudgetLimits(Collection $budgetLimits, Budget $budget, Carbon $start, Carbon $end): Collection // filter data + protected function groupByBudget(Collection $set): array // filter + group data { - $set = $budgetLimits->filter( - function (BudgetLimit $budgetLimit) use ($budget, $start, $end) { - if ($budgetLimit->budget_id === $budget->id - && $budgetLimit->start_date->lte($start) // start of budget limit is on or before start - && $budgetLimit->end_date->gte($end) // end of budget limit is on or after end - ) { - return $budgetLimit; - } + // group by category ID: + $grouped = []; + /** @var Transaction $transaction */ + foreach ($set as $transaction) { + $jrnlBudId = (int)$transaction->transaction_journal_budget_id; + $transBudId = (int)$transaction->transaction_budget_id; + $budgetId = max($jrnlBudId, $transBudId); + $grouped[$budgetId] = $grouped[$budgetId] ?? '0'; + $grouped[$budgetId] = bcadd($transaction->transaction_amount, $grouped[$budgetId]); + } - return false; + return $grouped; + } + + /** + * Group transactions by category. + * + * @param Collection $set + * + * @return array + */ + protected function groupByCategory(Collection $set): array // filter + group data + { + // group by category ID: + $grouped = []; + /** @var Transaction $transaction */ + foreach ($set as $transaction) { + $jrnlCatId = (int)$transaction->transaction_journal_category_id; + $transCatId = (int)$transaction->transaction_category_id; + $categoryId = max($jrnlCatId, $transCatId); + $grouped[$categoryId] = $grouped[$categoryId] ?? '0'; + $grouped[$categoryId] = bcadd($transaction->transaction_amount, $grouped[$categoryId]); + } + + return $grouped; + } + + /** + * Group set of transactions by name of opposing account. + * + * @param Collection $set + * + * @return array + */ + protected function groupByName(Collection $set): array // filter + group data + { + // group by opposing account name. + $grouped = []; + /** @var Transaction $transaction */ + foreach ($set as $transaction) { + $name = $transaction->opposing_account_name; + $grouped[$name] = $grouped[$name] ?? '0'; + $grouped[$name] = bcadd($transaction->transaction_amount, $grouped[$name]); + } + + return $grouped; + } + + /** + * Group transactions by tag. + * + * @param Collection $set + * + * @return array + */ + protected function groupByTag(Collection $set): array // filter + group data + { + // group by category ID: + $grouped = []; + /** @var Transaction $transaction */ + foreach ($set as $transaction) { + $journal = $transaction->transactionJournal; + $journalTags = $journal->tags; + /** @var Tag $journalTag */ + foreach ($journalTags as $journalTag) { + $journalTagId = $journalTag->id; + $grouped[$journalTagId] = $grouped[$journalTagId] ?? '0'; + $grouped[$journalTagId] = bcadd($transaction->transaction_amount, $grouped[$journalTagId]); } - ); + } - return $set; + return $grouped; } } \ No newline at end of file diff --git a/app/Support/Http/Controllers/TransactionCalculation.php b/app/Support/Http/Controllers/TransactionCalculation.php new file mode 100644 index 0000000000..97dddc2034 --- /dev/null +++ b/app/Support/Http/Controllers/TransactionCalculation.php @@ -0,0 +1,203 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Support\Http\Controllers; + +use Carbon\Carbon; +use FireflyIII\Helpers\Collector\JournalCollectorInterface; +use FireflyIII\Helpers\Filter\NegativeAmountFilter; +use FireflyIII\Helpers\Filter\OpposingAccountFilter; +use FireflyIII\Helpers\Filter\PositiveAmountFilter; +use FireflyIII\Helpers\Filter\TransferFilter; +use FireflyIII\Models\TransactionType; +use Illuminate\Support\Collection; + +/** + * Trait TransactionCalculation + * + * @package FireflyIII\Support\Http\Controllers + */ +trait TransactionCalculation +{ + /** + * Get all expenses for a set of accounts. + * + * @param Collection $accounts + * @param Collection $opposing + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + protected function getExpensesForOpposing(Collection $accounts, Collection $opposing, Carbon $start, Carbon $end): Collection // get data + augument + { + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setOpposingAccounts($opposing); + + return $collector->getJournals(); + } + + /** + * Get all expenses by tags. + * + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + * + */ + protected function getExpensesForTags(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): Collection // get data + augument + { + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) + ->setTags($tags)->withOpposingAccount(); + $collector->removeFilter(TransferFilter::class); + + $collector->addFilter(OpposingAccountFilter::class); + $collector->addFilter(PositiveAmountFilter::class); + + return $collector->getJournals(); + } + + /** + * Helper function that collects expenses for the given budgets. + * + * @param Collection $accounts + * @param Collection $budgets + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + protected function getExpensesInBudgets(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): Collection // get data + augment with info + { + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) + ->setBudgets($budgets)->withOpposingAccount(); + $collector->removeFilter(TransferFilter::class); + + $collector->addFilter(OpposingAccountFilter::class); + $collector->addFilter(PositiveAmountFilter::class); + + return $collector->getJournals(); + } + + /** + * Get all expenses in a period for categories. + * + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + * + * + */ + protected function getExpensesInCategories(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): Collection // get data + augument + { + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) + ->setCategories($categories)->withOpposingAccount(); + $collector->removeFilter(TransferFilter::class); + + $collector->addFilter(OpposingAccountFilter::class); + $collector->addFilter(PositiveAmountFilter::class); + + return $collector->getJournals(); + } + + /** + * Get all income for a period and a bunch of categories. + * + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + protected function getIncomeForCategories(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): Collection // get data + augument + { + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]) + ->setCategories($categories)->withOpposingAccount(); + + $collector->addFilter(OpposingAccountFilter::class); + $collector->addFilter(NegativeAmountFilter::class); + + return $collector->getJournals(); + } + + /** + * Get the income for a set of accounts. + * + * @param Collection $accounts + * @param Collection $opposing + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + protected function getIncomeForOpposing(Collection $accounts, Collection $opposing, Carbon $start, Carbon $end): Collection // get data + augument + { + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setOpposingAccounts($opposing); + + return $collector->getJournals(); + } + + /** + * Get all income by tag. + * + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + protected function getIncomeForTags(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): Collection // get data + augument + { + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]) + ->setTags($tags)->withOpposingAccount(); + + $collector->addFilter(OpposingAccountFilter::class); + $collector->addFilter(NegativeAmountFilter::class); + + return $collector->getJournals(); + } + +} \ No newline at end of file