getWorkSet(); /* * Extract: * possible budget ids for journals * possible category ids journals * possible budget ids for transactions * possible category ids for transactions * * possible IBAN and account numbers? * */ $journals = $this->extractJournalIds(); $transactions = $this->extractTransactionIds(); // extend work set with category data from journals: $this->categoryDataForJournals($journals); // extend work set with category cate from transactions (overrules journals): $this->categoryDataForTransactions($transactions); // same for budgets: $this->budgetDataForJournals($journals); $this->budgetDataForTransactions($transactions); $this->setEntries($this->workSet); return true; } /** * @param Collection $accounts */ public function setAccounts(Collection $accounts) { $this->accounts = $accounts; } /** * @param Carbon $start * @param Carbon $end */ public function setDates(Carbon $start, Carbon $end) { $this->start = $start; $this->end = $end; } /** * @param array $journals * * @return bool */ private function budgetDataForJournals(array $journals): bool { $set = DB::table('budget_transaction_journal') ->leftJoin('budgets', 'budgets.id', '=', 'budget_transaction_journal.budget_id') ->whereIn('budget_transaction_journal.transaction_journal_id', $journals) ->get( [ 'budget_transaction_journal.budget_id', 'budget_transaction_journal.transaction_journal_id', 'budgets.name', 'budgets.encrypted', ] ); $set->each( function ($obj) { $obj->name = $obj->encrypted === 1 ? Crypt::decrypt($obj->name) : $obj->name; } ); $array = []; foreach ($set as $obj) { $array[$obj->transaction_journal_id] = ['id' => $obj->budget_id, 'name' => $obj->name]; } $this->workSet->each( function ($obj) use ($array) { if (isset($array[$obj->transaction_journal_id])) { $obj->budget_id = $array[$obj->transaction_journal_id]['id']; $obj->budget_name = $array[$obj->transaction_journal_id]['name']; } } ); return true; } /** * @param array $transactions * * @return bool */ private function budgetDataForTransactions(array $transactions): bool { $set = DB::table('budget_transaction') ->leftJoin('budgets', 'budgets.id', '=', 'budget_transaction.budget_id') ->whereIn('budget_transaction.transaction_id', $transactions) ->get( [ 'budget_transaction.budget_id', 'budget_transaction.transaction_id', 'budgets.name', 'budgets.encrypted', ] ); $set->each( function ($obj) { $obj->name = $obj->encrypted === 1 ? Crypt::decrypt($obj->name) : $obj->name; } ); $array = []; foreach ($set as $obj) { $array[$obj->transaction_id] = ['id' => $obj->budget_id, 'name' => $obj->name]; } $this->workSet->each( function ($obj) use ($array) { // first transaction if (isset($array[$obj->id])) { $obj->budget_id = $array[$obj->id]['id']; $obj->budget_name = $array[$obj->id]['name']; } } ); return true; } /** * @param array $journals * * @return bool */ private function categoryDataForJournals(array $journals): bool { $set = DB::table('category_transaction_journal') ->leftJoin('categories', 'categories.id', '=', 'category_transaction_journal.category_id') ->whereIn('category_transaction_journal.transaction_journal_id', $journals) ->get( [ 'category_transaction_journal.category_id', 'category_transaction_journal.transaction_journal_id', 'categories.name', 'categories.encrypted', ] ); $set->each( function ($obj) { $obj->name = $obj->encrypted === 1 ? Crypt::decrypt($obj->name) : $obj->name; } ); $array = []; foreach ($set as $obj) { $array[$obj->transaction_journal_id] = ['id' => $obj->category_id, 'name' => $obj->name]; } $this->workSet->each( function ($obj) use ($array) { if (isset($array[$obj->transaction_journal_id])) { $obj->category_id = $array[$obj->transaction_journal_id]['id']; $obj->category_name = $array[$obj->transaction_journal_id]['name']; } } ); return true; } /** * @param array $transactions * * @return bool */ private function categoryDataForTransactions(array $transactions): bool { $set = DB::table('category_transaction') ->leftJoin('categories', 'categories.id', '=', 'category_transaction.category_id') ->whereIn('category_transaction.transaction_id', $transactions) ->get( [ 'category_transaction.category_id', 'category_transaction.transaction_id', 'categories.name', 'categories.encrypted', ] ); $set->each( function ($obj) { $obj->name = $obj->encrypted === 1 ? Crypt::decrypt($obj->name) : $obj->name; } ); $array = []; foreach ($set as $obj) { $array[$obj->transaction_id] = ['id' => $obj->category_id, 'name' => $obj->name]; } $this->workSet->each( function ($obj) use ($array) { // first transaction if (isset($array[$obj->id])) { $obj->category_id = $array[$obj->id]['id']; $obj->category_name = $array[$obj->id]['name']; } } ); return true; } /** * @return array */ private function extractJournalIds(): array { return $this->workSet->pluck('transaction_journal_id')->toArray(); } /** * @return array */ private function extractTransactionIds() { $set = $this->workSet->pluck('id')->toArray(); $opposing = $this->workSet->pluck('opposing_id')->toArray(); $complete = $set + $opposing; return array_unique($complete); } /** * */ private function getWorkSet() { $accountIds = $this->accounts->pluck('id')->toArray(); $this->workSet = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin( 'transactions AS opposing', function (JoinClause $join) { $join->on('opposing.transaction_journal_id', '=', 'transactions.transaction_journal_id') ->where('opposing.amount', '=', DB::raw('transactions.amount * -1')) ->where('transactions.identifier', '=', DB::raw('opposing.identifier')); } ) ->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id') ->leftJoin('accounts AS opposing_accounts', 'opposing.account_id', '=', 'opposing_accounts.id') ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', 'transaction_types.id') ->leftJoin('transaction_currencies', 'transaction_journals.transaction_currency_id', '=', 'transaction_currencies.id') ->whereIn('transactions.account_id', $accountIds) ->where('transaction_journals.user_id', $this->job->user_id) ->where('transaction_journals.date', '>=', $this->start->format('Y-m-d')) ->where('transaction_journals.date', '<=', $this->end->format('Y-m-d')) ->where('transaction_journals.completed', 1) ->whereNull('transaction_journals.deleted_at') ->whereNull('transactions.deleted_at') ->whereNull('opposing.deleted_at') ->orderBy('transaction_journals.date', 'DESC') ->orderBy('transactions.identifier', 'ASC') ->get( [ 'transactions.id', 'transactions.amount', 'transactions.description', 'transactions.account_id', 'accounts.name as account_name', 'accounts.encrypted as account_name_encrypted', 'transactions.identifier', 'opposing.id as opposing_id', 'opposing.amount AS opposing_amount', 'opposing.description as opposing_description', 'opposing.account_id as opposing_account_id', 'opposing_accounts.name as opposing_account_name', 'opposing_accounts.encrypted as opposing_account_encrypted', 'opposing.identifier as opposing_identifier', 'transaction_journals.id as transaction_journal_id', 'transaction_journals.date', 'transaction_journals.description as journal_description', 'transaction_journals.encrypted as journal_encrypted', 'transaction_journals.transaction_type_id', 'transaction_types.type as transaction_type', 'transaction_journals.transaction_currency_id', 'transaction_currencies.code AS transaction_currency_code', ] ); } }