mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-29 06:34:37 +00:00 
			
		
		
		
	Some query cleaning up.
This commit is contained in:
		| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use Crypt; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Support\Collection; | ||||
| use stdClass; | ||||
| @@ -36,7 +37,7 @@ class Expense | ||||
|         bcscale(2); | ||||
|  | ||||
|         $accountId = $entry->account_id; | ||||
|         $amount    = strval(round($entry->amount, 2)); | ||||
|         $amount    = strval(round($entry->journalAmount, 2)); | ||||
|         if (bccomp('0', $amount) === -1) { | ||||
|             $amount = bcmul($amount, '-1'); | ||||
|         } | ||||
| @@ -44,7 +45,7 @@ class Expense | ||||
|         if (!$this->expenses->has($accountId)) { | ||||
|             $newObject         = new stdClass; | ||||
|             $newObject->amount = $amount; | ||||
|             $newObject->name   = $entry->name; | ||||
|             $newObject->name   = Crypt::decrypt($entry->account_name); | ||||
|             $newObject->count  = 1; | ||||
|             $newObject->id     = $accountId; | ||||
|             $this->expenses->put($accountId, $newObject); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| namespace FireflyIII\Helpers\Collection; | ||||
|  | ||||
| use Crypt; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Support\Collection; | ||||
| use stdClass; | ||||
| @@ -38,15 +39,15 @@ class Income | ||||
|         $accountId = $entry->account_id; | ||||
|         if (!$this->incomes->has($accountId)) { | ||||
|             $newObject         = new stdClass; | ||||
|             $newObject->amount = strval(round($entry->amount_positive, 2)); | ||||
|             $newObject->name   = $entry->name; | ||||
|             $newObject->amount = strval(round($entry->journalAmount, 2)); | ||||
|             $newObject->name   = Crypt::decrypt($entry->account_name); | ||||
|             $newObject->count  = 1; | ||||
|             $newObject->id     = $accountId; | ||||
|             $this->incomes->put($accountId, $newObject); | ||||
|         } else { | ||||
|             bcscale(2); | ||||
|             $existing         = $this->incomes->get($accountId); | ||||
|             $existing->amount = bcadd($existing->amount, $entry->amount_positive); | ||||
|             $existing->amount = bcadd($existing->amount, $entry->journalAmount); | ||||
|             $existing->count++; | ||||
|             $this->incomes->put($accountId, $existing); | ||||
|         } | ||||
|   | ||||
| @@ -2,7 +2,9 @@ | ||||
|  | ||||
| namespace FireflyIII\Helpers\Report; | ||||
|  | ||||
| use Auth; | ||||
| use Carbon\Carbon; | ||||
| use DB; | ||||
| use FireflyIII\Helpers\Collection\Account as AccountCollection; | ||||
| use FireflyIII\Helpers\Collection\Balance; | ||||
| use FireflyIII\Helpers\Collection\BalanceEntry; | ||||
| @@ -19,8 +21,9 @@ use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\Budget as BudgetModel; | ||||
| use FireflyIII\Models\LimitRepetition; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use Illuminate\Database\Query\JoinClause; | ||||
| use Illuminate\Support\Collection; | ||||
| use Steam; | ||||
|  | ||||
| /** | ||||
|  * Class ReportHelper | ||||
| @@ -127,21 +130,59 @@ class ReportHelper implements ReportHelperInterface | ||||
|         $startAmount = '0'; | ||||
|         $endAmount   = '0'; | ||||
|         $diff        = '0'; | ||||
|         $ids         = $accounts->pluck('id')->toArray(); | ||||
|  | ||||
|         $yesterday = clone $start; | ||||
|         $yesterday->subDay(); | ||||
|  | ||||
|         bcscale(2); | ||||
|  | ||||
|         // get balances for start. | ||||
|         $startSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') | ||||
|                            ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||
|                            ->whereIn('accounts.id', $ids) | ||||
|                            ->whereNull('transaction_journals.deleted_at') | ||||
|                            ->whereNull('transactions.deleted_at') | ||||
|                            ->where('transaction_journals.date', '<=', $yesterday->format('Y-m-d')) | ||||
|                            ->groupBy('accounts.id') | ||||
|                            ->get(['accounts.id', DB::Raw('SUM(`transactions`.`amount`) as `balance`')]); | ||||
|  | ||||
|         // and for end: | ||||
|         $endSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') | ||||
|                          ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') | ||||
|                          ->whereIn('accounts.id', $ids) | ||||
|                          ->whereNull('transaction_journals.deleted_at') | ||||
|                          ->whereNull('transactions.deleted_at') | ||||
|                          ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) | ||||
|                          ->groupBy('accounts.id') | ||||
|                          ->get(['accounts.id', DB::Raw('SUM(`transactions`.`amount`) as `balance`')]); | ||||
|  | ||||
|  | ||||
|         $accounts->each( | ||||
|             function (Account $account) use ($start, $end) { | ||||
|             function (Account $account) use ($startSet, $endSet) { | ||||
|                 /** | ||||
|                  * The balance for today always incorporates transactions | ||||
|                  * made on today. So to get todays "start" balance, we sub one | ||||
|                  * day. | ||||
|                  */ | ||||
|                 $yesterday = clone $start; | ||||
|                 $yesterday->subDay(); | ||||
|                 // | ||||
|                 $currentStart = $startSet->filter( | ||||
|                     function (Account $entry) use ($account) { | ||||
|                         return $account->id == $entry->id; | ||||
|                     } | ||||
|                 ); | ||||
|                 if ($currentStart->first()) { | ||||
|                     $account->startBalance = $currentStart->first()->balance; | ||||
|                 } | ||||
|  | ||||
|                 /** @noinspection PhpParamsInspection */ | ||||
|                 $account->startBalance = Steam::balance($account, $yesterday); | ||||
|                 $account->endBalance   = Steam::balance($account, $end); | ||||
|                 $currentEnd = $endSet->filter( | ||||
|                     function (Account $entry) use ($account) { | ||||
|                         return $account->id == $entry->id; | ||||
|                     } | ||||
|                 ); | ||||
|                 if ($currentEnd->first()) { | ||||
|                     $account->endBalance = $currentEnd->first()->balance; | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|  | ||||
| @@ -174,9 +215,32 @@ class ReportHelper implements ReportHelperInterface | ||||
|     public function getIncomeReport($start, $end, Collection $accounts) | ||||
|     { | ||||
|         $object = new Income; | ||||
|         $set    = $this->query->incomeInPeriod($start, $end, $accounts); | ||||
|  | ||||
|         /* | ||||
|          * TODO move to ReportQuery class. | ||||
|          */ | ||||
|         $ids = $accounts->pluck('id')->toArray(); | ||||
|         $set = Auth::user()->transactionjournals() | ||||
|                    ->leftJoin( | ||||
|                        'transactions as t_from', function (JoinClause $join) { | ||||
|                        $join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0); | ||||
|                    } | ||||
|                    ) | ||||
|                    ->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', 't_from.account_id', '=', 'accounts.id') | ||||
|                    ->transactionTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE]) | ||||
|                    ->before($end) | ||||
|                    ->after($start) | ||||
|                    ->whereIn('t_to.account_id', $ids) | ||||
|                    ->whereNotIn('t_from.account_id', $ids) | ||||
|                    ->get(['transaction_journals.*', 't_to.amount as journalAmount', 'accounts.id as account_id', 'accounts.name as account_name']); | ||||
|  | ||||
|         foreach ($set as $entry) { | ||||
|             $object->addToTotal($entry->amount_positive); | ||||
|             $object->addToTotal($entry->journalAmount); | ||||
|             $object->addOrCreateIncome($entry); | ||||
|         } | ||||
|  | ||||
| @@ -195,9 +259,33 @@ class ReportHelper implements ReportHelperInterface | ||||
|     public function getExpenseReport($start, $end, Collection $accounts) | ||||
|     { | ||||
|         $object = new Expense; | ||||
|         $set    = $this->query->expenseInPeriod($start, $end, $accounts); | ||||
|  | ||||
|  | ||||
|         /* | ||||
|          * TODO move to ReportQuery class. | ||||
|          */ | ||||
|         $ids = $accounts->pluck('id')->toArray(); | ||||
|         $set = Auth::user()->transactionjournals() | ||||
|                    ->leftJoin( | ||||
|                        'transactions as t_from', function (JoinClause $join) { | ||||
|                        $join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0); | ||||
|                    } | ||||
|                    ) | ||||
|                    ->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', 't_to.account_id', '=', 'accounts.id') | ||||
|                    ->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE]) | ||||
|                    ->before($end) | ||||
|                    ->after($start) | ||||
|                    ->whereIn('t_from.account_id', $ids) | ||||
|                    ->whereNotIn('t_to.account_id', $ids) | ||||
|                    ->get(['transaction_journals.*', 't_from.amount as journalAmount', 'accounts.id as account_id', 'accounts.name as account_name']); | ||||
|  | ||||
|         foreach ($set as $entry) { | ||||
|             $object->addToTotal($entry->amount); // can be positive, if it's a transfer | ||||
|             $object->addToTotal($entry->journalAmount); // can be positive, if it's a transfer | ||||
|             $object->addOrCreateExpense($entry); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -103,69 +103,69 @@ class ReportQuery implements ReportQueryInterface | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * This method works the same way as ReportQueryInterface::incomeInPeriod does, but instead of returning results | ||||
|      * will simply list the transaction journals only. This should allow any follow up counting to be accurate with | ||||
|      * regards to tags. It will only get the incomes to the specified accounts. | ||||
|      * | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * @param Collection $accounts | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function incomeInPeriod(Carbon $start, Carbon $end, Collection $accounts) | ||||
|     { | ||||
|         $query = $this->queryJournalsWithTransactions($start, $end); | ||||
|  | ||||
|         $ids = []; | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $ids[] = $account->id; | ||||
|         } | ||||
|  | ||||
|         // OR is a deposit | ||||
|         // OR any transfer TO the accounts in $accounts, not FROM any of the accounts in $accounts. | ||||
|         $query->where( | ||||
|             function (Builder $query) use ($ids) { | ||||
|                 $query->where( | ||||
|                     function (Builder $q) { | ||||
|                         $q->where('transaction_types.type', TransactionType::DEPOSIT); | ||||
|                     } | ||||
|                 ); | ||||
|                 $query->orWhere( | ||||
|                     function (Builder $q) use ($ids) { | ||||
|                         $q->where('transaction_types.type', TransactionType::TRANSFER); | ||||
|                         $q->whereNotIn('ac_from.id', $ids); | ||||
|                         $q->whereIn('ac_to.id', $ids); | ||||
|                     } | ||||
|                 ); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         // only include selected accounts. | ||||
|         $query->whereIn('ac_to.id', $ids); | ||||
|         $query->orderBy('transaction_journals.date'); | ||||
|  | ||||
|         // get everything | ||||
|         $data = $query->get( | ||||
|             ['transaction_journals.*', | ||||
|              'transaction_types.type', 'ac_from.name as name', | ||||
|              't_from.amount as from_amount', | ||||
|              't_to.amount as to_amount', | ||||
|              'ac_from.id as account_id', 'ac_from.encrypted as account_encrypted'] | ||||
|         ); | ||||
|  | ||||
|         $data->each( | ||||
|             function (TransactionJournal $journal) { | ||||
|                 if (intval($journal->account_encrypted) == 1) { | ||||
|                     $journal->name = Crypt::decrypt($journal->name); | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
| //    /** | ||||
| //     * This method works the same way as ReportQueryInterface::incomeInPeriod does, but instead of returning results | ||||
| //     * will simply list the transaction journals only. This should allow any follow up counting to be accurate with | ||||
| //     * regards to tags. It will only get the incomes to the specified accounts. | ||||
| //     * | ||||
| //     * @param Carbon     $start | ||||
| //     * @param Carbon     $end | ||||
| //     * @param Collection $accounts | ||||
| //     * | ||||
| //     * @return Collection | ||||
| //     */ | ||||
| //    public function incomeInPeriod(Carbon $start, Carbon $end, Collection $accounts) | ||||
| //    { | ||||
| //        $query = $this->queryJournalsWithTransactions($start, $end); | ||||
| // | ||||
| //        $ids = []; | ||||
| //        /** @var Account $account */ | ||||
| //        foreach ($accounts as $account) { | ||||
| //            $ids[] = $account->id; | ||||
| //        } | ||||
| // | ||||
| //        // OR is a deposit | ||||
| //        // OR any transfer TO the accounts in $accounts, not FROM any of the accounts in $accounts. | ||||
| //        $query->where( | ||||
| //            function (Builder $query) use ($ids) { | ||||
| //                $query->where( | ||||
| //                    function (Builder $q) { | ||||
| //                        $q->where('transaction_types.type', TransactionType::DEPOSIT); | ||||
| //                    } | ||||
| //                ); | ||||
| //                $query->orWhere( | ||||
| //                    function (Builder $q) use ($ids) { | ||||
| //                        $q->where('transaction_types.type', TransactionType::TRANSFER); | ||||
| //                        $q->whereNotIn('ac_from.id', $ids); | ||||
| //                        $q->whereIn('ac_to.id', $ids); | ||||
| //                    } | ||||
| //                ); | ||||
| //            } | ||||
| //        ); | ||||
| // | ||||
| //        // only include selected accounts. | ||||
| //        $query->whereIn('ac_to.id', $ids); | ||||
| //        $query->orderBy('transaction_journals.date'); | ||||
| // | ||||
| //        // get everything | ||||
| //        $data = $query->get( | ||||
| //            ['transaction_journals.*', | ||||
| //             'transaction_types.type', 'ac_from.name as name', | ||||
| //             't_from.amount as from_amount', | ||||
| //             't_to.amount as to_amount', | ||||
| //             'ac_from.id as account_id', 'ac_from.encrypted as account_encrypted'] | ||||
| //        ); | ||||
| // | ||||
| //        $data->each( | ||||
| //            function (TransactionJournal $journal) { | ||||
| //                if (intval($journal->account_encrypted) == 1) { | ||||
| //                    $journal->name = Crypt::decrypt($journal->name); | ||||
| //                } | ||||
| //            } | ||||
| //        ); | ||||
| // | ||||
| //        return $data; | ||||
| //    } | ||||
|  | ||||
|     /** | ||||
|      * See ReportQueryInterface::incomeInPeriod | ||||
|   | ||||
| @@ -31,18 +31,18 @@ interface ReportQueryInterface | ||||
|      */ | ||||
|     public function expenseInPeriod(Carbon $start, Carbon $end, Collection $accounts); | ||||
|  | ||||
|     /** | ||||
|      * This method works the same way as ReportQueryInterface::incomeInPeriod does, but instead of returning results | ||||
|      * will simply list the transaction journals only. This should allow any follow up counting to be accurate with | ||||
|      * regards to tags. It will only get the incomes to the specified accounts. | ||||
|      * | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * @param Collection $accounts | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function incomeInPeriod(Carbon $start, Carbon $end, Collection $accounts); | ||||
| //    /** | ||||
| //     * This method works the same way as ReportQueryInterface::incomeInPeriod does, but instead of returning results | ||||
| //     * will simply list the transaction journals only. This should allow any follow up counting to be accurate with | ||||
| //     * regards to tags. It will only get the incomes to the specified accounts. | ||||
| //     * | ||||
| //     * @param Carbon     $start | ||||
| //     * @param Carbon     $end | ||||
| //     * @param Collection $accounts | ||||
| //     * | ||||
| //     * @return Collection | ||||
| //     */ | ||||
| //    public function incomeInPeriod(Carbon $start, Carbon $end, Collection $accounts); | ||||
|  | ||||
|     /** | ||||
|      * Covers tags as well. | ||||
|   | ||||
| @@ -125,9 +125,9 @@ class ReportController extends Controller | ||||
|         $expenseTopLength = 8; | ||||
|  | ||||
|         // get report stuff! | ||||
|         $accountReport = $this->helper->getAccountReport($start, $end, $accounts); | ||||
|         $incomes       = $this->helper->getIncomeReport($start, $end, $accounts); | ||||
|         $expenses      = $this->helper->getExpenseReport($start, $end, $accounts); | ||||
|         $accountReport = $this->helper->getAccountReport($start, $end, $accounts); // done | ||||
|         $incomes       = $this->helper->getIncomeReport($start, $end, $accounts); // done | ||||
|         $expenses      = $this->helper->getExpenseReport($start, $end, $accounts); // done | ||||
|         $budgets       = $this->helper->getBudgetReport($start, $end, $accounts); | ||||
|         $categories    = $this->helper->getCategoryReport($start, $end, $accounts); | ||||
|         $balance       = $this->helper->getBalanceReport($start, $end, $accounts); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user