diff --git a/app/controllers/TransactionController.php b/app/controllers/TransactionController.php index b987272c45..5be29c9855 100644 --- a/app/controllers/TransactionController.php +++ b/app/controllers/TransactionController.php @@ -162,6 +162,8 @@ class TransactionController extends BaseController } /** + * @SuppressWarnings("CyclomaticComplexity") // It's 7. More than 5 but alright. + * * @param $what * * @return $this diff --git a/app/lib/FireflyIII/Event/Piggybank.php b/app/lib/FireflyIII/Event/Piggybank.php index 5188658a2a..9273f5c600 100644 --- a/app/lib/FireflyIII/Event/Piggybank.php +++ b/app/lib/FireflyIII/Event/Piggybank.php @@ -180,6 +180,7 @@ class PiggyBank } /** + * @SuppressWarnings("CyclomaticComplexity") // It's 6. More than 5 but alright. * * Validates the presence of repetitions for all repeated expenses! */ diff --git a/app/lib/FireflyIII/Report/Report.php b/app/lib/FireflyIII/Report/Report.php index 70b651eb74..0dfce025fc 100644 --- a/app/lib/FireflyIII/Report/Report.php +++ b/app/lib/FireflyIII/Report/Report.php @@ -7,7 +7,6 @@ use FireflyIII\Database\Account\Account as AccountRepository; use FireflyIII\Database\SwitchUser; use FireflyIII\Database\TransactionJournal\TransactionJournal as JournalRepository; use Illuminate\Database\Query\Builder; -use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; /** @@ -47,6 +46,7 @@ class Report implements ReportInterface /** * This methods fails to take in account transfers FROM shared accounts. + * * @param Carbon $start * @param Carbon $end * @param int $limit @@ -117,7 +117,7 @@ class Report implements ReportInterface $accounts = []; /** @var \Account $account */ foreach ($list as $account) { - $id = intval($account->id); + $id = intval($account->id); /** @noinspection PhpParamsInspection */ $accounts[$id] = [ 'name' => $account->name, @@ -232,8 +232,6 @@ class Report implements ReportInterface * * @SuppressWarnings(PHPMD.UnusedFormalParameter) * - * TODO: This method runs two queries which are only marginally different. Try and combine these. - * * @param Carbon $date * @param bool $shared * @@ -247,45 +245,48 @@ class Report implements ReportInterface $end->endOfMonth(); $userId = $this->_accounts->getUser()->id; - $list = \TransactionJournal::leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id') - ->leftJoin( - 'account_meta', function (JoinClause $join) { - $join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole'); - } - ) - ->transactionTypes(['Deposit']) - ->where('transaction_journals.user_id', $userId) - ->where('transactions.amount', '>', 0) - ->where('transaction_journals.user_id', \Auth::user()->id) - ->where('account_meta.data', '!=', '"sharedExpense"') - ->orderBy('date', 'ASC') - ->before($end)->after($start)->get(['transaction_journals.*']); + return $this->_queries->incomeByPeriod($start, $end); - // incoming from a shared account: it's profit (income): - $transfers = \TransactionJournal::withRelevantData() - ->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id') - ->leftJoin( - 'account_meta', function (JoinClause $join) { - $join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole'); - } - ) - ->transactionTypes(['Transfer']) - ->where('transaction_journals.user_id', $userId) - ->where('transactions.amount', '<', 0) - ->where('account_meta.data', '=', '"sharedExpense"') - ->orderBy('date', 'ASC') - ->before($end)->after($start)->get(['transaction_journals.*']); + // $list = \TransactionJournal::leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + // ->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id') + // ->leftJoin( + // 'account_meta', function (JoinClause $join) { + // $join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole'); + // } + // ) + // ->transactionTypes(['Deposit']) + // ->where('transaction_journals.user_id', $userId) + // ->where('transactions.amount', '>', 0) + // ->where('transaction_journals.user_id', \Auth::user()->id) + // ->where('account_meta.data', '!=', '"sharedExpense"') + // ->orderBy('date', 'ASC') + // ->before($end)->after($start)->get(['transaction_journals.*']); + // + // // incoming from a shared account: it's profit (income): + // $transfers = \TransactionJournal::withRelevantData() + // ->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + // ->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id') + // ->leftJoin( + // 'account_meta', function (JoinClause $join) { + // $join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole'); + // } + // ) + // ->transactionTypes(['Transfer']) + // ->where('transaction_journals.user_id', $userId) + // ->where('transactions.amount', '<', 0) + // ->where('account_meta.data', '=', '"sharedExpense"') + // ->orderBy('date', 'ASC') + // ->before($end)->after($start)->get(['transaction_journals.*']); + // + // $list = $list->merge($transfers); + // $list->sort( + // function (\TransactionJournal $journal) { + // return $journal->date->format('U'); + // } + // ); + // + // return $list; - $list = $list->merge($transfers); - $list->sort( - function (\TransactionJournal $journal) { - return $journal->date->format('U'); - } - ); - - return $list; } /** @@ -302,21 +303,21 @@ class Report implements ReportInterface \PiggyBank:: leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id') - ->where('accounts.user_id', \Auth::user()->id) - ->where('repeats', 0) - ->where( - function (Builder $query) use ($start, $end) { - $query->whereNull('piggy_banks.deleted_at'); - $query->orWhere( - function (Builder $query) use ($start, $end) { - $query->whereNotNull('piggy_banks.deleted_at'); - $query->where('piggy_banks.deleted_at', '>=', $start->format('Y-m-d 00:00:00')); - $query->where('piggy_banks.deleted_at', '<=', $end->format('Y-m-d 00:00:00')); - } - ); - } - ) - ->get(['piggy_banks.*']); + ->where('accounts.user_id', \Auth::user()->id) + ->where('repeats', 0) + ->where( + function (Builder $query) use ($start, $end) { + $query->whereNull('piggy_banks.deleted_at'); + $query->orWhere( + function (Builder $query) use ($start, $end) { + $query->whereNotNull('piggy_banks.deleted_at'); + $query->where('piggy_banks.deleted_at', '>=', $start->format('Y-m-d 00:00:00')); + $query->where('piggy_banks.deleted_at', '<=', $end->format('Y-m-d 00:00:00')); + } + ); + } + ) + ->get(['piggy_banks.*']); } @@ -372,7 +373,6 @@ class Report implements ReportInterface return $this->_queries->journalsByRevenueAccount($start, $end, $limit); - } /** diff --git a/app/lib/FireflyIII/Report/ReportQuery.php b/app/lib/FireflyIII/Report/ReportQuery.php index 4f8fd1a663..2591b858a6 100644 --- a/app/lib/FireflyIII/Report/ReportQuery.php +++ b/app/lib/FireflyIII/Report/ReportQuery.php @@ -199,6 +199,70 @@ class ReportQuery implements ReportQueryInterface } + /** + * This method returns all "income" journals in a certain period, which are both transfers from a shared account + * and "ordinary" deposits. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does + * not group and returns different fields. + * + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function incomeByPeriod(Carbon $start, Carbon $end) + { + return \TransactionJournal:: + leftJoin( + 'transactions as t_from', function (JoinClause $join) { + $join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0); + } + ) + ->leftJoin('accounts as ac_from', 't_from.account_id', '=', 'ac_from.id') + ->leftJoin( + 'account_meta as acm_from', function (JoinClause $join) { + $join->on('ac_from.id', '=', 'acm_from.account_id')->where('acm_from.name', '=', 'accountRole'); + } + ) + ->leftJoin( + 'transactions as t_to', function (JoinClause $join) { + $join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0); + } + ) + ->leftJoin('accounts as ac_to', 't_to.account_id', '=', 'ac_to.id') + ->leftJoin( + 'account_meta as acm_to', function (JoinClause $join) { + $join->on('ac_to.id', '=', 'acm_to.account_id')->where('acm_to.name', '=', 'accountRole'); + } + ) + ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') + ->where( + function ($query) { + $query->where( + function ($q) { + $q->where('transaction_types.type', 'Deposit'); + $q->where('acm_to.data', '!=', '"sharedExpense"'); + } + ); + $query->orWhere( + function ($q) { + $q->where('transaction_types.type', 'Transfer'); + $q->where('acm_from.data', '=', '"sharedExpense"'); + } + ); + } + ) + ->before($end)->after($start) + ->where('transaction_journals.user_id', \Auth::user()->id) + ->groupBy('t_from.account_id')->orderBy('transaction_journals.date') + ->get( + ['transaction_journals.id', + 'transaction_journals.description', + 'transaction_types.type', + 't_to.amount', 'transaction_journals.date', 't_from.account_id as account_id', + 'ac_from.name as name'] + ); + } + /** * Gets a list of expenses grouped by the budget they were filed under. * diff --git a/app/lib/FireflyIII/Report/ReportQueryInterface.php b/app/lib/FireflyIII/Report/ReportQueryInterface.php index a2097c6635..046835b843 100644 --- a/app/lib/FireflyIII/Report/ReportQueryInterface.php +++ b/app/lib/FireflyIII/Report/ReportQueryInterface.php @@ -117,6 +117,18 @@ interface ReportQueryInterface */ public function journalsByRevenueAccount(Carbon $start, Carbon $end); + /** + * This method returns all "income" journals in a certain period, which are both transfers from a shared account + * and "ordinary" deposits. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does + * not group and returns different fields. + * + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function incomeByPeriod(Carbon $start, Carbon $end); + /** * With an equally misleading name, this query returns are transfers to shared accounts. These are considered * expenses. diff --git a/app/lib/FireflyIII/Shared/Toolkit/Filter.php b/app/lib/FireflyIII/Shared/Toolkit/Filter.php index 73ca317790..70f0aef677 100644 --- a/app/lib/FireflyIII/Shared/Toolkit/Filter.php +++ b/app/lib/FireflyIII/Shared/Toolkit/Filter.php @@ -174,37 +174,35 @@ class Filter */ public function previous($range, Carbon $date) { - switch ($range) { - default: - throw new FireflyException('Cannot do _previous() on ' . $range); - break; - case '1D': - $date->startOfDay()->subDay(); - break; - case '1W': - $date->startOfWeek()->subWeek(); - break; - case '1M': - $date->startOfMonth()->subMonth(); - break; - case '3M': - $date->firstOfQuarter()->subMonths(3)->firstOfQuarter(); - break; - case '6M': - $month = intval($date->format('m')); - if ($month <= 6) { - $date->startOfYear()->subMonths(6); - } else { - $date->startOfYear(); - } - break; - case '1Y': - $date->startOfYear()->subYear(); - break; + $functionMap = [ + '1D' => 'Day', + '1W' => 'Week', + '1M' => 'Month', + '1Y' => 'Year' + ]; + if (isset($functionMap[$range])) { + $startFunction = 'startOf' . $functionMap[$range]; + $subFunction = 'sub' . $functionMap[$range]; + $date->$startFunction()->$subFunction(); + + return $date; } + if ($range == '3M') { + $date->firstOfQuarter()->subMonths(3)->firstOfQuarter(); - return $date; + return $date; + } + if ($range == '6M') { + $month = intval($date->format('m')); + $date->startOfYear(); + if ($month <= 6) { + $date->subMonths(6); + } + + return $date; + } + throw new FireflyException('Cannot do _previous() on ' . $range); } /** diff --git a/app/views/reports/month.blade.php b/app/views/reports/month.blade.php index c60d473d62..6943a09ba8 100644 --- a/app/views/reports/month.blade.php +++ b/app/views/reports/month.blade.php @@ -5,7 +5,41 @@
Income
- @include('list.journals-small',['journals' => $income]) + + + @foreach($income as $entry) + + + + + + + @endforeach + @if(isset($displaySum) && $displaySum === true) + + + + + + @endif +
+ {{{$entry->description}}} + + amount);?> + @if($entry->type == 'Withdrawal') + {{Amount::format($entry->amount,false)}} + @endif + @if($entry->type == 'Deposit') + {{Amount::format($entry->amount,false)}} + @endif + @if($entry->type == 'Transfer') + {{Amount::format($entry->amount,false)}} + @endif + + {{$entry->date->format('j F Y')}} + + {{{$entry->name}}} +
Sum{{Amount::format($tableSum)}}